diff --git a/.vscode/settings.json b/.vscode/settings.json
index a5a9e3e4..438438c2 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -3,7 +3,7 @@
"latex-workshop.synctex.afterBuild.enabled": true,
"latex-workshop.view.pdf.viewer": "tab",
"latex-workshop.latex.build.forceRecipeUsage": false,
- "latex-workshop.latex.search.rootFiles.include": ["**/courses/5/main.tex"], // Change this to the path of your main tex file
+ "latex-workshop.latex.search.rootFiles.include": ["**/instructionset/main.tex"], // Change this to the path of your main tex file
"latex-workshop.view.pdf.internal.synctex.keybinding": "double-click",
"latex-workshop.latex.autoClean.run": "onBuilt",
"latex-workshop.latex.autoBuild.run": "onSave",
diff --git a/assignments/exam/.gitignore b/assignments/exam/.gitignore
new file mode 100644
index 00000000..14a7f05a
--- /dev/null
+++ b/assignments/exam/.gitignore
@@ -0,0 +1,3 @@
+plantuml
+out/*
+out
\ No newline at end of file
diff --git a/assignments/exam/README.md b/assignments/exam/README.md
index 9254f082..270ce091 100644
--- a/assignments/exam/README.md
+++ b/assignments/exam/README.md
@@ -5,68 +5,65 @@
## 1
## 2
-1. Given the following hexadecimal number 0xhex in big endian format, convert it to binary and decimal.
+1. Given the following hexadecimal number 0xhex in big endian format, convert it to binary.
-2. Given the hexadecimal string 0xhex, what is the value of the
+2. Given the following hexadecimal number 0xhex in big endian format, convert it to decimal.
+
+3. Given the hexadecimal string 0xhex, what is the value of the
number in the X NRS (number representation system)?
## 3
-3. Calculate the number of bits for the tag, index, and block offset
+4. Calculate the number of bits for the tag, index, and block offset
for a cache memory with the following characteristics: X cache size, Y
-block placement, and Z block size.
+block placement, and Z block size. The address size will be given.
-4. What happens to CPU execution time if we increase the block size to
+5. What happens to CPU execution time if we increase the block size to
reduce the miss rate?
-5. What happens to CPU execution time if we increase the cache size to
+6. What happens to CPU execution time if we increase the cache size to
reduce the miss rate?
-6. What happens to CPU execution time if we increase the associativity
+7. What happens to CPU execution time if we increase the associativity
to reduce the miss rate?
-7. What happens to CPU execution time if we add multiple levels of
+8. What happens to CPU execution time if we add multiple levels of
cache?
## 4
-8. Given the x-bit adder of type y, calculate the number of gates
+9. Given the x-bit adder of type y, calculate the number of gates
for the carry-out.
-9. Given the x-bit Booth's algorithm, how many additions are for
+10. Given the x-bit Booth's algorithm, how many additions are for
M x R?
-10. What are the status flags for the following operation X ?
+11. What are the status flags for the following operation X ?
## 5
-11. Having the following registers value, main memory address and
+12. Having the following registers value, main memory address and
data, and the immediate value what is the value of the MA register if we
use the X addressing mode?
-12. Having the memory addressing table and instruction format
-tables, what is the instruction conding for the X operation?
-
13. Having the memory addressing table and instruction format
+tables, what is the instruction encoding in hexadecimal for the X operation?
+
+14. Having the memory addressing table and instruction format
tables, what is the instruction for the IR = x?
## 6
## 7
-14. Having the following IO registers value, main memory address
+15. Having the following IO registers value, main memory address
and data, what can you find on the data bus?
-15. Having the X UART configuration, what is the maxim data rate
+16. Having the X UART configuration, what is the maxim data rate
that can be achieved?
## 8
-16. Having the following values in the registers at time 0, interrupts
-requested with the time of the request and the type of the interrupt, and
-how much time the CPU will take to handle every type of interrupt, which
-is the order of the interrupts that will be handled by the CPU?
-
17. Having the following values in the registers at time 0, interrupts
requested with the time of the request and the type of the interrupt, and
how much time the CPU will take to handle every type of interrupt, which
diff --git a/assignments/exam/addertype/fetch.py b/assignments/exam/addertype/fetch.py
new file mode 100644
index 00000000..446e2718
--- /dev/null
+++ b/assignments/exam/addertype/fetch.py
@@ -0,0 +1,70 @@
+import sys, json, random, datetime
+args = {param.split('=')[0]: param.split('=')[1] for param in sys.argv[1:]}
+student_id = args['id']
+# TODO: change for EXAM
+secret = 0
+week=datetime.datetime.now().isocalendar()[0]
+random.seed(secret + week + int(student_id))
+
+def calculate_no_gates_ripple_carry_adder(n, order):
+ return n * 5
+
+def calculate_no_gates_kogge_stone_adder(n, order):
+ return n * 3 + 3 * n * order - 3 * n + 3
+
+def calculate_no_gates_brent_kung_adder(n, order):
+ return n * 3 + 6 * n - 6 - 3 * order
+
+def path_carry_out_ripple_carry_adder(n, order):
+ return n * 3
+
+def path_carry_out_kogge_stone_adder(n, order):
+ return 2 * order + 1
+
+def path_carry_out_brent_kung_adder(n, order):
+ return 2 * order + 1
+
+# Define the possible values for the number of bits
+order_of_bits = [x for x in range(4, 5, 6)]
+adder_types = ['ripple-carry adder', 'kogge-stone CLA', 'brent-kung CLA']
+question_types = ['gates', 'carry-out path']
+questions = ['How many gates are in a {}-bit {}?', 'How many gates are in the carry-out path are in a {}-bit {}?']
+selected_order_of_bits = random.choice(order_of_bits)
+selected_adder_type = random.choice(adder_types)
+selected_no_bits = 2 ** selected_order_of_bits
+selected_question_type = random.choice(question_types)
+
+answer = 0
+
+if selected_question_type == 'gates':
+ if selected_adder_type == 'ripple-carry adder':
+ answer = calculate_no_gates_ripple_carry_adder(selected_no_bits, selected_order_of_bits)
+ elif selected_adder_type == 'kogge-stone CLA':
+ answer = calculate_no_gates_kogge_stone_adder(selected_no_bits, selected_order_of_bits)
+ elif selected_adder_type == 'brent-kung CLA':
+ answer = calculate_no_gates_brent_kung_adder(selected_no_bits, selected_order_of_bits)
+elif selected_question_type == 'carry-out path':
+ if selected_adder_type == 'ripple-carry adder':
+ answer = path_carry_out_ripple_carry_adder(selected_no_bits, selected_order_of_bits)
+ elif selected_adder_type == 'kogge-stone CLA':
+ answer = path_carry_out_kogge_stone_adder(selected_no_bits, selected_order_of_bits)
+ elif selected_adder_type == 'brent-kung CLA':
+ answer = path_carry_out_brent_kung_adder(selected_no_bits, selected_order_of_bits)
+
+question = questions[question_types.index(selected_question_type)].format(selected_no_bits, selected_adder_type)
+
+# transform in a html format question
+question = """
+
+""".format(question)
+
+print(
+ json.dumps(
+ {
+ 'question': question,
+ 'result': answer
+ }
+ )
+)
diff --git a/assignments/exam/addertype/sol.tex b/assignments/exam/addertype/sol.tex
new file mode 100644
index 00000000..1e83316a
--- /dev/null
+++ b/assignments/exam/addertype/sol.tex
@@ -0,0 +1,130 @@
+\subsection*{Problem}
+Given the X-bit adder of type Y, calculate the total number of gates and
+the number of gates on the path to the carry out. Y can be:
+\begin{itemize}
+ \item Ripple Carry Adder
+ \item Carry Lookahead Kogge-Stone
+ \item Carry Lookahead Brent-Kung
+\end{itemize}
+
+\subsection*{Solution}
+Let's calculate the total number of gates and the number of gates on the path to the carry out for each type of 32-bit adder.
+
+\textbf{Ripple Carry Adder}
+
+In a ripple carry adder, each bit addition requires a full adder, which consists of:
+\begin{itemize}
+ \item 2 XOR gates for sum
+ \item 2 AND gates and 1 OR gate for carry-out
+\end{itemize}
+For a 32-bit adder:
+\[
+\text{Total gates} = 32 \times (2 \text{ XOR} + 2 \text{ AND} + 1 \text{ OR}) = 32 \times 5 = 160 \text{ gates}
+\]
+The number of gates on the path to the carry out is:
+\[
+\text{Gates on carry-out path} = 32 \times (2 \text{ AND} + 1 \text{ OR}) = 32 \times 3 = 96 \text{ gates}
+\]
+
+\textbf{Carry Lookahead Adder (CLA)}
+
+Each bit in the adder generates two signals:
+\begin{itemize}
+ \item Generate signal: \( G_i = A_i \land B_i \) (AND gate per bit)
+ \item Propagate signal: \( P_i = A_i \oplus B_i \) (XOR gate per bit)
+\end{itemize}
+
+For an \( n \)-bit adder, this requires:
+\[
+n \times \text{AND gates} + n \times \text{XOR gates}.
+\]
+
+The sum is computed using:
+\[
+S_i = P_i \oplus C_i.
+\]
+
+This requires:
+\[
+n \times \text{XOR gates}.
+\]
+
+The carry equation is given by:
+\[
+C_{i+1} = G_i \lor (P_i \land C_i).
+\]
+
+
+\textbf{Kogge-Stone CLA:}
+The Kogge-Stone adder is a parallel prefix adder with a highly regular structure, providing optimal computation for propagate ($P$) and generate ($G$) signals in $\lceil \log_2 n \rceil$ levels.
+
+The total number of gates in the Kogge-Stone CLA depends on:
+\begin{itemize}
+ \item \textbf{Propagation of $P$ and $G$:}
+ At each level $k$, the $P$ and $G$ values are computed using:
+ \[
+ G_i^{(k)} = G_i^{(k-1)} \lor \left(P_i^{(k-1)} \land G_{i-2^{k-1}}^{(k-1)}\right),
+ \]
+ \[
+ P_i^{(k)} = P_i^{(k-1)} \land P_{i-2^{k-1}}^{(k-1)}.
+ \]
+ This requires:
+ \begin{itemize}
+ \item \textbf{1 AND gate} for $P_i^{(k)}$.
+ \item \textbf{1 AND gate and 1 OR gate} for $G_i^{(k)}$.
+ \end{itemize}
+ \item The number of operations at each level is $n - 2^{k-1}$.
+\end{itemize}
+
+The carry-out path in a Kogge-Stone adder corresponds to the depth of the tree, which is $\lceil \log_2 n \rceil$. At each level:
+\begin{itemize}
+ \item \textbf{1 AND gate} for propagate ($P$).
+ \item \textbf{1 AND gate and 1 OR gate} for generate ($G$).
+\end{itemize}
+This results in \textbf{3 gates per level}.
+
+For an \( n \)-bit adder, the total number of carry gates is approximately:
+\begin{equation*}
+ \begin{split}
+\text{Carry Gates} & = \sum_{i=1}^{\log_2 n} \left( n - 2^{i-1} \right) \times 3 = 3 \times n \times \sum_{i=1}^{\log_2 n} 1 - 3 \times \sum_{i=1}^{\log_2 n} 2^{i-1} = \\
+ & = 3 \times n \times \log_2 n - 3 \times \left( 2^{\log_2 n} - 1 \right) = \\
+ & = 3 \times n \times \log_2 n - 3 \times (n - 1) = \\
+ & = 3 \times n \times \log_2 n - 3 \times n + 3. \\
+ & = 3 \times 32 \times 5 - 3 \times 32 + 3 = 480 - 96 + 3 = 387 \text{ gates}. \\
+\text{Total gates} & = n + n + n + 387 = 3 \times 32 + 387 = 96 + 387 = 483 \text{ gates}. \\
+\text{Carry-out path} & = 2 \times \lceil \log_2 n \rceil + 1 = 2 \times 5 + 1 = 11 \text{ gates}.
+ \end{split}
+\end{equation*}
+
+\textbf{Brent-Kung CLA:}
+The Brent-Kung adder is another form of parallel prefix adder with a different structure than Kogge-Stone.
+It keeps the same number of gates for the carry-out path, but the total number of gates is different and depth is $2 \log_2 n - 1$.
+It has a tree structure with a depth of $\log_2 n$ to compute the carry signals followed by a depth of $\log_2 n$ to compute the sum.
+For the first $\log_2 n$ levels:
+\begin{itemize}
+ \item \textbf{1 AND gate} for $P_i^{(k)}$.
+ \item \textbf{1 AND gate and 1 OR gate} for $G_i^{(k)}$.
+ \item The number of operations at each level is $ \frac{n}{2^{k}}$.
+\end{itemize}
+For the next $\log_2 n - 1$ levels:
+\begin{itemize}
+ \item \textbf{1 AND gate} for $P_i^{(k)}$.
+ \item \textbf{1 AND gate and 1 OR gate} for $G_i^{(k)}$.
+ \item The number of operations at each level is $\frac{n}{2^{k}} - 1$.
+\end{itemize}
+
+The total number of gates in the Brent-Kung CLA is:
+\begin{equation*}
+ \begin{split}
+\text{Carry Gates} & = \sum_{i=1}^{\log_2 n} \left( \frac{n}{2^{i}} \right) \times 3 + \sum_{i=1}^{\log_2 n - 1} \left( \frac{n}{2^{i}} - 1 \right) \times 3 = \\
+ & = 3 \times n \times \sum_{i=1}^{\log_2 n} \frac{1}{2^{i}} + 3 \times \sum_{i=1}^{\log_2 n - 1} \left( \frac{n}{2^{i}} - 1 \right) = \\
+ & = 3 \times n \times \left( 1 - \frac{1}{2^{\log_2 n}} \right) + 3 \times \left( n \times \sum_{i=1}^{\log_2 n - 1} \frac{1}{2^{i}} - \sum_{i=1}^{\log_2 n - 1} 1 \right) = \\
+ & = 3 \times n \times \left( 1 - \frac{1}{n} \right) + 3 \times \left( n \times \left( 1 - \frac{1}{2^{\log_2 n - 1}} \right) - \left( \log_2 n - 1 \right) \right) = \\
+ & = 3 \times n - 3 + 3 \times n \times \left( 1 - \frac{2}{n} \right) - 3 \times \left( \log_2 n - 1 \right) = \\
+ & = 3 \times n - 3 + 3 \times n - 6 - 3 \times \log_2 n + 3 = \\
+ & = 6 \times n - 6 - 3 \times \log_2 n = \\
+ & = 6 \times 32 - 6 - 3 \times 5 = 192 - 6 - 15 = 171 \text{ gates}. \\
+\text{Total gates} & = n + n + n + 171 = 3 \times 32 + 171 = 96 + 171 = 267 \text{ gates}. \\
+\text{Carry-out path} & = 2 \times \log_2 n + 1 = 2 \times 5 + 1 = 11 \text{ gates}.
+ \end{split}
+\end{equation*}
diff --git a/assignments/exam/addressing/fetch.py b/assignments/exam/addressing/fetch.py
new file mode 100644
index 00000000..da84d1aa
--- /dev/null
+++ b/assignments/exam/addressing/fetch.py
@@ -0,0 +1,203 @@
+import sys, json, random, datetime
+args = {param.split('=')[0]: param.split('=')[1] for param in sys.argv[1:]}
+student_id = args['id']
+# TODO: change for EXAM
+secret = 0
+week=datetime.datetime.now().isocalendar()[0]
+random.seed(secret + week + int(student_id))
+
+
+# Define the register values
+registers = {
+ "RA": random.randint(0, 2000),
+ "RB": random.randint(0, 2000),
+ "RC": random.randint(0, 2000),
+ "SP": random.randint(0, 2000),
+ "XA": random.randint(2, 200),
+ "XB": random.randint(2, 200),
+ "BA": random.randint(0, 2000),
+ "BB": random.randint(0, 2000),
+ "PC": random.randint(0, 200)
+}
+
+# Define the immediate value
+immediate_value = random.randint(0, 2000)
+
+# Define the main memory
+main_memory = {}
+
+# go though each type of memory addressing
+# 1. Direct Addressing
+da_question = "What is the value of the memory address register (MA) if the instruction is using direct addressing?"
+da_result = immediate_value
+# 2. Indirect Addressing
+ia_question = "What is the value of the memory address register (MA) if the instruction is using indirect addressing?"
+if immediate_value not in main_memory:
+ main_memory[immediate_value] = random.randint(0, 2000)
+ia_result = main_memory[immediate_value]
+# 3. Indirect Addressing from Register
+iar_registers = ["RA", "RB", "RC", "SP", "XA", "XB", "BA", "BB", "PC"]
+for register in iar_registers:
+ if registers[register] not in main_memory:
+ main_memory[registers[register]] = random.randint(0, 2000)
+selected_register = random.choice(iar_registers)
+iar_question = "What is the value of the memory address register (MA) if the instruction is using indirect addressing from register {}?".format(selected_register)
+iar_result = registers[selected_register]
+# 4. Indirect Addressing from Base and Index Registers with Increment After for Index
+base_registers = ["BA", "BB"]
+index_registers = ["XA", "XB"]
+for base_register in base_registers:
+ for index_register in index_registers:
+ if registers[base_register] + registers[index_register] not in main_memory:
+ main_memory[registers[base_register] + registers[index_register]] = random.randint(0, 2000)
+selected_base_register = random.choice(base_registers)
+selected_index_register = random.choice(index_registers)
+iabii_question = "What is the value of the memory address register (MA) if the instruction is using indirect addressing from base register {} and index register {} with increment after for index?".format(selected_base_register, selected_index_register)
+iabii_result = registers[selected_base_register] + registers[selected_index_register]
+# 5. Indirect Addressing from Base and Index Registers with Decrement Before for Index
+for base_register in base_registers:
+ for index_register in index_registers:
+ if registers[base_register] + registers[index_register] - 1 not in main_memory:
+ main_memory[registers[base_register] + registers[index_register] - 1] = random.randint(0, 2000)
+iabid_question = "What is the value of the memory address register (MA) if the instruction is using indirect addressing from base register {} and index register {} with decrement before for index?".format(selected_base_register, selected_index_register)
+iabid_result = registers[selected_base_register] + registers[selected_index_register] - 1
+# 6. Indirect Addressing from Base and Immediate
+for base_register in base_registers:
+ if registers[base_register] + immediate_value not in main_memory:
+ main_memory[registers[base_register] + immediate_value] = random.randint(0, 2000)
+iabimm_question = "What is the value of the memory address register (MA) if the instruction is using indirect addressing from base register {} and immediate value?".format(selected_base_register)
+iabimm_result = registers[selected_base_register] + immediate_value
+# 7. Indirect Addressing from Index and Immediate
+for index_register in index_registers:
+ if registers[index_register] + immediate_value not in main_memory:
+ main_memory[registers[index_register] + immediate_value] = random.randint(0, 2000)
+iaiimm_question = "What is the value of the memory address register (MA) if the instruction is using indirect addressing from index register {} and immediate value?".format(selected_index_register)
+iaiimm_result = registers[selected_index_register] + immediate_value
+# 8. Indirect Addressing from Base and Index with Immediate
+for base_register in base_registers:
+ for index_register in index_registers:
+ if registers[base_register] + registers[index_register] + immediate_value not in main_memory:
+ main_memory[registers[base_register] + registers[index_register] + immediate_value] = random.randint(0, 2000)
+iabiimm_question = "What is the value of the memory address register (MA) if the instruction is using indirect addressing from base register {} and index register {} with immediate value?".format(selected_base_register, selected_index_register)
+iabiimm_result = registers[selected_base_register] + registers[selected_index_register] + immediate_value
+# 9. Immediate Addressing
+if registers["PC"] + immediate_value not in main_memory:
+ main_memory[registers["PC"] + immediate_value] = random.randint(0, 2000)
+imma_question = "What is the value of the memory address register (MA) if the instruction is using immediate addressing?"
+imma_result = registers["PC"] + immediate_value
+# 10. Direct Register Addressing
+dra_question = "What is the value of the memory address register (MA) if the instruction is using direct register addressing?"
+dra_result = 0
+
+# compute the question and result
+addressing_modes = [
+ {
+ "question": da_question,
+ "result": da_result
+ },
+ {
+ "question": ia_question,
+ "result": ia_result
+ },
+ {
+ "question": iar_question,
+ "result": iar_result
+ },
+ {
+ "question": iabii_question,
+ "result": iabii_result
+ },
+ {
+ "question": iabid_question,
+ "result": iabid_result
+ },
+ {
+ "question": iabimm_question,
+ "result": iabimm_result
+ },
+ {
+ "question": iaiimm_question,
+ "result": iaiimm_result
+ },
+ {
+ "question": iabiimm_question,
+ "result": iabiimm_result
+ },
+ {
+ "question": imma_question,
+ "result": imma_result
+ },
+ {
+ "question": dra_question,
+ "result": dra_result
+ }
+]
+selected_addressing_mode = random.choice(addressing_modes)
+
+# generate the register table in html format
+registers_table = """
+
+
+ Register | Value |
+"""
+for register in registers:
+ registers_table += "{} | 0x{} |
".format(register, '{:04x}'.format(registers[register]))
+registers_table += "
"
+# print(registers_table)
+
+# generate the main memory table in html format
+main_memory_table = """
+
+
+ Address | Value |
+"""
+for address in sorted(main_memory):
+ main_memory_table += "0x{} | 0x{} |
".format('{:04x}'.format(address), '{:04x}'.format(main_memory[address]))
+main_memory_table += "
"
+# print(main_memory_table)
+
+# generate the question in html format
+question = """
+
+
Having the following register values, the main memory values and the immediate value 0x{},
+
{}
+
Write the answer in hexadecimal format (4 hex characters - MSB first) starting with 0x
+
Registers Table:
+ {}
+
Main Memory Table:
+ {}
+
+""".format(
+ '{:04x}'.format(immediate_value),
+ selected_addressing_mode["question"],
+ registers_table,
+ main_memory_table
+)
+# print(question)
+
+print(
+ json.dumps(
+ {
+ 'question': question,
+ 'result': '0x{:04x}'.format(selected_addressing_mode["result"])
+ }
+ )
+)
\ No newline at end of file
diff --git a/assignments/exam/addressing/sol.tex b/assignments/exam/addressing/sol.tex
new file mode 100644
index 00000000..4d3a89d1
--- /dev/null
+++ b/assignments/exam/addressing/sol.tex
@@ -0,0 +1,151 @@
+\section*{Problem}
+
+Having the following registers value, main memory address and data, and the immediate value, what is the value of the MA register if we use the X addressing mode? X can be:
+\begin{itemize}
+ \item Direct Addressing
+ \item Indirect Addressing
+ \item Indirect Addressing from Register
+ \item Indirect Addressing from Base and Index Registers
+ \item Indirect Addressing from Base and Index Registers with Increment After for Index
+ \item Indirect Addressing from Base and Index Registers with Decrement Before for Index
+ \item Indirect Addressing from Base and Immediate
+ \item Indirect Addressing from Index and Immediate
+ \item Indirect Addressing from Base and Index with Immediate
+ \item Immediate Addressing
+ \item Direct Register Addressing
+\end{itemize}
+
+Given:
+Registers:
+\begin{table}[h!]
+ \centering
+ \begin{tabular}{|c|c|}
+ \hline
+ \textbf{Register} & \textbf{Hex Value} \\
+ \hline
+ RA & 0x1000 \\
+ \hline
+ RB & 0x2000 \\
+ \hline
+ RC & 0x3000 \\
+ \hline
+ SP & 0x4000 \\
+ \hline
+ XA & 0x0004 \\
+ \hline
+ XB & 0x0008 \\
+ \hline
+ BA & 0x7000 \\
+ \hline
+ BB & 0x8000 \\
+ \hline
+ PC & 0x0100 \\
+ \hline
+ \end{tabular}
+ \caption{Register Values in Hexadecimal}
+\end{table}
+
+Immediate Value: 0x0096
+
+Main Memory:
+\begin{table}[h!]
+ \centering
+ \begin{tabular}{|c|c|}
+ \hline
+ \textbf{Address} & \textbf{Value} \\
+ \hline
+ 0x0096 & 0x4321 \\
+ \hline
+ 0x1000 & 0x1234 \\
+ \hline
+ 0x2000 & 0x5678 \\
+ \hline
+ 0x3000 & 0x9ABC \\
+ \hline
+ 0x4000 & 0xDEF0 \\
+ \hline
+ 0x4500 & 0x6000 \\
+ \hline
+ 0x5000 & 0x1111 \\
+ \hline
+ 0x6000 & 0x2222 \\
+ \hline
+ 0x7000 & 0x3333 \\
+ \hline
+ 0x8000 & 0x4444 \\
+ \hline
+ \end{tabular}
+ \caption{Main Memory Values}
+\end{table}
+
+\section*{Solution}
+Let's calculate the value of the MA register for each addressing mode.
+
+\textbf{Direct Addressing}
+\[
+\text{MA} = \text{Immediate Value} = 0x0096
+\]
+
+\textbf{Indirect Addressing}
+\[
+\text{MA} = \text{MM}[\text{Immediate Value}] = 0x4321
+\]
+
+\textbf{Indirect Addressing from Register}
+Let's use RA.
+\[
+\text{MA} = RA = 0x1000
+\]
+
+\textbf{Indirect Addressing from Base and Index Registers}
+Let's use BA and XA.
+\[
+\text{MA} = BA + XA = 0x7000 + 0x0004 = 0x7004
+\]
+
+\textbf{Indirect Addressing from Base and Index Registers with Increment After for Index}
+Let's use BA and XA.
+\[
+\text{MA} = BA + XA = 0x7000 + 0x0004 = 0x7004
+\]
+\[
+XA = XA + 1 = 0x0005
+\]
+
+\textbf{Indirect Addressing from Base and Index Registers with Decrement Before for Index}
+Let's use BA and XA.
+\[
+XA = XA - 1 = 0x0003
+\]
+\[
+\text{MA} = BA + XA = 0x7000 + 0x0003 = 0x7003
+\]
+
+\textbf{Indirect Addressing from Base and Immediate}
+Let's use BA.
+\[
+\text{MA} = BA + \text{Immediate Value} = 0x7000 + 0x0096 = 0x7096
+\]
+
+\textbf{Indirect Addressing from Index and Immediate}
+Let's use XA.
+\[
+\text{MA} = XA + \text{Immediate Value} = 0x0004 + 0x0096 = 0x009A
+\]
+
+\textbf{Indirect Addressing from Base and Index with Immediate}
+Let's use BA and XA.
+\[
+\text{MA} = BA + XA + \text{Immediate Value} = 0x7000 + 0x0004 + 0x0096 = 0x709A
+\]
+
+\textbf{Immediate Addressing}
+\[
+\text{MA} = PC + \text{Immediate Value} = 0x0100 + 0x0096 = 0x0196
+\]
+
+\textbf{Direct Register Addressing}
+We don't use the memory address for this addressing mode.
+\[
+\text{MA} = 0
+\]
diff --git a/assignments/exam/booth/fetch.py b/assignments/exam/booth/fetch.py
new file mode 100644
index 00000000..a0ab2290
--- /dev/null
+++ b/assignments/exam/booth/fetch.py
@@ -0,0 +1,34 @@
+import sys, json, random, datetime
+args = {param.split('=')[0]: param.split('=')[1] for param in sys.argv[1:]}
+student_id = args['id']
+# TODO: change for EXAM
+secret = 0
+week=datetime.datetime.now().isocalendar()[0]
+random.seed(secret + week + int(student_id))
+
+m = random.randint(129, 255)
+r = random.randint(129, 255)
+
+r_bs = '{:016b}'.format(r)
+
+no_additions = 0
+r_bs = "0" + r_bs + "0"
+for i in range(1, 18):
+ if r_bs[i]!=r_bs[i-1]:
+ no_additions += 1
+
+# generate the question in html format
+question = """
+
+
Given the 16-bit Booth's algorithm, how many additions are required for {} multiply by {} ?
+
+""".format(m, r)
+
+print(
+ json.dumps(
+ {
+ "question": question,
+ "result": no_additions
+ }
+ )
+)
\ No newline at end of file
diff --git a/assignments/exam/booth/sol.tex b/assignments/exam/booth/sol.tex
new file mode 100644
index 00000000..853a29de
--- /dev/null
+++ b/assignments/exam/booth/sol.tex
@@ -0,0 +1,22 @@
+\section*{Problem}
+Given the 16-bit Booth's algorithm, how many additions are required for \( M \times R \)? $M=13$ and $R=11$.
+
+\section*{Solution}
+To calculate the number of additions required for \( M \times R \) using Booth's algorithm, we follow these steps:
+
+1. Convert the $R$ to binary:
+\begin{align*}
+R & = 11_{10} = 0000\_0000\_0000\_1011_2
+\end{align*}
+
+2. Transofrm the $R$ to Booth's algorithm format:
+\begin{align*}
+R & = 2^{4} - 2^{3} + 2^{2} - 2^{0}
+\end{align*}
+
+3. Count the number of additions required:
+\begin{align*}
+\text{Number of additions} & = 4
+\end{align*}
+
+
diff --git a/assignments/exam/cacheassociativity/fetch.py b/assignments/exam/cacheassociativity/fetch.py
new file mode 100644
index 00000000..cc169034
--- /dev/null
+++ b/assignments/exam/cacheassociativity/fetch.py
@@ -0,0 +1,92 @@
+import sys, json, random, datetime
+args = {param.split('=')[0]: param.split('=')[1] for param in sys.argv[1:]}
+student_id = args['id']
+# TODO: change for EXAM
+secret = 0
+week=datetime.datetime.now().isocalendar()[0]
+random.seed(secret + week + int(student_id))
+
+def calculate_miss_penalty(access_time, block_size, byte_transfer_times):
+ return access_time + (block_size * byte_transfer_times)
+
+def calculate_amat(hit_time, miss_rate, miss_penalty):
+ return hit_time + (miss_rate * miss_penalty)
+
+
+# Define the possible values for the cache size, block size, cache mapping, and associativity
+cache_sizes_in_KBytes = [16, 32, 64, 128, 256, 512, 1024, 2048, 4096]
+block_sizes_in_bytes = [8, 16, 32, 64, 128, 256, 512, 1024]
+cache_mapping = ['direct', 'set-associative', 'fully-associative']
+associativities = [2, 4, 8]
+main_memory_access_times = [x * 10 for x in range(12, 20)]
+cache_hit_times = [x * 2 for x in range(3, 5)]
+main_memory_byte_transfer_times = [x * 4 for x in cache_hit_times]
+cache_miss_rates = [float(x)/100 for x in range(6, 10)]
+
+
+# Randomly select one value from each list
+selected_cache_size = random.choice(cache_sizes_in_KBytes)
+selected_block_size = random.choice(block_sizes_in_bytes)
+selected_cache_mapping = 'direct'
+selected_main_memory_access_time = random.choice(main_memory_access_times)
+selected_cache_hit_time = random.choice(cache_hit_times)
+selected_main_memory_byte_transfer_time = random.choice(main_memory_byte_transfer_times)
+selected_cache_miss_rate = random.choice(cache_miss_rates)
+
+# select values for a modified cache in associativity
+selected_new_cache_mapping = 'set-associative'
+selected_new_associativity = random.choice(associativities)
+selected_new_cache_hit_time = selected_cache_hit_time * random.choice([1.5, 2, 2.5])
+selected_new_cache_miss_rate = selected_cache_miss_rate - random.choice([0.02, 0.03, 0.04])
+
+initial_miss_penalty = calculate_miss_penalty(selected_main_memory_access_time, selected_block_size, selected_main_memory_byte_transfer_time)
+initial_amat = calculate_amat(selected_cache_hit_time, selected_cache_miss_rate, initial_miss_penalty)
+new_miss_penalty = calculate_miss_penalty(selected_main_memory_access_time, selected_block_size, selected_main_memory_byte_transfer_time)
+new_amat = calculate_amat(selected_new_cache_hit_time, selected_new_cache_miss_rate, new_miss_penalty)
+speedup = initial_amat / new_amat
+
+selected_new_cache_mapping = str(selected_new_associativity) + '-way set-associative'
+
+# generate the html question
+question = """
+
+
We have a cache system with the following characteristics:
+
+ - One level cache
+ - Main memory access time: {}
+ - Main memory byte transfer time: {}
+ - Cache hit time: {}
+ - Cache miss rate: {}%
+ - Cache block size: {} bytes
+ - Cache size: {} KB
+ - Cache Mapping: {}
+
+
What is the speedup in average memory access time (AMAT) if we change the following characteristics:
+
+ - Cache hit time: {}
+ - Cache miss rate: {}%
+ - Cache Mapping: {}
+
+
+""".format(
+ selected_main_memory_access_time,
+ selected_main_memory_byte_transfer_time,
+ selected_cache_hit_time,
+ selected_cache_miss_rate * 100,
+ selected_block_size,
+ selected_cache_size,
+ selected_cache_mapping,
+ selected_new_cache_hit_time,
+ selected_new_cache_miss_rate * 100,
+ selected_new_cache_mapping
+)
+
+# Print the selected values
+print(
+ json.dumps(
+ {
+ 'question': question,
+ 'result': speedup
+ }
+ )
+)
diff --git a/assignments/exam/cacheassociativity/sol.tex b/assignments/exam/cacheassociativity/sol.tex
new file mode 100644
index 00000000..0f28e3b4
--- /dev/null
+++ b/assignments/exam/cacheassociativity/sol.tex
@@ -0,0 +1,59 @@
+\subsection*{Problem}
+
+We have a cache with the following characteristics:
+\begin{itemize}
+ \item Only one cache level
+ \item Main memory access time: 120 cycles $L_{MM}=120$
+ \item Main memory byte transfer time: 12 cycles $BT_{MM}=12$
+ \item Cache hit time: 4 cycle $H_{C}=4$
+ \item Cache miss rate: 5\% $MR_{C}=0.05$
+ \item Cache block size: 16 bytes $BS_{C}=16$
+ \item Cache size: 64 KB $S_{C}=64 \times 1024$
+ \item Cache is Direct Mapped
+\end{itemize}
+
+What is the speedup in average memory access time (AMAT) when the cache becomes 4-way set associative reducing the miss rate $MR_{NC}=0.02$, but the new cycle is double in time compared to the initial cache?
+
+\subsection*{Solution}
+
+To calculate the speedup in AMAT, we need to determine the AMAT before and after changing the cache to 4-way set associative and then compute the speedup.
+
+1. Calculate the initial miss penalty:
+\[
+\text{Initial miss penalty} = L_{MM} + (BS_{C} \times BT_{MM})
+\]
+\[
+\text{Initial miss penalty} = 120 \text{ cycles} + (16 \text{ bytes} \times 12 \text{ cycles/byte}) = 120 + 192 = 312 \text{ cycles}
+\]
+
+2. Calculate the initial AMAT:
+\[
+\text{Initial AMAT} = H_{C} + (MR_{C} \times \text{miss penalty})
+\]
+\[
+\text{Initial AMAT} = 4 \text{ cycles} + (0.05 \times 312 \text{ cycles}) = 4 + 15.6 = 19.6 \text{ cycles}
+\]
+
+3. Calculate the new miss penalty:
+\[
+\text{New miss penalty} = L_{MM} + (BS_{C} \times BT_{MM})
+\]
+\[
+\text{New miss penalty} = 120 \text{ cycles} + (16 \text{ bytes} \times 12 \text{ cycles/byte}) = 120 + 192 = 312 \text{ cycles}
+\]
+
+4. Calculate the new AMAT:
+Since the new cycle time is double that of the initial cache, the new hit time will be $2 \times H_{C} = 2 \times 4 = 8$ cycles.
+\[
+\text{New AMAT} = 8 \text{ cycles} + (0.02 \times 312 \text{ cycles}) = 8 + 6.24 = 14.24 \text{ cycles}
+\]
+
+5. Calculate the speedup:
+\[
+\text{Speedup} = \frac{\text{Initial AMAT}}{\text{New AMAT}}
+\]
+\[
+\text{Speedup} = \frac{19.6 \text{ cycles}}{14.24 \text{ cycles}} \approx 1.38
+\]
+
+Therefore, the speedup in average memory access time (AMAT) when the cache becomes 4-way set associative, reducing the miss rate to 0.02 but doubling the cycle time, is approximately 1.38.
diff --git a/assignments/exam/cacheblocksize/fetch.py b/assignments/exam/cacheblocksize/fetch.py
new file mode 100644
index 00000000..6611dcc1
--- /dev/null
+++ b/assignments/exam/cacheblocksize/fetch.py
@@ -0,0 +1,93 @@
+import sys, json, random, datetime
+args = {param.split('=')[0]: param.split('=')[1] for param in sys.argv[1:]}
+student_id = args['id']
+# TODO: change for EXAM
+secret = 0
+week=datetime.datetime.now().isocalendar()[0]
+random.seed(secret + week + int(student_id))
+
+def calculate_miss_penalty(access_time, block_size, byte_transfer_times):
+ return access_time + (block_size * byte_transfer_times)
+
+def calculate_amat(hit_time, miss_rate, miss_penalty):
+ return hit_time + (miss_rate * miss_penalty)
+
+
+# Define the possible values for the cache size, block size, cache mapping, and associativity
+cache_sizes_in_KBytes = [16, 32, 64, 128, 256, 512, 1024, 2048, 4096]
+block_sizes_in_bytes = [8, 16, 32, 64, 128, 256, 512, 1024]
+cache_mapping = ['direct', 'set-associative', 'fully-associative']
+associativities = [2, 4, 8]
+main_memory_access_times = [x * 10 for x in range(12, 20)]
+cache_hit_times = [x * 2 for x in range(1, 3)]
+main_memory_byte_transfer_times = [x * 4 for x in cache_hit_times]
+cache_miss_rates = [float(x)/100 for x in range(4, 7)]
+
+
+# Randomly select one value from each list
+selected_cache_size = random.choice(cache_sizes_in_KBytes)
+selected_block_size = random.choice(block_sizes_in_bytes)
+selected_cache_mapping = 'direct'
+selected_main_memory_access_time = random.choice(main_memory_access_times)
+selected_cache_hit_time = random.choice(cache_hit_times)
+selected_main_memory_byte_transfer_time = random.choice(main_memory_byte_transfer_times)
+selected_cache_miss_rate = random.choice(cache_miss_rates)
+
+# select values for a modified cache in block size
+selected_new_block_size = random.choice([x for x in block_sizes_in_bytes if x != selected_block_size])
+if selected_new_block_size > selected_block_size:
+ selected_new_cache_hit_time = selected_cache_hit_time + random.choice([-1, 1, 2])
+ selected_new_cache_miss_rate = selected_cache_miss_rate - random.choice([0.01, 0.02, 0.03])
+else:
+ selected_new_cache_hit_time = selected_cache_hit_time + random.choice([-1, 1, 2])
+ selected_new_cache_miss_rate = selected_cache_miss_rate + random.choice([0.01, 0.02, 0.03])
+
+initial_miss_penalty = calculate_miss_penalty(selected_main_memory_access_time, selected_block_size, selected_main_memory_byte_transfer_time)
+initial_amat = calculate_amat(selected_cache_hit_time, selected_cache_miss_rate, initial_miss_penalty)
+new_miss_penalty = calculate_miss_penalty(selected_main_memory_access_time, selected_new_block_size, selected_main_memory_byte_transfer_time)
+new_amat = calculate_amat(selected_new_cache_hit_time, selected_new_cache_miss_rate, new_miss_penalty)
+speedup = initial_amat / new_amat
+
+# generate the html question
+question = """
+
+
We have a cache system with the following characteristics:
+
+ - One level cache
+ - Main memory access time: {}
+ - Main memory byte transfer time: {}
+ - Cache hit time: {}
+ - Cache miss rate: {}%
+ - Cache block size: {} bytes
+ - Cache size: {} KB
+ - Cache Mapping: {}
+
+
What is the speedup in average memory access time (AMAT) if we change the following characteristics:
+
+ - Cache hit time: {}
+ - Cache miss rate: {}%
+ - Cache block size: {} bytes
+
+
+""".format(
+ selected_main_memory_access_time,
+ selected_main_memory_byte_transfer_time,
+ selected_cache_hit_time,
+ selected_cache_miss_rate * 100,
+ selected_block_size,
+ selected_cache_size,
+ selected_cache_mapping,
+ selected_new_cache_hit_time,
+ selected_new_cache_miss_rate * 100,
+ selected_new_block_size
+)
+
+# Print the selected values
+print(
+ json.dumps(
+ {
+ 'question': question,
+ 'result': speedup
+ }
+ )
+)
diff --git a/assignments/exam/cacheblocksize/sol.tex b/assignments/exam/cacheblocksize/sol.tex
new file mode 100644
index 00000000..03555782
--- /dev/null
+++ b/assignments/exam/cacheblocksize/sol.tex
@@ -0,0 +1,61 @@
+\subsection*{Problem}
+
+We have a cache system with the following characteristics:
+\begin{itemize}
+ \item Only one cache level
+ \item Main memory access time: 120 cycles $L_{MM}=120$
+ \item Main memory byte transfer time: 12 cycles $BT_{MM}=12$
+ \item Cache hit time: 4 cycle $H_{C}=4$
+ \item Cache miss rate: 5\% $MR_{C}=0.05$
+ \item Cache block size: 16 bytes $BS_{C}=16$
+ \item Cache size: 64 KB $S_{C}=64 \times 1024$
+ \item Cache is Direct Mapped
+\end{itemize}
+What is the speedup in average memory access time (AMAT) when the cache block size is increased to $BS_{NC}=64$ to reduce the memory miss rate to $MR_{NC}=0.03$ and $H_{NC}=2$?
+
+\subsection*{Solution}
+
+To calculate the speedup in AMAT, we need to determine the AMAT before and after increasing the cache block size
+and then compute the speedup.
+
+1. Calculate the initial miss penalty:
+\[
+\text{Initial miss penalty} = L_{MM} + \left(BS_{C} \times BT_{MM}\right)
+\]
+\[
+\text{Initial miss penalty} = 120 \text{ cycles} + \left(16 \text{ bytes} \times 12 \text{ cycles/byte}\right) = 120 + 192 = 312 \text{ cycles}
+\]
+
+2. Calculate the initial AMAT:
+\[
+\text{Initial AMAT} = H_{C} + (MR_{C} \times \text{miss penalty})
+\]
+\[
+\text{Initial AMAT} = 4 \text{ cycles} + (0.05 \times 312 \text{ cycles}) = 4 + 15.6 = 19.6 \text{ cycles}
+\]
+
+3. Calculate the new miss penalty:
+\[
+\text{New miss penalty} = L_{MM} + \left(BS_{NC} \times BT_{MM}\right)
+\]
+\[
+\text{New miss penalty} = 120 \text{ cycles} + \left(64 \text{ bytes} \times 12 \text{ cycles/byte}\right) = 120 + 768 = 888 \text{ cycles}
+\]
+
+4. Calculate the new AMAT:
+\[
+\text{New AMAT} = H_{NC} + (MR_{NC} \times \text{miss penalty})
+\]
+\[
+\text{New AMAT} = 2 \text{ cycles} + (0.02 \times 888 \text{ cycles}) = 2 + 17.76 = 19.76 \text{ cycles}
+\]
+
+5. Calculate the speedup:
+\[
+\text{Speedup} = \frac{\text{Initial AMAT}}{\text{New AMAT}}
+\]
+\[
+\text{Speedup} = \frac{19.6 \text{ cycles}}{19.76 \text{ cycles}} \approx 0.992
+\]
+
+Therefore, the speedup in average memory access time (AMAT) when the cache block size is increased from 16 to 64 bytes and the hit time is decreased to 2 cycles is approximately 0.992.
diff --git a/assignments/exam/cachesize/fetch.py b/assignments/exam/cachesize/fetch.py
new file mode 100644
index 00000000..f0824436
--- /dev/null
+++ b/assignments/exam/cachesize/fetch.py
@@ -0,0 +1,92 @@
+import sys, json, random, datetime
+args = {param.split('=')[0]: param.split('=')[1] for param in sys.argv[1:]}
+student_id = args['id']
+# TODO: change for EXAM
+secret = 0
+week=datetime.datetime.now().isocalendar()[0]
+random.seed(secret + week + int(student_id))
+
+def calculate_miss_penalty(access_time, block_size, byte_transfer_times):
+ return access_time + (block_size * byte_transfer_times)
+
+def calculate_amat(hit_time, miss_rate, miss_penalty):
+ return hit_time + (miss_rate * miss_penalty)
+
+
+# Define the possible values for the cache size, block size, cache mapping, and associativity
+cache_sizes_in_KBytes = [16, 32, 64, 128, 256, 512, 1024, 2048, 4096]
+block_sizes_in_bytes = [8, 16, 32, 64, 128, 256, 512, 1024]
+cache_mapping = ['direct', 'set-associative', 'fully-associative']
+associativities = [2, 4, 8]
+main_memory_access_times = [x * 10 for x in range(12, 20)]
+cache_hit_times = [x * 2 for x in range(3, 5)]
+main_memory_byte_transfer_times = [x * 4 for x in cache_hit_times]
+cache_miss_rates = [float(x)/100 for x in range(6, 10)]
+
+
+# Randomly select one value from each list
+selected_cache_size = random.choice(cache_sizes_in_KBytes)
+selected_block_size = random.choice(block_sizes_in_bytes)
+selected_cache_mapping = 'direct'
+selected_main_memory_access_time = random.choice(main_memory_access_times)
+selected_cache_hit_time = random.choice(cache_hit_times)
+selected_main_memory_byte_transfer_time = random.choice(main_memory_byte_transfer_times)
+selected_cache_miss_rate = random.choice(cache_miss_rates)
+
+# select values for a modified cache in cache size
+selected_new_cache_size = random.choice([x for x in cache_sizes_in_KBytes if x != selected_cache_size])
+if selected_new_cache_size > selected_cache_size:
+ selected_new_cache_hit_time = selected_cache_hit_time + random.choice([2, 4, 6])
+ selected_new_cache_miss_rate = selected_cache_miss_rate - random.choice([0.02, 0.03, 0.04])
+else:
+ selected_new_cache_hit_time = selected_cache_hit_time + random.choice([-2, -3, -4, -5])
+ selected_new_cache_miss_rate = selected_cache_miss_rate + random.choice([0.02, 0.03, 0.04])
+
+initial_miss_penalty = calculate_miss_penalty(selected_main_memory_access_time, selected_block_size, selected_main_memory_byte_transfer_time)
+initial_amat = calculate_amat(selected_cache_hit_time, selected_cache_miss_rate, initial_miss_penalty)
+new_miss_penalty = calculate_miss_penalty(selected_main_memory_access_time, selected_block_size, selected_main_memory_byte_transfer_time)
+new_amat = calculate_amat(selected_new_cache_hit_time, selected_new_cache_miss_rate, new_miss_penalty)
+speedup = initial_amat / new_amat
+
+# generate the html question
+question = """
+
+
We have a cache system with the following characteristics:
+
+ - One level cache
+ - Main memory access time: {}
+ - Main memory byte transfer time: {}
+ - Cache hit time: {}
+ - Cache miss rate: {}%
+ - Cache block size: {} bytes
+ - Cache size: {} KB
+ - Cache Mapping: {}
+
+
What is the speedup in average memory access time (AMAT) if we change the following characteristics:
+
+ - Cache hit time: {}
+ - Cache miss rate: {}%
+ - Cache size: {} KB
+
+
+""".format(
+ selected_main_memory_access_time,
+ selected_main_memory_byte_transfer_time,
+ selected_cache_hit_time,
+ selected_cache_miss_rate * 100,
+ selected_block_size,
+ selected_cache_size,
+ selected_cache_mapping,
+ selected_new_cache_hit_time,
+ selected_new_cache_miss_rate * 100,
+ selected_new_cache_size
+)
+# Print the selected values
+print(
+ json.dumps(
+ {
+ 'question': question,
+ 'result': speedup
+ }
+ )
+)
diff --git a/assignments/exam/cachesize/sol.tex b/assignments/exam/cachesize/sol.tex
new file mode 100644
index 00000000..802b5e90
--- /dev/null
+++ b/assignments/exam/cachesize/sol.tex
@@ -0,0 +1,60 @@
+\subsection*{Problem}
+
+We have a cache with the following characteristics:
+\begin{itemize}
+ \item Only one cache level
+ \item Main memory access time: 120 cycles $L_{MM}=120$
+ \item Main memory byte transfer time: 12 cycles $BT_{MM}=12$
+ \item Cache hit time: 4 cycle $H_{C}=4$
+ \item Cache miss rate: 5\% $MR_{C}=0.05$
+ \item Cache block size: 16 bytes $BS_{C}=16$
+ \item Cache size: 64 KB $S_{C}=64 \times 1024$
+ \item Cache is Direct Mapped
+\end{itemize}
+What is the speedup in average memory access time (AMAT) when the cache size is increased to $S_{NC}=128 \times 1024$ to reduce the memory miss rate to $MR_{NC}=0.02$ and increase $H_{NC}=6$?
+
+\subsection*{Solution}
+
+To calculate the speedup in AMAT, we need to determine the AMAT before and after increasing the cache size and then compute the speedup.
+
+1. Calculate the initial miss penalty:
+\[
+\text{Initial miss penalty} = L_{MM} + (BS_{C} \times BT_{MM})
+\]
+\[
+\text{Initial miss penalty} = 120 \text{ cycles} + (16 \text{ bytes} \times 12 \text{ cycles/byte}) = 120 + 192 = 312 \text{ cycles}
+\]
+
+2.*Calculate the initial AMAT:
+\[
+\text{Initial AMAT} = H_{C} + (MR_{C} \times \text{miss penalty})
+\]
+\[
+\text{Initial AMAT} = 4 \text{ cycles} + (0.05 \times 312 \text{ cycles}) = 4 + 15.6 = 19.6 \text{ cycles}
+\]
+
+3. Calculate the new miss penalty:
+\[
+\text{New miss penalty} = L_{MM} + (BS_{C} \times BT_{MM})
+\]
+\[
+\text{New miss penalty} = 120 \text{ cycles} + (16 \text{ bytes} \times 12 \text{ cycles/byte}) = 120 + 192 = 312 \text{ cycles}
+\]
+
+4. Calculate the new AMAT:
+\[
+\text{New AMAT} = H_{NC} + (MR_{NC} \times \text{miss penalty})
+\]
+\[
+\text{New AMAT} = 6 \text{ cycles} + (0.02 \times 312 \text{ cycles}) = 6 + 6.24 = 12.24 \text{ cycles}
+\]
+
+5. Calculate the speedup:
+\[
+\text{Speedup} = \frac{\text{Initial AMAT}}{\text{New AMAT}}
+\]
+\[
+\text{Speedup} = \frac{19.6 \text{ cycles}}{12.24 \text{ cycles}} \approx 1.60
+\]
+
+Therefore, the speedup in average memory access time (AMAT) when the cache size is increased from 64 KB to 128 KB and the hit time is increased to 6 cycles is approximately 1.60.
diff --git a/assignments/exam/cachetype/fetch.py b/assignments/exam/cachetype/fetch.py
new file mode 100644
index 00000000..72c89857
--- /dev/null
+++ b/assignments/exam/cachetype/fetch.py
@@ -0,0 +1,97 @@
+import sys, json, random, datetime
+args = {param.split('=')[0]: param.split('=')[1] for param in sys.argv[1:]}
+student_id = args['id']
+# TODO: change for EXAM
+secret = 0
+week=datetime.datetime.now().isocalendar()[0]
+random.seed(secret + week + int(student_id))
+
+def calculate_cache_parameter(cachesize, blocksize, cachemapping, associativity, addressbits, questiontag):
+ # Calculate the number of blocks in the cache
+ cache_size_bytes = cachesize * 1024
+ number_of_blocks = cache_size_bytes // blocksize
+
+ # Calculate the number of sets in the cache
+ if cachemapping == 'direct':
+ number_of_sets = number_of_blocks
+ elif cachemapping == 'fully-associative':
+ number_of_sets = 1
+ elif cachemapping == 'set-associative':
+ number_of_sets = number_of_blocks // associativity
+
+ # Calculate the number of bits for the block offset
+ block_offset_bits = blocksize.bit_length() - 1
+
+ # Calculate the number of bits for the index
+ index_bits = number_of_sets.bit_length() - 1
+
+ # Calculate the number of bits for the tag
+ tag_bits = addressbits - index_bits - block_offset_bits
+
+ if questiontag == 'tag':
+ return tag_bits
+ elif questiontag == 'index':
+ return index_bits
+ elif questiontag == 'block offset':
+ return block_offset_bits
+ else:
+ return addressbits
+
+# Define the possible values for the cache size, block size, cache mapping, and associativity
+cache_sizes_in_KBytes = [16, 32, 64, 128, 256, 512, 1024, 2048, 4096]
+block_sizes_in_bytes = [8, 16, 32, 64, 128, 256, 512, 1024]
+cache_mapping = ['direct', 'set-associative', 'fully-associative']
+associativities = [2, 4, 8]
+address_bits = [32, 64]
+question_tags = ['tag', 'index', 'block offset']
+
+
+# Randomly select one value from each list
+selected_cache_size = random.choice(cache_sizes_in_KBytes)
+selected_block_size = random.choice(block_sizes_in_bytes)
+selected_cache_mapping = random.choice(cache_mapping)
+selected_address_bits = random.choice(address_bits)
+selected_question_tag = random.choice(question_tags)
+
+# If the cache mapping is set-associative, randomly select the associativity
+if selected_cache_mapping == 'set-associative':
+ selected_associativity = random.choice(associativities)
+else:
+ selected_associativity = 0
+
+# Calculate the cache parameter
+selected_cache_parameter = calculate_cache_parameter(
+ selected_cache_size, selected_block_size, selected_cache_mapping, selected_associativity, selected_address_bits, selected_question_tag
+)
+
+if selected_cache_mapping == 'set-associative':
+ selected_cache_mapping = str(selected_associativity) + '-way set-associative'
+
+
+# generate the html question
+question = """
+
+
Calculate the number of bits for the {} for a cache memory with the following characteristics:
+
+ - Cache size: {} KB
+ - Block size: {} bytes
+ - Mapping: {}
+
+
The address space is {} bits.
+
+""".format(
+ selected_question_tag,
+ selected_cache_size,
+ selected_block_size,
+ selected_cache_mapping,
+ selected_address_bits
+)
+# Print the selected values
+print(
+ json.dumps(
+ {
+ 'question': question,
+ 'result': selected_cache_parameter
+ }
+ )
+)
diff --git a/assignments/exam/cachetype/sol.tex b/assignments/exam/cachetype/sol.tex
new file mode 100644
index 00000000..0863bbbd
--- /dev/null
+++ b/assignments/exam/cachetype/sol.tex
@@ -0,0 +1,46 @@
+\subsection*{Problem}
+
+Calculate the number of bits for the tag, index, and block offset for a cache memory with the following characteristics:
+\begin{itemize}
+ \item Cache size: 64 KB
+ \item Block size: 16 bytes
+ \item Cache is 4-way set associative
+\end{itemize}
+The address space is 32 bits.
+
+\subsection*{Solution}
+
+To calculate the number of bits for the tag, index, and block offset, we follow these steps:
+
+1. Calculate the number of blocks in the cache:
+\[
+\text{Number of blocks} = \frac{\text{Cache size}}{\text{Block size}} = \frac{64 \text{ KB}}{16 \text{ bytes}} = \frac{64 \times 1024 \text{ bytes}}{16 \text{ bytes}} = 4096 \text{ blocks}
+\]
+
+2. Calculate the number of sets in the cache:
+\[
+\text{Number of sets} = \frac{\text{Number of blocks}}{\text{Associativity}} = \frac{4096 \text{ blocks}}{4} = 1024 \text{ sets}
+\]
+
+3. Calculate the number of bits for the block offset:
+\[
+\text{Block offset bits} = \log_2(\text{Block size}) = \log_2(16 \text{ bytes}) = 4 \text{ bits}
+\]
+
+4. Calculate the number of bits for the index:
+\[
+\text{Index bits} = \log_2(\text{Number of sets}) = \log_2(1024) = 10 \text{ bits}
+\]
+
+5. Calculate the number of bits for the tag:
+Assuming a 32-bit address space:
+\[
+\text{Tag bits} = \text{Total address bits} - \text{Index bits} - \text{Block offset bits} = 32 - 10 - 4 = 18 \text{ bits}
+\]
+
+Therefore, the number of bits for the tag, index, and block offset are:
+\begin{itemize}
+ \item Tag bits: 18
+ \item Index bits: 10
+ \item Block offset bits: 4
+\end{itemize}
\ No newline at end of file
diff --git a/assignments/exam/common/answer.md b/assignments/exam/common/answer.md
new file mode 100644
index 00000000..1cd76770
--- /dev/null
+++ b/assignments/exam/common/answer.md
@@ -0,0 +1 @@
+{{ result }}
\ No newline at end of file
diff --git a/assignments/exam/common/question.html b/assignments/exam/common/question.html
new file mode 100644
index 00000000..e45e7717
--- /dev/null
+++ b/assignments/exam/common/question.html
@@ -0,0 +1,6 @@
+
+
\ No newline at end of file
diff --git a/assignments/exam/common/run/binary.py b/assignments/exam/common/run/binary.py
new file mode 100644
index 00000000..431494b9
--- /dev/null
+++ b/assignments/exam/common/run/binary.py
@@ -0,0 +1,31 @@
+import re
+
+student_binary_text = """{{ STUDENT_ANSWER }}"""
+question_number = """{{ result }}"""
+question_number = int(question_number, 2) # Convert the expected result to an integer from binary
+precheck = {{ IS_PRECHECK }}
+
+SEPARATOR = "##"
+
+# Regex to match any binary integer text (0 or 1)
+regex = r"^[01]+$"
+
+fixed_length = 8
+
+{% for TEST in TESTCASES %}
+if re.match(regex, student_binary_text):
+ if len(student_binary_text) != fixed_length:
+ print('You need to have exactly 8 binary characters')
+ else:
+ if precheck != 1:
+ if int(student_binary_text, 2) == question_number:
+ print('correct')
+ else:
+ print('incorrect')
+else:
+ print("The value must be a binary text")
+# {{ TEST.testcode }}
+{% if not loop.last %}
+print(SEPARATOR)
+{% endif %}
+{% endfor %}
\ No newline at end of file
diff --git a/assignments/exam/common/run/float.py b/assignments/exam/common/run/float.py
new file mode 100644
index 00000000..ee99353a
--- /dev/null
+++ b/assignments/exam/common/run/float.py
@@ -0,0 +1,27 @@
+import re
+
+student_decimal_text = """{{ STUDENT_ANSWER }}"""
+question_number = """{{ result }}"""
+question_number = float(question_number)
+precheck = {{ IS_PRECHECK }}
+
+# __student_answer__ = """{{ STUDENT_ANSWER | e('py') }}"""
+
+SEPARATOR = "##"
+
+regex = r"^[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$"
+
+{% for TEST in TESTCASES %}
+if re.match(regex, student_decimal_text):
+ if precheck != 1:
+ if abs(float(student_decimal_text) - question_number) < 0.1:
+ print('correct')
+ else:
+ print('incorrect')
+else:
+ print("This is not a floating point number")
+# {{ TEST.testcode }}
+{% if not loop.last %}
+print(SEPARATOR)
+{% endif %}
+{% endfor %}
\ No newline at end of file
diff --git a/assignments/exam/common/run/hex.py b/assignments/exam/common/run/hex.py
new file mode 100644
index 00000000..b3db3b18
--- /dev/null
+++ b/assignments/exam/common/run/hex.py
@@ -0,0 +1,30 @@
+import re
+
+student_hex_text = """{{ STUDENT_ANSWER }}"""
+question_answer = """{{ result }}"""
+precheck = {{ IS_PRECHECK }}
+
+SEPARATOR = "##"
+
+# Regex for hexadecimal string starting with '0x'
+regex = r"^0x[0-9A-Fa-f]+$"
+
+fixed_length = 4
+
+{% for TEST in TESTCASES %}
+if re.match(regex, student_hex_text):
+ if len(student_hex_text) != (fixed_length + 2):
+ print('You need to have exact {} hexadecimal characters after 0x'.format(fixed_length))
+ else:
+ if precheck != 1:
+ if int(student_hex_text, 16) == int(question_answer, 16):
+ print('correct')
+ else:
+ print('incorrect')
+else:
+ print("This is not a valid hexadecimal number")
+# {{ TEST.testcode }}
+{% if not loop.last %}
+print(SEPARATOR)
+{% endif %}
+{% endfor %}
\ No newline at end of file
diff --git a/assignments/exam/common/run/integer.py b/assignments/exam/common/run/integer.py
new file mode 100644
index 00000000..70072cd0
--- /dev/null
+++ b/assignments/exam/common/run/integer.py
@@ -0,0 +1,26 @@
+import re
+
+student_decimal_text = """{{ STUDENT_ANSWER }}"""
+question_number = """{{ result }}"""
+question_number = int(question_number)
+precheck = {{ IS_PRECHECK }}
+
+SEPARATOR = "##"
+
+# Regex to match any decimal integer text, including negative integers
+regex = r"^-?\d+$"
+
+{% for TEST in TESTCASES %}
+if re.match(regex, student_decimal_text):
+ if precheck != 1:
+ if int(student_decimal_text, 10) == question_number:
+ print('correct')
+ else:
+ print('incorrect')
+else:
+ print("The value must be an integer")
+# {{ TEST.testcode }}
+{% if not loop.last %}
+print(SEPARATOR)
+{% endif %}
+{% endfor %}
\ No newline at end of file
diff --git a/assignments/exam/decoding/fetch.py b/assignments/exam/decoding/fetch.py
new file mode 100644
index 00000000..7c6550c9
--- /dev/null
+++ b/assignments/exam/decoding/fetch.py
@@ -0,0 +1,222 @@
+import sys, json, random, datetime
+args = {param.split('=')[0]: param.split('=')[1] for param in sys.argv[1:]}
+student_id = args['id']
+# TODO: change for EXAM
+secret = 0
+week=datetime.datetime.now().isocalendar()[0]
+# to be different from the encode one
+random.seed(secret + 1 + week + int(student_id))
+
+# Define the 2D array based on the LaTeX table
+addressing_table = [
+ ["[BA+XA]", "[BA+XA+]", "[BA+XA+Imm]", "RA"],
+ ["[BA+XB]", "[BA+XB+]", "[BA+XB+Imm]", "RB"],
+ ["[BB+XA]", "[BB+XA+]", "[BB+XA+Imm]", "RC"],
+ ["[BB+XB]", "[BB+XB+]", "[BB+XB+Imm]", "SP"],
+ ["[XA]", "[BA+(-XA)]", "[XA+Imm]", "XA"],
+ ["[XB]", "[BB+(-XA)]", "[XB+Imm]", "XB"],
+ ["[BA]", "[Imm]", "[BA+Imm]", "BA"],
+ ["[BB]", "[[Imm]]", "[BB+Imm]", "BB"]
+]
+
+# Define the row and column labels
+rm_labels = ["000", "001", "010", "011", "100", "101", "110", "111"]
+mod_labels = ["00", "01", "10", "11"]
+
+# Generate the addressing table in html format
+addressing_table_html = """
+
+
+ MOD \ RM |
+"""
+for mod in mod_labels:
+ addressing_table_html += f"{mod} | "
+addressing_table_html += "
\n"
+for i, rm in enumerate(rm_labels):
+ addressing_table_html += f"{rm} | "
+ for j in range(len(mod_labels)):
+ addressing_table_html += f"{addressing_table[i][j]} | "
+ addressing_table_html += "
\n"
+addressing_table_html += "
"
+# print(addressing_table_html)
+
+opcode_table = {
+ "0000000" : "MOV",
+ "0001000" : "INC",
+ "0001001" : "DEC",
+ "0001010" : "NEG",
+ "0001011" : "NOT",
+ "0001100" : "SHL",
+ "0001101" : "SHR",
+ "0001110" : "SAR",
+ "0101000" : "ADD",
+ "0101001" : "ADC",
+ "0101010" : "SUB",
+ "0101011" : "SBB",
+ "0101100" : "AND",
+ "0101101" : "OR",
+ "0101110" : "XOR"
+}
+
+# Generate the opcode table in html format
+opcode_table_html = """
+
+
+ OPCODE | INSTRUCTION |
+"""
+for opcode in opcode_table:
+ opcode_table_html += f"{opcode} | {opcode_table[opcode]} |
\n"
+opcode_table_html += "
"
+# print(opcode_table_html)
+
+instruction_register_table = [
+ ["Instruction Register (IR)"],
+ ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"],
+ ["OPC", "OPC", "OPC", "OPC", "OPC", "OPC", "OPC", "d", "MOD", "MOD", "REG", "REG", "REG", "RM", "RM", "RM"]
+]
+# Generate the instruction register table in html format
+instruction_register_table_html = """
+
+
+ Instruction Register (IR) |
+
+"""
+for i in instruction_register_table[1]:
+ instruction_register_table_html += f"{i} | "
+instruction_register_table_html += "
\n"
+instruction_register_table_html += ""
+instruction_register_table_html += "OPC | "
+instruction_register_table_html += "d | "
+instruction_register_table_html += "MOD | "
+instruction_register_table_html += "REG | "
+instruction_register_table_html += "RM | "
+instruction_register_table_html += "
\n"
+instruction_register_table_html += "
"
+# print(instruction_register_table_html)
+
+register_table = {
+ "000" : "RA",
+ "001" : "RB",
+ "010" : "RC",
+ "011" : "SP",
+ "100" : "XA",
+ "101" : "XB",
+ "110" : "BA",
+ "111" : "BB"
+}
+# Generate the registers table in html format
+registers_table_html = """
+
+
+ REG | Name |
+"""
+for register in register_table:
+ registers_table_html += f"{register} | {register_table[register]} |
"
+registers_table_html += "
"
+# print(registers_table_html)
+
+# Generate the random test case
+
+# first opcode
+opcode = random.choice(list(opcode_table.keys()))
+
+# get the mod and rm values
+# mod can not be 10
+mod = random.choice(mod_labels)
+while mod == "10":
+ mod = random.choice(mod_labels)
+# if mod is 01 rm can not be 110 or 111
+rm = random.choice(rm_labels)
+while mod == "01" and rm in ["110", "111"]:
+ rm = random.choice(rm_labels)
+# test if it has one or two operands
+d = '0'
+reg = "000"
+instruction_text = opcode_table[opcode] + " "
+if opcode[1] == '0' and opcode[3] == '1':
+ instruction_text += addressing_table[int(rm, 2)][int(mod, 2)]
+else:
+ d = random.choice(["0", "1"])
+ reg = random.choice(list(register_table.keys()))
+ if d == "1":
+ instruction_text += register_table[reg] + ", " + addressing_table[int(rm, 2)][int(mod, 2)]
+ else:
+ instruction_text += addressing_table[int(rm, 2)][int(mod, 2)] + ", " + register_table[reg]
+
+# generate the instruction
+instruction_binary = opcode + d + mod + reg + rm
+instruction_hex = hex(int(instruction_binary, 2))
+
+# generate the question in html format
+question = """
+
+
Having the following memory addressing table, instruction format table, registers address table, and opcode table. What is the following instuction encoded in hexadecimal IR={} ?
+
Write the answer ah "OPERATION DESTINATION, SOURCE" (space between OPERATION and DESTINATION, ", " between DESTINATION and SOURCE)
+
+
Memory Addressing Table:
+ {}
+
+
+
Instruction Format Table:
+ {}
+
+
+
Registers Address Table:
+ {}
+
+
+
Opcode Table:
+ {}
+
+
+""".format(
+ instruction_hex,
+ addressing_table_html,
+ instruction_register_table_html,
+ registers_table_html,
+ opcode_table_html
+)
+
+
+print(
+ json.dumps({
+ "question": question,
+ "result": instruction_text
+ })
+)
diff --git a/assignments/exam/decoding/run.py b/assignments/exam/decoding/run.py
new file mode 100644
index 00000000..31ff49a5
--- /dev/null
+++ b/assignments/exam/decoding/run.py
@@ -0,0 +1,83 @@
+import re
+
+student_text = """{{ STUDENT_ANSWER }}"""
+question_answer = """{{ result }}"""
+question_answer = question_answer.strip().upper()
+student_text = student_text.strip().upper()
+precheck = {{ IS_PRECHECK }}
+
+SEPARATOR = "##"
+
+addressing_table = [
+ ["[BA+XA]", "[BA+XA+]", "[BA+XA+Imm]", "RA"],
+ ["[BA+XB]", "[BA+XB+]", "[BA+XB+Imm]", "RB"],
+ ["[BB+XA]", "[BB+XA+]", "[BB+XA+Imm]", "RC"],
+ ["[BB+XB]", "[BB+XB+]", "[BB+XB+Imm]", "SP"],
+ ["[XA]", "[BA+(-XA)]", "[XA+Imm]", "XA"],
+ ["[XB]", "[BB+(-XA)]", "[XB+Imm]", "XB"],
+ ["[BA]", "[Imm]", "[BA+Imm]", "BA"],
+ ["[BB]", "[[Imm]]", "[BB+Imm]", "BB"]
+]
+opcode_table = {
+ "0000000" : "MOV",
+ "0001000" : "INC",
+ "0001001" : "DEC",
+ "0001010" : "NEG",
+ "0001011" : "NOT",
+ "0001100" : "SHL",
+ "0001101" : "SHR",
+ "0001110" : "SAR",
+ "0101000" : "ADD",
+ "0101001" : "ADC",
+ "0101010" : "SUB",
+ "0101011" : "SBB",
+ "0101100" : "AND",
+ "0101101" : "OR",
+ "0101110" : "XOR"
+}
+
+def string_to_regex(string):
+ return string.replace("[", r"\[").replace("]", r"\]").replace("+", r"\+").replace("-", r"\-").replace("(", r"\(").replace(")", r"\)")
+
+# generate a regex pattern for the addressing table
+addressing_table_pattern = ""
+for row in addressing_table:
+ for element in row:
+ addressing_table_pattern += string_to_regex(element) + "|"
+addressing_table_pattern = addressing_table_pattern[:-1]
+
+opcode_table_pattern = ""
+for key in opcode_table:
+ opcode_table_pattern += opcode_table[key] + "|"
+opcode_table_pattern = opcode_table_pattern[:-1]
+
+instruction_pattern = r"^({opcode_table_pattern})\ ({addressing_table_pattern})(\,\ ({addressing_table_pattern}))?$".format(
+ opcode_table_pattern=opcode_table_pattern,
+ addressing_table_pattern=addressing_table_pattern
+)
+operation_pattern = r"({opcode_table_pattern})\ .*".format(
+ opcode_table_pattern=opcode_table_pattern
+)
+
+possible_addressing = []
+for row in addressing_table:
+ for element in row:
+ possible_addressing.append(element)
+
+{% for TEST in TESTCASES %}
+if re.match(instruction_pattern, student_text):
+ if precheck != 1:
+ if student_text == question_answer:
+ print('correct')
+ else:
+ print('incorrect')
+else:
+ if re.match(operation_pattern, student_text):
+ print("The ADDRESSING is incorrect it can be one of {} and if it has SOURCE use ', ' between DESTINATION and SOOURCE".format(possible_addressing))
+ else:
+ print("The OPERATION is incorrect it can be one of {}".format(opcode_table.values()))
+{{ TEST.testcode }}
+{% if not loop.last %}
+print(SEPARATOR)
+{% endif %}
+{% endfor %}
\ No newline at end of file
diff --git a/assignments/exam/decoding/sol.tex b/assignments/exam/decoding/sol.tex
new file mode 100644
index 00000000..5673c415
--- /dev/null
+++ b/assignments/exam/decoding/sol.tex
@@ -0,0 +1,25 @@
+\section*{Problem}
+Having the memory addressing table and instruction format tables, what instruction type has the following coding IR=\texttt{0x0140}?
+
+\section*{Solution}
+
+
+\begin{itemize}
+ \item \textbf{OPC}: \texttt{0000\_000}
+ \item \textbf{d}: \texttt{1}
+ \item \textbf{MOD}: \texttt{01}
+ \item \textbf{REG}: \texttt{000}
+ \item \textbf{RM}: \texttt{000}
+\end{itemize}
+
+
+\textbf{Identify the isntruction from the opcode using the instruction format table and the memory addressing table}.:
+\begin{itemize}
+ \item \texttt{MOV} is encoded as \texttt{000} when $IR_{1}=0$, $IR_{3}=0$, $IR_{0}=0$, and $IR_{2}=0$.
+ \item $d$ is \texttt{1} and $REG$ is \texttt{000} so destination register is \texttt{RA}.
+ \item $RM=IR_{13:15}=000$ and $MOD=IR_{8:9}=01$ so the addressing mode is \texttt{[BA+XA+]}.
+\end{itemize}
+
+The instruction is \texttt{MOV RA, [BA+XA+]}.
+
+Type of the instruction is \texttt{MOV}.
\ No newline at end of file
diff --git a/assignments/exam/flags/fetch.py b/assignments/exam/flags/fetch.py
new file mode 100644
index 00000000..21b93d36
--- /dev/null
+++ b/assignments/exam/flags/fetch.py
@@ -0,0 +1,62 @@
+import sys, json, random, datetime
+args = {param.split('=')[0]: param.split('=')[1] for param in sys.argv[1:]}
+student_id = args['id']
+# TODO: change for EXAM
+secret = 0
+week=datetime.datetime.now().isocalendar()[0]
+random.seed(secret + week + int(student_id))
+
+m = random.randint(0, 255)
+r = random.randint(0, 255)
+
+result = 0
+
+# operations = ['+', '-', 'x', '/', ]
+# selected_operation = random.choice(operations)
+
+# if selected_operation == '+':
+# result = m + r
+# elif selected_operation == '-':
+# result = m - r
+# elif selected_operation == 'x':
+# result = m * r
+# elif selected_operation == '/':
+# result = m / r
+
+
+result = m + r
+result_bs = '{:08b}'.format(result)
+m_bs = '{:08b}'.format(m)
+r_bs = '{:08b}'.format(r)
+m_sign = 1 if m_bs[0] == '1' else 0
+r_sign = 1 if r_bs[0] == '1' else 0
+
+# compute the flags
+zero_flag = 1
+carry_flag = 1 if result > 255 else 0
+sign_flag = 1 if result_bs[0] == '1' else 0
+overflow_flag = 1 if m_sign == r_sign and m_sign != sign_flag else 0
+parity_flag = 0
+
+for i in range(8):
+ if result_bs[i] == '1':
+ parity_flag += 1
+ zero_flag = 0
+parity_flag = 1 if parity_flag % 2 == 0 else 0
+
+flag_register_bs = str(zero_flag) + str(carry_flag) + str(sign_flag) + str(overflow_flag) + str(parity_flag)
+# generate the html question
+question = """
+
+
What is the binary representation of the the 5-bit status flags register (order from left Zero Flag, Carry Flag, Sign Flag, Overflow Flag, Parity Flag) after the 8-bit operation {} plus {} ?
+
+""".format(m, r)
+
+print(
+ json.dumps(
+ {
+ "question": question,
+ "result": flag_register_bs
+ }
+ )
+)
\ No newline at end of file
diff --git a/assignments/exam/flags/sol.tex b/assignments/exam/flags/sol.tex
new file mode 100644
index 00000000..0905f27a
--- /dev/null
+++ b/assignments/exam/flags/sol.tex
@@ -0,0 +1,53 @@
+\section*{Problem}
+What are the status flags (Z, C, S, O, P) for the following operation in 8-bits: \(11 + 13\)?
+
+\section*{Solution}
+To determine the status flags for the 8-bit addition of \(11\) and \(13\), we first perform the addition and then evaluate each flag.
+
+1. Perform the addition:
+\[
+11_{10} = 00001011_2
+\]
+\[
+13_{10} = 00001101_2
+\]
+\[
+11 + 13 = 00001011_2 + 00001101_2 = 0\_00011000_2 = 24_{10}
+\]
+
+2. Evaluate the status flags:
+\begin{itemize}
+ \item \textbf{Zero flag (Z):} Set if the result is zero.
+ \[
+ \text{Z} = 0 \quad (\text{since } 24 \neq 0)
+ \]
+
+ \item \textbf{Carry flag (C):} Set if there is a carry out of the most significant bit.
+ \[
+ \text{C} = 0 \quad (\text{since there is no carry out of the most significant bit})
+ \]
+
+ \item \textbf{Sign flag (S):} Set if the most significant bit of the result is 1 (indicating a negative number in two's complement).
+ \[
+ \text{S} = 0 \quad (\text{since the most significant bit of 00011000 is 0})
+ \]
+
+ \item \textbf{Overflow flag (O):} Set if there is a signed overflow, which occurs when the sign of the result does not match the expected sign.
+ \[
+ \text{O} = 0 \quad (\text{since there is no signed overflow})
+ \]
+
+ \item \textbf{Parity flag (P):} Set if the number of set bits (1s) in the result is even.
+ \[
+ \text{P} = 1 \quad (\text{since the number of 1s in 00011000 is 2, which is even})
+ \]
+\end{itemize}
+
+Therefore, the status flags for the 8-bit addition of \(11 + 13\) are:
+\begin{itemize}
+ \item Zero flag (Z): 0
+ \item Carry flag (C): 0
+ \item Sign flag (S): 0
+ \item Overflow flag (O): 0
+ \item Parity flag (P): 1
+\end{itemize}
\ No newline at end of file
diff --git a/assignments/exam/hextobin/fetch.py b/assignments/exam/hextobin/fetch.py
new file mode 100644
index 00000000..af5ed204
--- /dev/null
+++ b/assignments/exam/hextobin/fetch.py
@@ -0,0 +1,30 @@
+import sys, json, random, datetime
+args = {param.split('=')[0]: param.split('=')[1] for param in sys.argv[1:]}
+student_id = args['id']
+# TODO: change for EXAM
+secret = 0
+week=datetime.datetime.now().isocalendar()[0]
+random.seed(secret + week + int(student_id))
+
+# define the problem
+# Generate a random number between 129 and 255
+number=random.randint(129, 255)
+# Convert the number to binary and hexadecimal
+nbs = '{:08b}'.format(number)
+nhs = '0x{:02x}'.format(number)
+
+# generate the question in html
+question = """
+
+
Convert the hexadecimal number {} in big endian format to 8-bit binary
+
+""".format(nhs)
+
+result = nbs
+
+print(
+ json.dumps({
+ "question": question,
+ "result": result
+ })
+)
\ No newline at end of file
diff --git a/assignments/exam/hextobin/sol.tex b/assignments/exam/hextobin/sol.tex
new file mode 100644
index 00000000..14a7c103
--- /dev/null
+++ b/assignments/exam/hextobin/sol.tex
@@ -0,0 +1,17 @@
+\subsection*{Problem}
+Given the following hexadecimal number \texttt{0x1A3F} in big endian format, convert it to 8-bit binary.
+
+\subsection*{Solution}
+To convert the hexadecimal number \texttt{0x1A3F} to binary, we convert each hexadecimal digit to its 4-bit binary equivalent:
+
+\begin{align*}
+1 & = 0001 \\
+A & = 1010 \\
+3 & = 0011 \\
+F & = 1111 \\
+\end{align*}
+
+Therefore, the binary representation of \texttt{0x1A3F} is:
+\[
+\texttt{0x1A3F} = 0001\ 1010\ 0011\ 1111
+\]
\ No newline at end of file
diff --git a/assignments/exam/hextodec/fetch.py b/assignments/exam/hextodec/fetch.py
new file mode 100644
index 00000000..6da89767
--- /dev/null
+++ b/assignments/exam/hextodec/fetch.py
@@ -0,0 +1,30 @@
+import sys, json, random, datetime
+args = {param.split('=')[0]: param.split('=')[1] for param in sys.argv[1:]}
+student_id = args['id']
+# TODO: change for EXAM
+secret = 0
+week=datetime.datetime.now().isocalendar()[0]
+random.seed(secret + week + int(student_id))
+
+# define the problem
+# Generate a random number between 129 and 255
+number=random.randint(129, 255)
+# Convert the number to binary and hexadecimal
+nbs = '{:08b}'.format(number)
+nhs = '0x{:02x}'.format(number)
+
+# generate the question in html
+question = """
+
+
Convert the hexadecimal number {} in big endian format to integer value (no sign)
+
+""".format(nhs)
+
+result = number
+
+print(
+ json.dumps({
+ "question": question,
+ "result": result
+ })
+)
\ No newline at end of file
diff --git a/assignments/exam/hextodec/sol.tex b/assignments/exam/hextodec/sol.tex
new file mode 100644
index 00000000..24fffa23
--- /dev/null
+++ b/assignments/exam/hextodec/sol.tex
@@ -0,0 +1,33 @@
+\subsection*{Problem}
+Given the following hexadecimal number \texttt{0x1A3F} in big endian format, convert it to decimal.
+
+\subsection*{Solution}
+To convert the hexadecimal number \texttt{0x1A3F} to decimal, we use the positional value of each digit. The hexadecimal number \texttt{0x1A3F} can be expanded as follows:
+
+\[
+0x1A3F = 1 \times 16^3 + A \times 16^2 + 3 \times 16^1 + F \times 16^0
+\]
+
+Where:
+\begin{align*}
+A & = 10 \\
+F & = 15 \\
+\end{align*}
+
+Now, calculate each term:
+\begin{align*}
+1 \times 16^3 & = 1 \times 4096 = 4096 \\
+10 \times 16^2 & = 10 \times 256 = 2560 \\
+3 \times 16^1 & = 3 \times 16 = 48 \\
+15 \times 16^0 & = 15 \times 1 = 15 \\
+\end{align*}
+
+Adding these values together gives:
+\[
+4096 + 2560 + 48 + 15 = 6719
+\]
+
+Therefore, the decimal representation of \texttt{0x1A3F} is:
+\[
+\texttt{0x1A3F} = 6719
+\]
\ No newline at end of file
diff --git a/assignments/exam/ieee754/fetch.py b/assignments/exam/ieee754/fetch.py
new file mode 100644
index 00000000..9558c559
--- /dev/null
+++ b/assignments/exam/ieee754/fetch.py
@@ -0,0 +1,27 @@
+import sys, json, random, datetime, struct
+args = {param.split('=')[0]: param.split('=')[1] for param in sys.argv[1:]}
+student_id = args['id']
+# TODO: change for EXAM
+secret = 0
+week=datetime.datetime.now().isocalendar()[0]
+random.seed(secret + week + int(student_id))
+
+# define the problem
+# Generate a random number between 129 and 255
+number=random.randint(129, 255)
+floating_point_number = float(number)
+nhs = ''.join(f'{c:02x}' for c in struct.pack('!f', floating_point_number))
+# generate the question in html
+question = """
+
+
Given the following hexadecimal string 0x{} in big endian format of an 32-bit IEEE754 floating-point, what is the value of it?
+
+""".format(nhs)
+result = floating_point_number
+
+print(
+ json.dumps({
+ "question": question,
+ "result": result
+ })
+)
\ No newline at end of file
diff --git a/assignments/exam/ieee754/sol.tex b/assignments/exam/ieee754/sol.tex
new file mode 100644
index 00000000..d1349e6c
--- /dev/null
+++ b/assignments/exam/ieee754/sol.tex
@@ -0,0 +1,48 @@
+\subsection*{Problem}
+
+Given the hexadecimal string \texttt{0x44490100}, what is the value of the number in the 32-bit IEEE 754 floating-point representation?
+
+\subsection*{Solution}
+
+To convert the hexadecimal string \texttt{0x44490100} to a 32-bit IEEE 754 floating-point number, we follow these steps:
+
+1. Convert the hexadecimal string to binary:
+\[
+\texttt{0x44490100} = 0100\ 0100\ 0100\ 1001\ 0000\ 0001\ 0000\ 0000
+\]
+
+2. Identify the sign bit, exponent, and mantissa:
+\begin{itemize}
+ \item Sign bit: 0 (positive number)
+ \item Exponent: 10001000 (in binary)
+ \item Mantissa: 10010010000000100000000 (in binary)
+\end{itemize}
+
+3. Convert the exponent from binary to decimal and apply the bias (127 for 32-bit IEEE 754):
+\[
+\text{Exponent} = 10001000_2 = 136_{10}
+\]
+\[
+\text{Unbiased Exponent} = 136 - 127 = 9
+\]
+
+4. Normalize the mantissa and add the implicit leading 1:
+\[
+\text{Mantissa} = 1.10010010000000100000000_2
+\]
+
+5. Calculate the value:
+\[
+\text{Value} = (-1)^{\text{sign}} \times 1.\text{mantissa} \times 2^{\text{exponent}}
+\]
+\[
+\text{Value} = (-1)^0 \times 1.10010010000000100000000_2 \times 2^9
+\]
+\[
+\text{Value} = 1 \times 1100100100.000001_2 = 804_{10} + 2^{-6} = 804.015625_{10}
+\]
+
+Therefore, the value of the hexadecimal string \texttt{0x44490100} in the 32-bit IEEE 754 floating-point representation is:
+\[
+ 804.015625
+\]
\ No newline at end of file
diff --git a/assignments/exam/instructionset/fetch.py b/assignments/exam/instructionset/fetch.py
new file mode 100644
index 00000000..6b27ba34
--- /dev/null
+++ b/assignments/exam/instructionset/fetch.py
@@ -0,0 +1,220 @@
+import sys, json, random, datetime
+args = {param.split('=')[0]: param.split('=')[1] for param in sys.argv[1:]}
+student_id = args['id']
+# TODO: change for EXAM
+secret = 0
+week=datetime.datetime.now().isocalendar()[0]
+random.seed(secret + week + int(student_id))
+
+# Define the 2D array based on the LaTeX table
+addressing_table = [
+ ["[BA+XA]", "[BA+XA+]", "[BA+XA+Imm]", "RA"],
+ ["[BA+XB]", "[BA+XB+]", "[BA+XB+Imm]", "RB"],
+ ["[BB+XA]", "[BB+XA+]", "[BB+XA+Imm]", "RC"],
+ ["[BB+XB]", "[BB+XB+]", "[BB+XB+Imm]", "SP"],
+ ["[XA]", "[BA+(-XA)]", "[XA+Imm]", "XA"],
+ ["[XB]", "[BB+(-XA)]", "[XB+Imm]", "XB"],
+ ["[BA]", "[Imm]", "[BA+Imm]", "BA"],
+ ["[BB]", "[[Imm]]", "[BB+Imm]", "BB"]
+]
+
+# Define the row and column labels
+rm_labels = ["000", "001", "010", "011", "100", "101", "110", "111"]
+mod_labels = ["00", "01", "10", "11"]
+
+# Generate the addressing table in html format
+addressing_table_html = """
+
+
+ MOD \ RM |
+"""
+for mod in mod_labels:
+ addressing_table_html += f"{mod} | "
+addressing_table_html += "
\n"
+for i, rm in enumerate(rm_labels):
+ addressing_table_html += f"{rm} | "
+ for j in range(len(mod_labels)):
+ addressing_table_html += f"{addressing_table[i][j]} | "
+ addressing_table_html += "
\n"
+addressing_table_html += "
"
+# print(addressing_table_html)
+
+opcode_table = {
+ "0000000" : "MOV",
+ "0001000" : "INC",
+ "0001001" : "DEC",
+ "0001010" : "NEG",
+ "0001011" : "NOT",
+ "0001100" : "SHL",
+ "0001101" : "SHR",
+ "0001110" : "SAR",
+ "0101000" : "ADD",
+ "0101001" : "ADC",
+ "0101010" : "SUB",
+ "0101011" : "SBB",
+ "0101100" : "AND",
+ "0101101" : "OR",
+ "0101110" : "XOR"
+}
+
+# Generate the opcode table in html format
+opcode_table_html = """
+
+
+ OPCODE | INSTRUCTION |
+"""
+for opcode in opcode_table:
+ opcode_table_html += f"{opcode} | {opcode_table[opcode]} |
\n"
+opcode_table_html += "
"
+# print(opcode_table_html)
+
+instruction_register_table = [
+ ["Instruction Register (IR)"],
+ ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"],
+ ["OPC", "OPC", "OPC", "OPC", "OPC", "OPC", "OPC", "d", "MOD", "MOD", "REG", "REG", "REG", "RM", "RM", "RM"]
+]
+# Generate the instruction register table in html format
+instruction_register_table_html = """
+
+
+ Instruction Register (IR) |
+
+"""
+for i in instruction_register_table[1]:
+ instruction_register_table_html += f"{i} | "
+instruction_register_table_html += "
\n"
+instruction_register_table_html += ""
+instruction_register_table_html += "OPC | "
+instruction_register_table_html += "d | "
+instruction_register_table_html += "MOD | "
+instruction_register_table_html += "REG | "
+instruction_register_table_html += "RM | "
+instruction_register_table_html += "
\n"
+instruction_register_table_html += "
"
+# print(instruction_register_table_html)
+
+register_table = {
+ "000" : "RA",
+ "001" : "RB",
+ "010" : "RC",
+ "011" : "SP",
+ "100" : "XA",
+ "101" : "XB",
+ "110" : "BA",
+ "111" : "BB"
+}
+# Generate the registers table in html format
+registers_table_html = """
+
+
+ REG | Name |
+"""
+for register in register_table:
+ registers_table_html += f"{register} | {register_table[register]} |
"
+registers_table_html += "
"
+# print(registers_table_html)
+
+# Generate the random test case
+
+# first opcode
+opcode = random.choice(list(opcode_table.keys()))
+
+# get the mod and rm values
+# mod can not be 10
+mod = random.choice(mod_labels)
+while mod == "10":
+ mod = random.choice(mod_labels)
+# if mod is 01 rm can not be 110 or 111
+rm = random.choice(rm_labels)
+while mod == "01" and rm in ["110", "111"]:
+ rm = random.choice(rm_labels)
+# test if it has one or two operands
+d = '0'
+reg = "000"
+instruction_text = opcode_table[opcode] + " "
+if opcode[1] == '0' and opcode[3] == '1':
+ instruction_text += addressing_table[int(rm, 2)][int(mod, 2)]
+else:
+ d = random.choice(["0", "1"])
+ reg = random.choice(list(register_table.keys()))
+ if d == "1":
+ instruction_text += register_table[reg] + ", " + addressing_table[int(rm, 2)][int(mod, 2)]
+ else:
+ instruction_text += addressing_table[int(rm, 2)][int(mod, 2)] + ", " + register_table[reg]
+
+# generate the instruction
+instruction_binary = opcode + d + mod + reg + rm
+instruction_hex = hex(int(instruction_binary, 2))
+
+# generate the question in html format
+question = """
+
+
Having the following memory addressing table, instruction format table, registers address table, and opcode table. What is the encoding of the following instuction {} in hexadecimal (starting with 0x) ?
+
+
Memory Addressing Table:
+ {}
+
+
+
Instruction Format Table:
+ {}
+
+
+
Registers Address Table:
+ {}
+
+
+
Opcode Table:
+ {}
+
+
+""".format(
+ instruction_text,
+ addressing_table_html,
+ instruction_register_table_html,
+ registers_table_html,
+ opcode_table_html
+)
+
+
+print(
+ json.dumps({
+ "question": question,
+ "result": instruction_hex
+ })
+)
\ No newline at end of file
diff --git a/assignments/exam/instructionset/main.tex b/assignments/exam/instructionset/main.tex
new file mode 100644
index 00000000..46787e48
--- /dev/null
+++ b/assignments/exam/instructionset/main.tex
@@ -0,0 +1,85 @@
+\documentclass{standalone}
+\usepackage{geometry}
+\usepackage{multirow}
+\usepackage{multicol}
+\usepackage{caption}
+
+% \begin{document}
+% \begin{minipage}[t][18cm][t]{\textwidth}
+% \begin{tabular}{|l|l||l|l|l|l|}
+% \hline
+% \multirow{2}{*}{\textbf{$IR_{1}$}} & \multirow{2}{*}{\textbf{$IR_{3}$}} & \multicolumn{2}{|l|}{$IR_{0}=0$} & \multicolumn{2}{|l|}{$IR_{0}=1$} \\ \cline{3-6}
+% & & $IR_{2}=0$ & $IR_{2}=1$ & \multicolumn{2}{|l|}{$IR_{2}=0$} \\ \hline \hline
+% \multirow{14}{*}{$0$} & \multirow{7}{*}{$0$} & $000=\text{MOV}$ & $000=\text{MOV}$ & $000=\text{IN}$ & \\ \cline{3-6}
+% & & $001=$ & $001=$ & $001=\text{OUT}$ & \\ \cline{3-6}
+% & & $010=\text{PUSH}$ & $010=$ & $010=\text{PUSHF}$ &\\ \cline{3-6}
+% & & $011=\text{POP}$ & $011=$ & $011=\text{POPF}$ & \\ \cline{3-6}
+% & & $100=\text{CALL}$ & $100=$ & $100=\text{RET}$ & \\ \cline{3-6}
+% & & $101=\text{JMP}$ & $101=$ & $101=\text{IRET}$ & \\ \cline{3-6}
+% & & $110=$ & $110=$ & $110=\text{HLT}$ & \\ \cline{3-6}
+% & & $111=$ & $111=$ & $111=$ & \\ \cline{2-6}
+% & \multirow{7}{*}{$1$} & $000=\text{INC}$ & $000=$ & $0000=\text{JBE}$ & $1000=\text{JBA}$ \\ \cline{3-6}
+% & & $001=\text{DEC}$ & $001=$ & $0001=\text{JB/JC}$ & $1001=\text{JAE/JNC}$ \\ \cline{3-6}
+% & & $010=\text{NEG}$ & $010=$ & $0010=\text{JLE}$ & $1010=\text{JG}$ \\ \cline{3-6}
+% & & $011=\text{NOT}$ & $011=$ & $0011=\text{JL}$ & $1011=\text{JGE}$ \\ \cline{3-6}
+% & & $100=\text{SHL/SAL}$ & $100=$ & $0100=\text{JE/JZ}$ & $1100=\text{JNE/JNZ}$ \\ \cline{3-6}
+% & & $101=\text{SHR}$ & $101=$ & $0101=\text{JO}$ & $1101=\text{JNO}$ \\ \cline{3-6}
+% & & $110=\text{SAR}$ & $110=$ & $0110=\text{JS}$ & $1110=\text{JNS}$ \\ \cline{3-6}
+% & & $111=$ & $111=$ & $0111=\text{JPE}$ & $1111=\text{JPO}$ \\ \hline
+% \multirow{14}{*}{$1$} & \multirow{7}{*}{$0$} & $000=$ & $000=$ & & \\ \cline{3-6}
+% & & $001=$ & $001=$ & & \\ \cline{3-6}
+% & & $010=\text{CMP}$ & $010=\text{CMP}$ & &\\ \cline{3-6}
+% & & $011=$ & $011=$ & & \\ \cline{3-6}
+% & & $100=\text{TEST}$ & $100=\text{TEST}$ & & \\ \cline{3-6}
+% & & $101=$ & $101=$ & & \\ \cline{3-6}
+% & & $110=$ & $110=$ & & \\ \cline{3-6}
+% & & $111=$ & $111=$ & & \\ \cline{2-6}
+% & \multirow{7}{*}{$1$} & $000=\text{ADD}$ & $000=\text{ADD}$ & & \\ \cline{3-6}
+% & & $001=\text{ADC}$ & $001=\text{ADC}$ & & \\ \cline{3-6}
+% & & $010=\text{SUB}$ & $010=\text{SUB}$ & & \\ \cline{3-6}
+% & & $011=\text{SBB}$ & $011=\text{SBB}$ & & \\ \cline{3-6}
+% & & $100=\text{AND}$ & $100=\text{AND}$ & & \\ \cline{3-6}
+% & & $101=\text{OR}$ & $101=\text{OR}$ & & \\ \cline{3-6}
+% & & $110=\text{XOR}$ & $110=\text{XOR}$ & & \\ \cline{3-6}
+% & & $111=$ & $111=$ & & \\ \hline
+% \end{tabular}
+
+% \end{minipage}
+% \end{document}
+
+% \begin{document}
+% \begin{minipage}[t][6cm][t]{1\textwidth}
+% \begin{tabular}{|l||l|l|l|l|}
+% \hline
+% \multirow{2}{*}{$RM=IR_{13:15}$} & \multicolumn{4}{|l|}{$MOD=IR_{8:9}$} \\ \cline{2-5}
+% & $00$ & $01$ & $10$ & $11$ \\ \hline \hline
+% $000$ & $[BA+XA]$ & $[BA+XA+]$ & $[BA+XA+\text{Imm}]$ & $RA$ \\ \hline
+% $001$ & $[BA+XB]$ & $[BA+XB+]$ & $[BA+XB+\text{Imm}]$ & $RB$ \\ \hline
+% $010$ & $[BB+XA]$ & $[BB+XA+]$ & $[BB+XA+\text{Imm}]$ & $RC$ \\ \hline
+% $011$ & $[BB+XB]$ & $[BB+XB+]$ & $[BB+XB+\text{Imm}]$ & $SP$ \\ \hline
+% $100$ & $[XA]$ & $[BA+(-XA)]$ & $[XA+\text{Imm}]$ & $XA$ \\ \hline
+% $101$ & $[XB]$ & $[BB+(-XA)]$ & $[XB+\text{Imm}]$ & $XB$ \\ \hline
+% $110$ & $[BA]$ & $[\text{Imm}]$ & $[BA+\text{Imm}]$ & $BA$ \\ \hline
+% $111$ & $[BB]$ & $[[\text{Imm}]]$ & $[BB+\text{Imm}]$ & $BB$ \\ \hline \hline
+
+% \end{tabular}
+
+% \end{minipage}
+% \end{document}
+
+\begin{document}
+\begin{minipage}[t][6cm][t]{0.4\textwidth}
+ \begin{tabular}{|c|c|}
+ \hline
+ \textbf{Opcode} & \textbf{Register} \\ \hline
+ 000 & RA \\ \hline
+ 001 & RB \\ \hline
+ 010 & RC \\ \hline
+ 011 & SP \\ \hline
+ 100 & XA \\ \hline
+ 101 & XB \\ \hline
+ 110 & BA \\ \hline
+ 111 & BB \\ \hline
+ \end{tabular}
+\end{minipage}
+\end{document}
\ No newline at end of file
diff --git a/assignments/exam/instructionset/sol.tex b/assignments/exam/instructionset/sol.tex
new file mode 100644
index 00000000..852b45ed
--- /dev/null
+++ b/assignments/exam/instructionset/sol.tex
@@ -0,0 +1,111 @@
+\section*{Problem}
+
+Having the memory addressing table and instruction format tables, what is the instruction encoding in hexadecimal for the
+\texttt{MOV RA, [BA+XA+]} operation?
+
+\begin{table}[H]
+ \resizebox{\textwidth}{!}{%
+ \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|}
+ \hline
+ \multicolumn{16}{|c|}{Instruction Register (IR)} \\ \hline
+ \textbf{0} & \textbf{1} & \textbf{2} & \textbf{3} & \textbf{4} & \textbf{5} & \textbf{6} & \textbf{7} & \textbf{8} & \textbf{9} & \textbf{10} & \textbf{11} & \textbf{12} & \textbf{13} & \textbf{14} & \textbf{15} \\ \hline
+ \multicolumn{7}{|c|}{OPC} & d & \multicolumn{2}{|c|}{MOD} & \multicolumn{3}{|c|}{REG} & \multicolumn{3}{|c|}{RM} \\ \hline
+ \multicolumn{16}{|c|}{immediate/data} \\ \hline
+ \multicolumn{16}{|c|}{data} \\ \hline
+ \end{tabular}
+ }
+\end{table}
+
+\begin{table}[H]
+ \resizebox{\textwidth}{!}{%
+ \begin{tabular}{|l|l||l|l|l|l|}
+ \hline
+ \multirow{2}{*}{\textbf{$IR_{1}$}} & \multirow{2}{*}{\textbf{$IR_{3}$}} & \multicolumn{2}{|l|}{$IR_{0}=0$} & \multicolumn{2}{|l|}{$IR_{0}=1$} \\ \cline{3-6}
+ & & $IR_{2}=0$ & $IR_{2}=1$ & \multicolumn{2}{|l|}{$IR_{2}=0$} \\ \hline \hline
+ \multirow{14}{*}{$0$} & \multirow{7}{*}{$0$} & $000=\text{MOV}$ & $000=\text{MOV}$ & $000=\text{IN}$ & \\ \cline{3-6}
+ & & $001=$ & $001=$ & $001=\text{OUT}$ & \\ \cline{3-6}
+ & & $010=\text{PUSH}$ & $010=$ & $010=\text{PUSHF}$ &\\ \cline{3-6}
+ & & $011=\text{POP}$ & $011=$ & $011=\text{POPF}$ & \\ \cline{3-6}
+ & & $100=\text{CALL}$ & $100=$ & $100=\text{RET}$ & \\ \cline{3-6}
+ & & $101=\text{JMP}$ & $101=$ & $101=\text{IRET}$ & \\ \cline{3-6}
+ & & $110=$ & $110=$ & $110=\text{HLT}$ & \\ \cline{3-6}
+ & & $111=$ & $111=$ & $111=$ & \\ \cline{2-6}
+ & \multirow{7}{*}{$1$} & $000=\text{INC}$ & $000=$ & $0000=\text{JBE}$ & $1000=\text{JBA}$ \\ \cline{3-6}
+ & & $001=\text{DEC}$ & $001=$ & $0001=\text{JB/JC}$ & $1001=\text{JAE/JNC}$ \\ \cline{3-6}
+ & & $010=\text{NEG}$ & $010=$ & $0010=\text{JLE}$ & $1010=\text{JG}$ \\ \cline{3-6}
+ & & $011=\text{NOT}$ & $011=$ & $0011=\text{JL}$ & $1011=\text{JGE}$ \\ \cline{3-6}
+ & & $100=\text{SHL/SAL}$ & $100=$ & $0100=\text{JE/JZ}$ & $1100=\text{JNE/JNZ}$ \\ \cline{3-6}
+ & & $101=\text{SHR}$ & $101=$ & $0101=\text{JO}$ & $1101=\text{JNO}$ \\ \cline{3-6}
+ & & $110=\text{SAR}$ & $110=$ & $0110=\text{JS}$ & $1110=\text{JNS}$ \\ \cline{3-6}
+ & & $111=$ & $111=$ & $0111=\text{JPE}$ & $1111=\text{JPO}$ \\ \hline
+ \multirow{14}{*}{$1$} & \multirow{7}{*}{$0$} & $000=$ & $000=$ & & \\ \cline{3-6}
+ & & $001=$ & $001=$ & & \\ \cline{3-6}
+ & & $010=\text{CMP}$ & $010=\text{CMP}$ & &\\ \cline{3-6}
+ & & $011=$ & $011=$ & & \\ \cline{3-6}
+ & & $100=\text{TEST}$ & $100=\text{TEST}$ & & \\ \cline{3-6}
+ & & $101=$ & $101=$ & & \\ \cline{3-6}
+ & & $110=$ & $110=$ & & \\ \cline{3-6}
+ & & $111=$ & $111=$ & & \\ \cline{2-6}
+ & \multirow{7}{*}{$1$} & $000=\text{ADD}$ & $000=\text{ADD}$ & & \\ \cline{3-6}
+ & & $001=\text{ADC}$ & $001=\text{ADC}$ & & \\ \cline{3-6}
+ & & $010=\text{SUB}$ & $010=\text{SUB}$ & & \\ \cline{3-6}
+ & & $011=\text{SBB}$ & $011=\text{SBB}$ & & \\ \cline{3-6}
+ & & $100=\text{AND}$ & $100=\text{AND}$ & & \\ \cline{3-6}
+ & & $101=\text{OR}$ & $101=\text{OR}$ & & \\ \cline{3-6}
+ & & $110=\text{XOR}$ & $110=\text{XOR}$ & & \\ \cline{3-6}
+ & & $111=$ & $111=$ & & \\ \hline
+ \end{tabular}
+ }
+\end{table}
+
+\begin{table}[H]
+ \resizebox{\textwidth}{!}{%
+ \begin{tabular}{|l||l|l|l|l|}
+ \hline
+ \multirow{2}{*}{$RM=IR_{13:15}$} & \multicolumn{4}{|l|}{$MOD=IR_{8:9}$} \\ \cline{2-5}
+ & $00$ & $01$ & $10$ & $11$ \\ \hline \hline
+ $000$ & $[BA+XA]$ & $[BA+XA+]$ & $[BA+XA+\text{Imm}]$ & $RA$ \\ \hline
+ $001$ & $[BA+XB]$ & $[BA+XB+]$ & $[BA+XB+\text{Imm}]$ & $RB$ \\ \hline
+ $010$ & $[BB+XA]$ & $[BB+XA+]$ & $[BB+XA+\text{Imm}]$ & $RC$ \\ \hline
+ $011$ & $[BB+XB]$ & $[BB+XB+]$ & $[BB+XB+\text{Imm}]$ & $SP$ \\ \hline
+ $100$ & $[XA]$ & $[BA+(-XA)]$ & $[XA+\text{Imm}]$ & $XA$ \\ \hline
+ $101$ & $[XB]$ & $[BB+(-XA)]$ & $[XB+\text{Imm}]$ & $XB$ \\ \hline
+ $110$ & $[BA]$ & $[\text{Imm}]$ & $[BA+\text{Imm}]$ & $BA$ \\ \hline
+ $111$ & $[BB]$ & $[[\text{Imm}]]$ & $[BB+\text{Imm}]$ & $BB$ \\ \hline \hline
+
+ \end{tabular}
+ }
+\end{table}
+
+
+\section*{Solution}
+
+\begin{itemize}
+ \item \textbf{Instruction}: \texttt{MOV}
+ \item \textbf{Source}: \texttt{[BA+XA+]}
+ \item \textbf{Destination}: \texttt{RA}
+\end{itemize}
+
+\textbf{Identify the opcode for \texttt{MOV} from the instruction format table}.:
+\begin{itemize}
+ \item \texttt{MOV} is encoded as \texttt{000} when $IR_{1}=0$, $IR_{3}=0$, and $IR_{0}=0$.
+ \item We don't have immediate value so $IR_{2}=0$.
+ \item Destination register is \texttt{RA} so $d$ is \texttt{1} and $REG$ is \texttt{000}.
+\end{itemize}
+
+\textbf{Determine the addressing mode for \texttt{[BA+XA+]} from the memory addressing table}:
+\begin{itemize}
+ \item $RM=IR_{13:15}=000$.
+ \item $MOD=IR_{8:9}=01$.
+\end{itemize}
+
+\textbf{Final encoding:}
+\begin{itemize}
+ \item \textbf{OPC}: \texttt{0000\_000}
+ \item \textbf{d}: \texttt{1}
+ \item \textbf{MOD}: \texttt{01}
+ \item \textbf{REG}: \texttt{000}
+ \item \textbf{RM}: \texttt{000}
+\end{itemize}
+
+Therefore, the instruction coding for the \texttt{MOV RA, [BA+XA+]} operation is \texttt{0000 0001 0100 0000} in binary and \texttt{0x0140} in hexadecimal.
\ No newline at end of file
diff --git a/assignments/exam/interrupts/fetch.py b/assignments/exam/interrupts/fetch.py
new file mode 100644
index 00000000..6860f36d
--- /dev/null
+++ b/assignments/exam/interrupts/fetch.py
@@ -0,0 +1,197 @@
+import sys, json, random, datetime
+args = {param.split('=')[0]: param.split('=')[1] for param in sys.argv[1:]}
+student_id = args['id']
+# TODO: change for EXAM
+secret = 0
+week=datetime.datetime.now().isocalendar()[0]
+random.seed(secret + week + int(student_id))
+# Define the problem
+interrupts_table = [
+ {"address": "0x0", "name": "Reserved", "type": "Internal Interrupt"},
+ {"address": "0x1", "name": "Software Interrupt (INT)", "type": "Internal Interrupt"},
+ {"address": "0x2", "name": "ALU Overflow", "type": "Internal Interrupt"},
+ {"address": "0x3", "name": "Lack of Voltage (Power Off)", "type": "External Non-Maskable Interrupt"},
+ {"address": "0x4", "name": "Level 0", "type": "External Maskable Interrupt"},
+ {"address": "0x5", "name": "Level 1", "type": "External Maskable Interrupt"},
+ {"address": "0x6", "name": "Level 2", "type": "External Maskable Interrupt"},
+ {"address": "0x7", "name": "Level 3", "type": "External Maskable Interrupt"},
+ {"address": "0x8", "name": "Level 4", "type": "External Maskable Interrupt"},
+ {"address": "0x9", "name": "Level 5", "type": "External Maskable Interrupt"},
+ {"address": "0xA", "name": "Level 6", "type": "External Maskable Interrupt"},
+ {"address": "0xB", "name": "Level 7", "type": "External Maskable Interrupt"}
+]
+
+# make the table into a html table
+interrupts_table_html = """
+
+
+ Address | Name | Type |
+"""
+for interrupt in interrupts_table:
+ interrupts_table_html += f"{interrupt['address']} | {interrupt['name']} | {interrupt['type']} |
"
+interrupts_table_html += "
"
+# print(interrupts_table_html)
+
+external_maskable_interrupts_times = [10, 20, 30, 40, 50, 60, 70, 80]
+
+time_to_handle = {
+ "External Maskable Interrupt Level 0": random.choice(external_maskable_interrupts_times),
+ "External Maskable Interrupt Level 1": random.choice(external_maskable_interrupts_times),
+ "External Maskable Interrupt Level 2": random.choice(external_maskable_interrupts_times),
+ "External Maskable Interrupt Level 3": random.choice(external_maskable_interrupts_times),
+ "External Maskable Interrupt Level 4": random.choice(external_maskable_interrupts_times),
+ "External Maskable Interrupt Level 5": random.choice(external_maskable_interrupts_times),
+ "External Maskable Interrupt Level 6": random.choice(external_maskable_interrupts_times),
+ "External Maskable Interrupt Level 7": random.choice(external_maskable_interrupts_times),
+ "External Non-Maskable Interrupt": random.choice([5, 10, 15, 20]),
+ "ALU Overflow": random.choice([10, 15, 20]),
+ "Software Interrupt": random.choice([15, 20, 25, 30])
+}
+
+# make the time to handle into a html table
+time_to_handle_html = """
+
+
+ Type | Time to Handle |
+"""
+for interrupt_type in time_to_handle:
+ time_to_handle_html += f"{interrupt_type} | {time_to_handle[interrupt_type]} |
"
+time_to_handle_html += "
"
+# print(time_to_handle_html)
+
+times_beetwen_interrupts = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
+
+index = 0
+interrupt_requests = []
+interrupt_requests.append({"cycle": 10, "type": random.choice(list(time_to_handle.keys())), "name": "INT" + str(index)})
+for index in range(1, 7):
+ cycle = interrupt_requests[index-1]["cycle"] + random.choice(times_beetwen_interrupts)
+ interrupt_type = random.choice(list(time_to_handle.keys()))
+ interrupt_name = "INT" + str(index)
+ interrupt_requests.append({"cycle": cycle, "type": interrupt_type, "name": interrupt_name})
+
+# make the interrupt requests into a html table
+interrupt_requests_html = """
+
+
+ Start Cycle | Type | Name |
+"""
+for request in interrupt_requests:
+ interrupt_requests_html += f"{request['cycle']} | {request['type']} | {request['name']} |
"
+interrupt_requests_html += "
"
+# print(interrupt_requests_html)
+
+
+
+priority_of_intq = {
+ "External Maskable Interrupt Level 0": 4,
+ "External Maskable Interrupt Level 1": 5,
+ "External Maskable Interrupt Level 2": 6,
+ "External Maskable Interrupt Level 3": 7,
+ "External Maskable Interrupt Level 4": 8,
+ "External Maskable Interrupt Level 5": 9,
+ "External Maskable Interrupt Level 6": 10,
+ "External Maskable Interrupt Level 7": 11,
+ "External Non-Maskable Interrupt": 3,
+ "ALU Overflow": 2,
+ "Software Interrupt": 1
+}
+
+def solve_interrupts(interrupt_requests):
+ handled_interrupts = []
+ current_cycle = 0
+ active_interrupts = []
+ remaining_interrupts = []
+
+ for request in interrupt_requests:
+ remaining_interrupts.append(request)
+
+ while len(remaining_interrupts) > 0 or len(active_interrupts) > 0:
+ if len(active_interrupts) > 0:
+ active_interrupt = active_interrupts.pop(0)
+ active_interrupt["remaining_cycles"] -= 1
+ if active_interrupt["remaining_cycles"] == 0:
+ handled_interrupts.append(active_interrupt["name"])
+ else:
+ active_interrupts.insert(0, active_interrupt)
+ current_cycle += 1
+ for request in remaining_interrupts:
+ if request["cycle"] == current_cycle:
+ active_interrupts.append({
+ "name": request["name"],
+ "type": request["type"],
+ "remaining_cycles": time_to_handle[request["type"]]
+ })
+ remaining_interrupts.remove(request)
+ active_interrupts.sort(key=lambda x: priority_of_intq[x["type"]])
+
+ return handled_interrupts
+
+# Get the order of handled interrupts
+handled_interrupts = solve_interrupts(interrupt_requests)
+
+# chose a random order of the handled interupts larger than 3
+index_of_interrupts = random.randint(4, len(handled_interrupts))
+
+# generate the question in html format
+question = """
+
+
+ Having the table of interrupt requests, interrupt types, and the time of the request,
+ what is {}th interupt that will be handled completly by the CPU?
+
+
+
+
Interrupts Table:
+ {}
+
+
+
Time to handle Interrupts Table:
+ {}
+
+
+
Interrupts to handle Table:
+ {}
+
+""".format(
+ index_of_interrupts,
+ interrupts_table_html,
+ time_to_handle_html,
+ interrupt_requests_html
+)
+
+print(
+ json.dumps(
+ {
+ "question": question,
+ "result": handled_interrupts[index_of_interrupts - 1]
+ }
+ )
+)
diff --git a/assignments/exam/interrupts/run.py b/assignments/exam/interrupts/run.py
new file mode 100644
index 00000000..6b571d69
--- /dev/null
+++ b/assignments/exam/interrupts/run.py
@@ -0,0 +1,24 @@
+import re
+
+student_text = """{{ STUDENT_ANSWER }}"""
+question_answer = """{{ result }}"""
+precheck = {{ IS_PRECHECK }}
+
+SEPARATOR = "##"
+
+regex = r"^INT[0-7]$"
+
+{% for TEST in TESTCASES %}
+if not re.match(regex, student_text):
+ print("A valid input is INT0, INT1, INT2, INT3, INT4, INT5, INT6, or INT7")
+else:
+ if precheck != 1:
+ if student_text.upper() == question_answer.upper():
+ print('correct')
+ else:
+ print('incorrect')
+# {{ TEST.testcode }}
+{% if not loop.last %}
+print(SEPARATOR)
+{% endif %}
+{% endfor %}
\ No newline at end of file
diff --git a/assignments/exam/interrupts/sol.tex b/assignments/exam/interrupts/sol.tex
new file mode 100644
index 00000000..de6b5762
--- /dev/null
+++ b/assignments/exam/interrupts/sol.tex
@@ -0,0 +1,131 @@
+\subsection*{Problem}
+Having the table of interrupt requests, interrupt types, and the time of the request, what is
+the Xth interupt that will be handled completly by the CPU?
+
+\begin{table}[H]
+ \centering
+ \begin{tabular}{|c|c|c|}
+ \hline
+ \textbf{Address} & \textbf{Name} & \textbf{Type} \\ \hline
+ 0x0 & Reserved & \multirow{3}{*}{Internal Interrupt} \\ \cline{1-2}
+ 0x1 & Software Interrupt (INT) & \\ \cline{1-2}
+ 0x2 & ALU Overflow & \\ \hline
+ 0x3 & Lack of Voltage (Power Off) & External Non-Maskable Interrupt \\ \hline
+ 0x4 & Level 0 & \multirow{8}{*}{External Maskable Interrupt} \\ \cline{1-2}
+ 0x5 & Level 1 & \\ \cline{1-2}
+ 0x6 & Level 2 & \\ \cline{1-2}
+ 0x7 & Level 3 & \\ \cline{1-2}
+ 0x8 & Level 4 & \\ \cline{1-2}
+ 0x9 & Level 5 & \\ \cline{1-2}
+ 0xA & Level 6 & \\ \cline{1-2}
+ 0xB & Level 7 & \\ \hline
+ \end{tabular}
+ \caption{Interrupts Table}
+\end{table}
+
+\begin{table}[H]
+ \centering
+ \begin{tabular}{|c|c|c|c|}
+ \hline
+ \texttt{REQINT} & \texttt{MEXTINT} & \texttt{RUNINT} & \texttt{FR} \\ \hline
+ 0x00 & 0x00 & 0x00 & Has I flag enable \\ \hline
+ \end{tabular}
+ \caption{Registers values at time 0}
+\end{table}
+
+\begin{table}[H]
+ \centering
+ \begin{tabular}{|c|c|c|c|}
+ \hline
+ Type of Request & Cycle to handle \\ \hline
+ External Maskable Interupt Level 0 & 30 \\ \hline
+ External Maskable Interupt Level 1 & 20 \\ \hline
+ External Maskable Interupt Level 2 & 10 \\ \hline
+ External Maskable Interupt Level 3 & 40 \\ \hline
+ External Maskable Interupt Level 4 & 20 \\ \hline
+ External Maskable Interupt Level 5 & 30 \\ \hline
+ External Maskable Interupt Level 6 & 10 \\ \hline
+ External Maskable Interupt Level 7 & 20 \\ \hline
+ External Non-Maskable Interupt & 5 \\ \hline
+ ALU Overflow & 10 \\ \hline
+ Software Interupt & 10 \\ \hline
+ \end{tabular}
+ \caption{Time to handle each type of interrupt}
+\end{table}
+
+
+\begin{table}[H]
+ \centering
+ \begin{tabular}{|c|c|c|c|}
+ \hline
+ Cycles from time 0 & Type of Request & Name \\ \hline
+ 10 & External Maskable Interupt Level 5 & A \\ \hline
+ 30 & External Maskable Interupt Level 3 & B \\ \hline
+ 50 & External Maskable Interupt Level 7 & C \\ \hline
+ 60 & External Maskable Interupt Level 1 & D \\ \hline
+ 100 & External Non-Maskable Interupt & E \\ \hline
+ 140 & ALU Overflow & F \\ \hline
+ 150 & Software Interupt & G \\ \hline
+ \end{tabular}
+ \caption{Time of the request for each type of interrupt}
+\end{table}
+
+\subsection*{Solution}
+
+Considering interupts enable for all external maskable interrupts, the order of interrupts that will be handled by the CPU is:
+
+At Cycle 10: There is not active interupt at this time. It starts the External Maskable Interupt Level 5 called A.
+
+At Cycle 30: The External Maskable Interupt Level 5 called A is still active (20/30 cycles passed).
+The External Maskable Interupt Level 3 called B has higher priority and will be handled.
+
+At Cycle 50: The External Maskable Interupt Level 3 called B is still active (20/40 cycles passed).
+The External Maskable Interupt Level 7 called C has lower priority and it will be queued.
+
+At Cycle 60: The External Maskable Interupt Level 3 called B is still active (30/40 cycles passed).
+The External Maskable Interupt Level 1 called D has higher priority and will be handled.
+
+At Cycle 80: The External Maskable Interupt Level 1 called D has finished (20/20 cycles passed).
+The External Maskable Interupt Level 3 called B returns to be active (30/40 cycles passed).
+
+At Cycle 90: The External Maskable Interupt Level 3 called B has finished (40/40 cycles passed).
+The External Maskable Interupt Level 5 called A returns to be active (20/30 cycles passed).
+
+At Cycle 100: The External Maskable Interupt Level 5 called A has finished (30/30 cycles passed).
+The External Non-Maskable Interupt called E has higher priority than the External Maskable Interupt Level 7 called C.
+
+At Cycle 105: The External Non-Maskable Interupt called E has finished (5/5 cycles passed).
+THe External Maskable Interupt Level 7 called C will be handled (0/20 cycles passed).
+
+At Cycle 125: The External Maskable Interupt Level 7 called C has finished (20/20 cycles passed).
+
+At Cycle 140: The ALU Overflow called F will be handled.
+
+At Cycle 150: The ALU Overflow called F has finished (10/10 cycles passed).
+The Software Interupt called G will be handled.
+
+At Cycle 160: The Software Interupt called G has finished (10/10 cycles passed).
+
+The order of interrupts that will be handled by the CPU is: D, B, A, E, C, F, G.
+
+If X is 3 then the Xth interrupt that will be handled completly by the CPU is A.
+
+\begin{table}
+ \centering
+ \begin{tabular}{|c||c|c|c|c|c|c|c|}
+ \hline
+ \textbf{Cycle} & A & B & C & D & E & F & G \\ \hline
+ 10 & A & & & & & & \\ \hline
+ 30 & P1 & A & & & & & \\ \hline
+ 50 & P1 & A & Q1 & & & & \\ \hline
+ 60 & P2 & P1 & Q1 & A & & & \\ \hline
+ 80 & P1 & A & Q1 & F & & & \\ \hline
+ 90 & A & F & Q1 & F & & & \\ \hline
+ 100 & F & F & Q1 & F & A & & \\ \hline
+ 105 & F & F & A & F & F & & \\ \hline
+ 125 & F & F & F & F & F & & \\ \hline
+ 140 & F & F & F & F & F & A & \\ \hline
+ 150 & F & F & F & F & F & F & A \\ \hline
+ 160 & F & F & F & F & F & F & F \\ \hline
+ \end{tabular}
+\end{table}
\ No newline at end of file
diff --git a/assignments/exam/io/fetch.py b/assignments/exam/io/fetch.py
new file mode 100644
index 00000000..eb21dd92
--- /dev/null
+++ b/assignments/exam/io/fetch.py
@@ -0,0 +1,196 @@
+import sys, json, random, datetime
+args = {param.split('=')[0]: param.split('=')[1] for param in sys.argv[1:]}
+student_id = args['id']
+# TODO: change for EXAM
+secret = 0
+week=datetime.datetime.now().isocalendar()[0]
+random.seed(secret + week + int(student_id))
+
+io_registers = {
+ "SCDMA" : "0x0192",
+ "MADMA" : random.randint(1000, 3000),
+ "CNTDMA" : random.randint(2, 8),
+ "INITDMA" : "0x0001",
+ "SCIO0" : "0x0000",
+ "SCIO1" : "0x0000",
+ "SCIO2" : "0x0000",
+ "SCIO3" : "0x0000"
+}
+MADMA = io_registers["MADMA"]
+CNTDMA = io_registers["CNTDMA"]
+io_registers["MADMA"] = f"0x{MADMA:04X}"
+io_registers["CNTDMA"] = f"0x{CNTDMA:04X}"
+
+# transform the io registers in a html table
+io_registers_table = """
+
+
+ Register | Value |
+"""
+for register in io_registers:
+ io_registers_table += f"{register} | {io_registers[register]} |
"
+io_registers_table += "
"
+# print(io_registers_table)
+
+main_memory = {}
+for i in range(10):
+ main_memory[f"0x{(MADMA+i):04X}"] = random.randint(0, 255)
+
+# transform the main memory in a html table
+main_memory_table = """
+
+
+ Address | Value |
+"""
+for address in main_memory:
+ main_memory_table += "0x{} | 0x{} |
".format(address, '{:04x}'.format(main_memory[address]))
+main_memory_table += "
"
+# print(main_memory_table)
+
+result = main_memory[f"0x{MADMA+CNTDMA:04X}"]
+
+# generate the question in html format
+question = """
+
+
Having the following I/O registers table and main memory table. What is the value on the data bus?
+
Write the result in hexadecimal (starting with 0x)
+
+
IO Registers
+ {}
+
+
+
Main Memopry
+ {}
+
+""".format(io_registers_table, main_memory_table)
+
+question += """
+
+
SCDMA Register
+
+
+ 0 |
+ 1 |
+ 2 |
+ 3 |
+ 4 |
+ 5 |
+ 6 |
+ 7 |
+ 8 |
+ 9 |
+ 10 |
+ 11 |
+ 12 |
+ 13 |
+ 14 |
+ 15 |
+
+
+ SIO_0 |
+ SIO_1 |
+ SIO_2 |
+ SIO_3 |
+ X |
+ X |
+ SDMA |
+ EOBT |
+ EXTIRQ |
+ X |
+ PIRQ |
+ ENIRQ |
+ X |
+ MT |
+ DT |
+ ENT |
+
+
+
+
+ - SIO_0-3 - Status of the I/O devices 0 - functional 1 - not functional
+ - SDMA - DMA is active for 0 - inactive for 1
+ - EOBT - End of block transfer for 0 - not for 1
+ - EXTIRQ - There is an external interrupt from IO device for 0 - not for 1
+ - PIRQ - There is a programmable interrupt from CPU for 0 - not for 1 (testing)
+ - ENIRQ - Enable interrupt for 0 - disable for 1
+ - MT - Mode of transfer 0 - block for 1 - cycle stealing
+ - DT - Direction of transfer 0 - from IO to memory to IO for 1 - from memory to IO
+ - ENT - Enable transfer for 0 - disable for 1
+
+
+
+
+
SCIOX Register
+
+
+ 0 |
+ 1 |
+ 2 |
+ 3 |
+ 4 |
+ 5 |
+ 6 |
+ 7 |
+ 8 |
+ 9 |
+ 10 |
+ 11 |
+ 12 |
+ 13 |
+ 14 |
+ 15 |
+
+
+ S |
+ C |
+ X |
+ X |
+ X |
+ X |
+ X |
+ X |
+ X |
+ X |
+ X |
+ ENIRQ |
+ X |
+ X |
+ DT |
+ X |
+
+
+
+
+ - S - Status of the IO device 0 - functional 1 - not functional
+ - C - Start transfer for 1 - stop for 0
+ - ENIRQ - Enable interrupt for 0 - disable for 1
+ - DT - Direction of transfer 0 - from IO to memory to IO for 1 - from memory to IO
+
+
+
+"""
+
+print(
+ json.dumps({
+ "question": question,
+ "result": f"0x{result:04X}"
+ })
+)
\ No newline at end of file
diff --git a/assignments/exam/io/sol.tex b/assignments/exam/io/sol.tex
new file mode 100644
index 00000000..5a8375a6
--- /dev/null
+++ b/assignments/exam/io/sol.tex
@@ -0,0 +1,105 @@
+
+
+\subsection*{Problem}
+Having the following IO registers value, main memory address
+and data, what is the value you can find on the databus?
+
+\begin{table}[H]
+ \centering
+ \begin{tabular}{|l|l|}
+ \hline
+ \textbf{Register} & \textbf{Value} \\ \hline
+ SCDMA & 0x0192 \\ \hline
+ MADMA & 0x5678 \\ \hline
+ CNTDMA & 0x0005 \\ \hline
+ INITDMA & 0x0001 \\ \hline
+ SCIO0 & 0x0000 \\ \hline
+ SCIO1 & 0x0000 \\ \hline
+ SCIO2 & 0x0000 \\ \hline
+ SCIO3 & 0x0000 \\ \hline
+ \end{tabular}
+ \begin{tabular}{|l|l|}
+ \hline
+ \textbf{Memory Address} & \textbf{Data} \\ \hline
+ 0x5678 & 0x0000 \\ \hline
+ 0x5679 & 0x0001 \\ \hline
+ 0x567a & 0x0002 \\ \hline
+ 0x567b & 0x0003 \\ \hline
+ 0x567c & 0x0004 \\ \hline
+ 0x567d & 0x0005 \\ \hline
+ 0x567e & 0x0006 \\ \hline
+ 0x567f & 0x0007 \\ \hline
+ \end{tabular}
+\end{table}
+
+\begin{table}[H]
+ \resizebox{\textwidth}{!}{%
+ \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|}
+ \hline
+ \textbf{0} & \textbf{1} & \textbf{2} & \textbf{3} & \textbf{4} & \textbf{5} & \textbf{6} & \textbf{7} & \textbf{8} & \textbf{9} & \textbf{10} & \textbf{11} & \textbf{12} & \textbf{13} & \textbf{14} & \textbf{15} \\ \hline
+ $SIO_{0}$ & $SIO_{1}$ & $SIO_{2}$ & $SIO_{3}$ & X & X & SDMA & EOBT & EXTIRQ & X & PIRQ & ENIRQ & X & MT & DT & ENT \\ \hline
+ \end{tabular}
+ }
+ \begin{itemize}
+ \item $SIO_{0-3}$ - Status of the I/O devices 0 - functional 1 - not functional
+ \item SDMA - DMA is active for 0 - inactive for 1
+ \item EOBT - End of block transfer for 0 - not for 1
+ \item EXTIRQ - There is an external interrupt from IO device for 0 - not for 1
+ \item PIRQ - There is a programable interrupt from CPU for 0 - not for 1 (testing)
+ \item ENIRQ - Enable interrupt for 0 - disable for 1
+ \item MT - Mode of transfer 0 - block for 1 - cycle stealing
+ \item DT - Direction of transfer 0 - from IO to memory to IO for 1 - from memory to IO
+ \item ENT - Enable transfer for 0 - disable for 1
+ \end{itemize}
+ \caption{SCDMA Register}
+\end{table}
+
+
+\begin{table}[H]
+ \resizebox{\textwidth}{!}{%
+ \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|}
+ \hline
+ \textbf{0} & \textbf{1} & \textbf{2} & \textbf{3} & \textbf{4} & \textbf{5} & \textbf{6} & \textbf{7} & \textbf{8} & \textbf{9} & \textbf{10} & \textbf{11} & \textbf{12} & \textbf{13} & \textbf{14} & \textbf{15} \\ \hline
+ $S$ & $C$ & X & X & X & X & X & X & X & X & X & ENIRQ & X & X & DT & X \\ \hline
+ \end{tabular}
+ }
+ \begin{itemize}
+ \item $S$ - Status of the IO device 0 - functional 1 - not functional
+ \item $C$ - Start transfer for 1 - stop for 0
+ \item ENIRQ - Enable interrupt for 0 - disable for 1
+ \item DT - Direction of transfer 0 - from IO to memory to IO for 1 - from memory to IO
+ \end{itemize}
+ \caption{SCIOX Register}
+\end{table}
+
+
+\subsection*{Solution}
+To determine the value on the data bus, we need to consider the DMA transfer
+settings and the memory address being accessed.
+
+Given the values:
+\begin{itemize}
+ \item SCDMA = 0x0192
+ \item MADMA = 0x5678
+ \item CNTDMA = 0x0005
+ \item INITDMA = 0x0001
+ \item SCIO0 = 0x0000
+ \item SCIO1 = 0x0000
+ \item SCIO2 = 0x0000
+ \item SCIO3 = 0x0000
+\end{itemize}
+
+The DMA transfer is initialized (INITDMA = 0x0001),
+and the starting address for the DMA transfer is 0x5678.
+The count of data to be transferred is 5 (CNTDMA = 0x0005).
+
+Since the DMA is active (SDMA = 0), and the direction of transfer is from memory to IO (DT = 1),
+the value on the data bus will be the data at the current memory address specified by MADMA plus
+CNTDMA = 0x567d.
+
+The value at memory address 0x567d is 0x0005.
+
+Therefore, the value on the data bus is:
+\[
+\text{Data Bus Value} = 0x0005
+\]
\ No newline at end of file
diff --git a/assignments/exam/main.tex b/assignments/exam/main.tex
new file mode 100644
index 00000000..ec13f617
--- /dev/null
+++ b/assignments/exam/main.tex
@@ -0,0 +1,78 @@
+\documentclass[a4paper,12pt]{article}
+\usepackage{amsmath}
+\usepackage{geometry}
+\usepackage{graphicx}
+\usepackage{subcaption}
+\usepackage{multirow}
+\usepackage{multicol}
+\usepackage{float}
+\geometry{a4paper, margin=1in}
+
+\title{Model Examen AB}
+\date{}
+
+\begin{document}
+
+\maketitle
+
+\section{Hexadecimal to Binary}
+\input{hextobin/sol.tex}
+
+\section{Hexadecimal to Decimal}
+\input{hextodec/sol.tex}
+
+\section{IEEE 754}
+\input{ieee754/sol.tex}
+
+\section{Cache Type}
+\input{cachetype/sol.tex}
+
+\section{Cache Block Size}
+\input{cacheblocksize/sol.tex}
+
+\section{Cache Size}
+\input{cachesize/sol.tex}
+
+\section{Cache Associativity}
+\input{cacheassociativity/sol.tex}
+
+\section{Multi-level Cache}
+\input{multilevelcache/sol.tex}
+
+\section{Adder Type}
+\input{addertype/sol.tex}
+
+\section{Booth's Algorithm}
+\input{booth/sol.tex}
+
+\section{Flags}
+\input{flags/sol.tex}
+
+\section{Addressing Modes}
+\input{addressing/sol.tex}
+
+\section{Instruction Set}
+\input{instructionset/sol.tex}
+
+\section{Decoding}
+\input{decoding/sol.tex}
+
+\section{IO}
+\input{io/sol.tex}
+
+\section{UART}
+\input{uart/sol.tex}
+
+\section{Interrupts}
+\input{interrupts/sol.tex}
+
+\section{Microcode MIC}
+\input{microcode/mic.tex}
+
+\section{Microcode MMC}
+\input{microcode/mmc.tex}
+
+\section{Microcode Minimal Instruction Set}
+\input{microcode/minimal.tex}
+
+\end{document}
\ No newline at end of file
diff --git a/assignments/exam/microcode/fetch.py b/assignments/exam/microcode/fetch.py
new file mode 100644
index 00000000..c25ba185
--- /dev/null
+++ b/assignments/exam/microcode/fetch.py
@@ -0,0 +1,445 @@
+import sys, json, random, datetime
+import numpy as np
+quiz_order = 2
+args = {param.split('=')[0]: param.split('=')[1] for param in sys.argv[1:]}
+student_id = args['id']
+# TODO: change for EXAM
+secret = 0
+week=datetime.datetime.now().isocalendar()[0]
+random.seed(secret + quiz_order + week + int(student_id))
+
+# Define the micro-instructions and micro-operations
+micro_instructions = ["μI" + str(i) for i in range(random.randint(6, 9))]
+micro_operations = ["μO" + str(i) for i in range(random.randint(8, 10))]
+
+micro_instruction_table = {}
+for micro_instruction in micro_instructions:
+ micro_instruction_table[micro_instruction] = [1 if random.randint(0, 3) == 0 else 0 for _ in range(len(micro_operations))]
+ # Ensure at least one micro-operation is executed
+ micro_instruction_table[micro_instruction][random.randint(0, len(micro_operations) - 1)] = 1
+
+# Print the micro-instruction table
+# print(json.dumps(micro_instruction_table))
+
+# make the html table for the micro-instruction table
+micro_instruction_table_html = """
+
+"""
+micro_instruction_table_html += "Micro-Instruction | "
+for micro_operation in micro_operations:
+ micro_instruction_table_html += f"{micro_operation} | "
+micro_instruction_table_html += "
"
+
+for micro_instruction in micro_instructions:
+ micro_instruction_table_html += f"{micro_instruction} | "
+ for micro_operation in micro_operations:
+ micro_instruction_table_html += f"{micro_instruction_table[micro_instruction][micro_operations.index(micro_operation)]} | "
+ micro_instruction_table_html += "
"
+micro_instruction_table_html += "
"
+# print(micro_instruction_table_html)
+
+# two micro operations are incompatible if they are part of the same micro instruction
+incompatible_micro_operations_table = np.zeros((len(micro_operations), len(micro_operations)), dtype=int)
+for i in range(len(micro_operations)):
+ incompatible_micro_operations_table[i][i] = 1
+ for j in range(i + 1, len(micro_operations)):
+ for micro_instruction in micro_instruction_table:
+ if micro_instruction_table[micro_instruction][i] == 1 and micro_instruction_table[micro_instruction][j] == 1:
+ incompatible_micro_operations_table[i][j] = 1
+ incompatible_micro_operations_table[j][i] = 1
+
+# Print the incompatible micro-operations table
+# print(incompatible_micro_operations_table)
+
+
+incompatability_classes = []
+for i in range(len(micro_operations)):
+ incompatability_classes.append({
+ "micro_operations": [i],
+ "to_add": incompatible_micro_operations_table[i].copy()
+ })
+
+compose_incompatability_classes = []
+
+while len(incompatability_classes) > 0:
+ incompatibility_class = incompatability_classes.pop(0)
+ evolving = False
+ for i in range(len(micro_operations)):
+ # need to check if the micro operation is higher than any of the micro operations in the class
+ if np.all(np.array(incompatibility_class["micro_operations"]) < i):
+ if i not in incompatibility_class["micro_operations"] and incompatibility_class["to_add"][i] == 1:
+ incompatability_classes.append({
+ "micro_operations": incompatibility_class["micro_operations"] + [i],
+ "to_add": np.logical_and(incompatibility_class["to_add"], incompatible_micro_operations_table[i])
+ })
+ evolving = True
+ if evolving is False:
+ compose_incompatability_classes.append(incompatibility_class["micro_operations"])
+
+# print(compose_incompatability_classes)
+
+# we need to filter out the classes that are subsets of other classes
+maximum_incompatability_classes = []
+for i in range(len(compose_incompatability_classes)):
+ is_subset = False
+ for j in range(len(compose_incompatability_classes)):
+ if i != j and set(compose_incompatability_classes[i]).issubset(compose_incompatability_classes[j]):
+ is_subset = True
+ break
+ if is_subset is False:
+ maximum_incompatability_classes.append(compose_incompatability_classes[i])
+
+# print(maximum_incompatability_classes)
+
+# get the highest number of micro operations in a class
+max_micro_operations = max([len(incompatability_class) for incompatability_class in maximum_incompatability_classes])
+
+# Print the maximum incompatibility classes
+# print(max_micro_operations)
+
+if quiz_order == 0:
+ question = """
+
+
Given the following micro-instruction table, determine the highest cardinality of any of the maximum incompatible classes of micro-operations.
+
Micro-instruction table:
+
+ {}
+
+
+ """.format(micro_instruction_table_html)
+ print(
+ json.dumps(
+ {
+ "question": question,
+ "result": max_micro_operations
+ }
+ )
+ )
+
+
+compatability_classes = []
+for i in range(len(micro_operations)):
+ compatability_classes.append({
+ "micro_operations": [i],
+ "to_add": incompatible_micro_operations_table[i].copy()
+ })
+
+compose_compatability_classes = []
+
+while len(compatability_classes) > 0:
+ compatability_class = compatability_classes.pop(0)
+ evolving = False
+ for i in range(len(micro_operations)):
+ # need to check if the micro operation is higher than any of the micro operations in the class
+ if np.all(np.array(compatability_class["micro_operations"]) < i):
+ if i not in compatability_class["micro_operations"] and compatability_class["to_add"][i] == 0:
+ compatability_classes.append({
+ "micro_operations": compatability_class["micro_operations"] + [i],
+ "to_add": np.logical_or(compatability_class["to_add"], incompatible_micro_operations_table[i])
+ })
+ evolving = True
+ if evolving is False:
+ compose_compatability_classes.append(compatability_class["micro_operations"])
+
+# print(compose_compatability_classes)
+
+# we need to filter out the classes that are subsets of other classes
+maximum_compatability_classes = []
+for i in range(len(compose_compatability_classes)):
+ is_subset = False
+ for j in range(len(compose_compatability_classes)):
+ if i != j and set(compose_compatability_classes[i]).issubset(compose_compatability_classes[j]):
+ is_subset = True
+ break
+ if is_subset is False:
+ maximum_compatability_classes.append(compose_compatability_classes[i])
+
+# print(maximum_compatability_classes)
+
+# get the number of maximum compatability classes
+number_of_maximum_compatability_classes = len(maximum_compatability_classes)
+
+# Print the number of maximum compatability classes
+# print(number_of_maximum_compatability_classes)
+
+
+if quiz_order == 1:
+ question = """
+
+
Given the following micro-instruction table, determine the number of maximum compatibility classes of micro-operations.
+
Micro-instruction table:
+
+ {}
+
+
+ """.format(micro_instruction_table_html)
+ print(
+ json.dumps(
+ {
+ "question": question,
+ "result": number_of_maximum_compatability_classes
+ }
+ )
+ )
+
+# make the html table for the maximum incompatible classes
+maximum_incompatability_classes_html = """
+
+"""
+maximum_incompatability_classes_html += "MIC | "
+for micro_operation in micro_operations:
+ maximum_incompatability_classes_html += f"{micro_operation} | "
+maximum_incompatability_classes_html += "
"
+for i, maximum_incompatability_class in enumerate(maximum_incompatability_classes):
+ maximum_incompatability_classes_html += f"MIC_{i} | "
+ for j in range(len(micro_operations)):
+ maximum_incompatability_classes_html += f"{1 if j in maximum_incompatability_class else 0} | "
+ maximum_incompatability_classes_html += "
"
+maximum_incompatability_classes_html += "
"
+# print(maximum_incompatability_classes_html)
+
+# make the html table for the maximum compatible classes
+maximum_compatability_classes_html = """
+
+"""
+maximum_compatability_classes_html += "MCC | "
+for micro_operation in micro_operations:
+ maximum_compatability_classes_html += f"{micro_operation} | "
+maximum_compatability_classes_html += "
"
+for i, maximum_compatability_class in enumerate(maximum_compatability_classes):
+ maximum_compatability_classes_html += f"MCC_{i} | "
+ for j in range(len(micro_operations)):
+ maximum_compatability_classes_html += f"{1 if j in maximum_compatability_class else 0} | "
+ maximum_compatability_classes_html += "
"
+maximum_compatability_classes_html += "
"
+# print(maximum_compatability_classes_html)
+
+# select the maximum incompatible class with the highest number of micro operations
+selected_maximum_incompatability_class = max(maximum_incompatability_classes, key=len)
+
+# Print the selected maximum incompatibility class
+# print(selected_maximum_incompatability_class)
+
+# select all the maximum compaticipiity classes that have at least one micro operation in the selected maximum incompatibility class
+selected_maximum_compatability_classes = []
+for maximum_compatability_class in maximum_compatability_classes:
+ if len(set(maximum_compatability_class).intersection(set(selected_maximum_incompatability_class))) > 0:
+ selected_maximum_compatability_classes.append(maximum_compatability_class)
+
+# Print the selected maximum compatability classes
+# print(selected_maximum_compatability_classes)
+
+current_solutions = []
+current_solutions.append({
+ "indexes": [],
+ "remaining_classes": [{ "index": i, "microop": maximum_compatability_class } for i, maximum_compatability_class in enumerate(selected_maximum_compatability_classes)]
+})
+def get_essential_classes(remaining_classes):
+ essential_classes = []
+ for maximum_compatability_class in remaining_classes:
+ for micro_operation in maximum_compatability_class["microop"]:
+ is_unique = True
+ for other_maximum_compatability_class in remaining_classes:
+ if maximum_compatability_class != other_maximum_compatability_class and micro_operation in other_maximum_compatability_class["microop"]:
+ is_unique = False
+ break
+ if is_unique:
+ essential_classes.append(maximum_compatability_class)
+ break
+ return essential_classes
+
+def remove_micro_operations(remaining_classes, essential_classes):
+ for essential_class in essential_classes:
+ for micro_operation in essential_class["microop"]:
+ for other_maximum_compatability_class in remaining_classes:
+ if micro_operation in other_maximum_compatability_class["microop"]:
+ other_maximum_compatability_class["microop"].remove(micro_operation)
+searchable = True
+while searchable:
+ searchable = False
+ new_current_solutions = []
+ for current_solution in current_solutions:
+ remaining_classes = current_solution["remaining_classes"]
+ current_indexes = current_solution["indexes"]
+ # if they are remaining classes
+ if len(remaining_classes) > 0:
+ # if any of the selected maximum compatability classes is the only class that has a micro operation that is not in the other classes
+ # then we can add that class to the current solution
+ essential_classes = get_essential_classes(remaining_classes)
+ if len(essential_classes) > 0:
+ current_indexes += [essential_class["index"] for essential_class in essential_classes]
+ for essential_class in essential_classes:
+ remaining_classes.remove(essential_class)
+ remove_micro_operations(remaining_classes, essential_classes)
+ new_current_solutions.append({
+ "indexes": current_indexes,
+ "remaining_classes": remaining_classes
+ })
+ searchable = True
+ else:
+ # find the class with the highest number of micro operations
+ maximum_micro_operations = max([len(maximum_compatability_class["microop"]) for maximum_compatability_class in remaining_classes])
+ if maximum_micro_operations > 0:
+ # maximum_micro_operations_classes = [maximum_compatability_class for maximum_compatability_class in remaining_classes if len(maximum_compatability_class["microop"]) == maximum_micro_operations]
+ # for each class we create a new solution
+ # for remaining_class in maximum_micro_operations_classes:
+ for remaining_class in remaining_classes:
+ new_remaining_classes = remaining_classes.copy()
+ new_remaining_classes.remove(remaining_class)
+ new_current_indexes = current_indexes.copy()
+ new_current_indexes.append(remaining_class["index"])
+ remove_micro_operations(new_remaining_classes, [remaining_class])
+ new_current_solutions.append({
+ "indexes": new_current_indexes,
+ "remaining_classes": new_remaining_classes
+ })
+ searchable = True
+ if searchable:
+ current_solutions = new_current_solutions.copy()
+
+
+# Print the current solution
+# print("current_solutions")
+# print(current_solutions)
+
+# filter the solutions that have a subset of the indexes in another solution
+filtered_current_solutions = []
+for current_solution in current_solutions:
+ has_subset = False
+ for other_current_solution in current_solutions:
+ if current_solution != other_current_solution and set(other_current_solution["indexes"]).issubset(set(current_solution["indexes"])):
+ if len(other_current_solution["indexes"]) < len(current_solution["indexes"]):
+ has_subset = True
+ break
+ if has_subset is False:
+ filtered_current_solutions.append(current_solution)
+
+# Print the filtered current solutions
+# print("filtered_current_solutions")
+# print(filtered_current_solutions)
+
+# store only the set of indexes
+final_solutions = []
+for filtered_current_solution in filtered_current_solutions:
+ current_indexes = set(filtered_current_solution["indexes"])
+ if current_indexes not in final_solutions:
+ final_solutions.append(current_indexes)
+
+# Print the final solutions
+# print("final_solutions")
+# print(final_solutions)
+
+def clog2(x):
+ """Ceiling of log2"""
+ if x <= 0:
+ raise ValueError("domain error")
+ return (x-1).bit_length()
+
+# for each solutions we take every time the class with the highest number of micro operations
+def get_minimum_instruction_size(solution):
+ minimum_instruction_size = 0
+ instruction_size_solutions = []
+ instruction_size_solutions.append({
+ "indexes": list(solution),
+ "remaining_classes": [{ "index": i, "microop": selected_maximum_compatability_classes[i] } for i in solution],
+ "instruction_size": 0
+ })
+
+ searchable = True
+ while searchable:
+ searchable = False
+ new_instruction_size_solutions = []
+ for current_solution in instruction_size_solutions:
+ remaining_classes = current_solution["remaining_classes"]
+ current_indexes = current_solution["indexes"]
+ current_instruction_size = current_solution["instruction_size"]
+ # if they are remaining classes
+ if len(remaining_classes) > 0:
+ # find the class with the highest number of micro operations
+ maximum_micro_operations = max([len(maximum_compatability_class["microop"]) for maximum_compatability_class in remaining_classes])
+ if maximum_micro_operations > 0:
+ maximum_micro_operations_classes = [maximum_compatability_class for maximum_compatability_class in remaining_classes if len(maximum_compatability_class["microop"]) == maximum_micro_operations]
+ # for each class we create a new solution
+ for remaining_class in maximum_micro_operations_classes:
+ new_remaining_classes = remaining_classes.copy()
+ new_remaining_classes.remove(remaining_class)
+ new_current_indexes = current_indexes.copy()
+ new_current_indexes.append(remaining_class["index"])
+ new_current_instruction_size = current_instruction_size + clog2(len(remaining_class["microop"]) + 1)
+ new_instruction_size_solutions.append({
+ "indexes": new_current_indexes,
+ "remaining_classes": new_remaining_classes,
+ "instruction_size": new_current_instruction_size
+ })
+ searchable = True
+ if searchable:
+ instruction_size_solutions = new_instruction_size_solutions.copy()
+ return min([current_solution["instruction_size"] for current_solution in instruction_size_solutions])
+
+# get the minimum instruction size for each solution
+minimum_instruction_sizes = [get_minimum_instruction_size(final_solution) for final_solution in final_solutions]
+
+# Print the minimum instruction sizes
+# print("minimum_instruction_sizes")
+# print(minimum_instruction_sizes)
+
+# get the minimum instruction size
+minimum_instruction_size = min(minimum_instruction_sizes)
+
+# Print the minimum instruction size
+# print("minimum_instruction_size")
+# print(minimum_instruction_size)
+
+if quiz_order == 2:
+ question = """
+
+
Given the following micro-instruction table, maximum incompatible classes table, and maximum compatible classes table determine the minimum instruction size required to encode the micro-instructions.
+
Micro-instruction table:
+
+ {}
+
+
Maximum Incompatible Classes:
+
+ {}
+
+
Maximum Compatible Classes:
+
+ {}
+
+
+ """.format(micro_instruction_table_html, maximum_incompatability_classes_html, maximum_compatability_classes_html)
+ print(
+ json.dumps(
+ {
+ "question": question,
+ "result": minimum_instruction_size
+ }
+ )
+ )
\ No newline at end of file
diff --git a/assignments/exam/microcode/mic.tex b/assignments/exam/microcode/mic.tex
new file mode 100644
index 00000000..f62b008e
--- /dev/null
+++ b/assignments/exam/microcode/mic.tex
@@ -0,0 +1,72 @@
+\subsection*{Problem}
+
+Given the following set of micro-instruction $\mu P(\mu I)$, with the table of every micro-instruction with the corresponding micro-operations $\mu P(\mu O)$ executed in the table.
+What is the highest cardinality of maximum incompatibility class?
+
+\begin{align*}
+\mu P(\mu I) & = \{ \mu I_{0}, \mu I_{1}, \mu I_{2}, \mu I_{3}, \mu I_{4}, \mu I_{5}, \mu I_{6}\} \\
+\mu P(\mu O) & = \{ \mu O_{0}, \mu O_{1}, \mu O_{2}, \mu O_{3}, \mu O_{4}, \mu O_{5}, \mu O_{6}, \mu O_{7}, \mu O_{8}, \mu O_{9}\}
+\end{align*}
+
+\begin{table}[H]
+ \centering
+ \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|}
+ \hline
+ $\mu I$ & $\mu O_{0}$ & $\mu O_{1}$ & $\mu O_{2}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{5}$ & $\mu O_{6}$ & $\mu O_{7}$ & $\mu O_{8}$ & $\mu O_{9}$ \\
+ \hline
+ \hline
+ $\mu I_{0}$ & 1 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ \hline
+ $\mu I_{1}$ & 1 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ \hline
+ $\mu I_{2}$ & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 1 & 0 \\ \hline
+ $\mu I_{3}$ & 0 & 0 & 0 & 1 & 1 & 0 & 1 & 1 & 0 & 0 \\ \hline
+ $\mu I_{4}$ & 0 & 0 & 1 & 1 & 1 & 1 & 1 & 0 & 0 & 0 \\ \hline
+ $\mu I_{5}$ & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 1 \\ \hline
+ $\mu I_{6}$ & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 \\ \hline
+ \end{tabular}
+\end{table}
+
+\subsection*{Solution}
+
+1. Find the incompatibility between each micro-operation $\mu O_{i}$.
+
+Two micro-operations are incompatible if they are part of the same micro-instruction $\mu I_{j}$.
+\begin{table}[H]
+ \centering
+ \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|c|}
+ \hline
+ $\mu O$ & $\mu O_{0}$ & $\mu O_{1}$ & $\mu O_{2}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{5}$ & $\mu O_{6}$ & $\mu O_{7}$ & $\mu O_{8}$ & $\mu O_{9}$ \\ \hline
+ $\mu O_{0}$ & 1 & 1 & 1 & 1 & 1 & 0 & 0 & 0 & 0 & 0 \\ \hline
+ $\mu O_{1}$ & 1 & 1 & 0 & 1 & 0 & 1 & 0 & 1 & 1 & 0 \\ \hline
+ $\mu O_{2}$ & 1 & 0 & 1 & 1 & 1 & 1 & 1 & 0 & 0 & 0 \\ \hline
+ $\mu O_{3}$ & 1 & 1 & 1 & 1 & 1 & 1 & 1 & 1 & 0 & 0 \\ \hline
+ $\mu O_{4}$ & 1 & 0 & 1 & 1 & 1 & 1 & 1 & 1 & 0 & 0 \\ \hline
+ $\mu O_{5}$ & 0 & 1 & 1 & 1 & 1 & 1 & 1 & 1 & 1 & 1 \\ \hline
+ $\mu O_{6}$ & 0 & 0 & 1 & 1 & 1 & 1 & 1 & 1 & 0 & 1 \\ \hline
+ $\mu O_{7}$ & 0 & 1 & 0 & 1 & 1 & 1 & 1 & 1 & 1 & 0 \\ \hline
+ $\mu O_{8}$ & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 1 & 1 \\ \hline
+ $\mu O_{9}$ & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 1 & 1 \\ \hline
+ \end{tabular}
+\end{table}
+
+2. Find the incompatibility classes for each micro-operation combination of micro-operations $\mu O_{i}$.
+
+To make incompatible classes we choose micro-operation from the table of incompatible operations and AND their rows.
+If there is 1 on the columns of the microoperations than it is a good match. After we try to add to the incompatibility
+class the other micro operation which have the value 1 on their column. If there is any 0 on the columns of the microoperations of the class than it is not a good match.
+\begin{table}[H]
+ \centering
+ \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|c|}
+ \hline
+ $MIC$ & $\mu O_{0}$ & $\mu O_{1}$ & $\mu O_{2}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{5}$ & $\mu O_{6}$ & $\mu O_{7}$ & $\mu O_{8}$ & $\mu O_{9}$ \\ \hline
+ $MIC_{0}$ & 1 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ \hline
+ $MIC_{1}$ & 1 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 0 & 0 \\ \hline
+ $MIC_{2}$ & 0 & 1 & 0 & 1 & 0 & 1 & 0 & 1 & 0 & 0 \\ \hline
+ $MIC_{3}$ & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 1 & 0 \\ \hline
+ $MIC_{4}$ & 0 & 0 & 1 & 1 & 1 & 1 & 1 & 0 & 0 & 0 \\ \hline
+ $MIC_{5}$ & 0 & 0 & 0 & 1 & 1 & 1 & 1 & 1 & 0 & 0 \\ \hline
+ $MIC_{6}$ & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 1 \\ \hline
+ $MIC_{7}$ & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 1 \\ \hline
+ \end{tabular}
+\end{table}
+
+The highest cardinality of maximum incompatible class is 5 ($MIC_{4}$ and $MIC_{5}$).
\ No newline at end of file
diff --git a/assignments/exam/microcode/minimal.tex b/assignments/exam/microcode/minimal.tex
new file mode 100644
index 00000000..334b4c6f
--- /dev/null
+++ b/assignments/exam/microcode/minimal.tex
@@ -0,0 +1,140 @@
+\section*{Problem}
+
+Given the table of maximum incompatible classes and table of maximum compatibility classes, find the nimimal number of bits for the micro-instruction.
+
+\begin{table}[H]
+ \centering
+ \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|c|}
+ \hline
+ $MIC$ & $\mu O_{0}$ & $\mu O_{1}$ & $\mu O_{2}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{5}$ & $\mu O_{6}$ & $\mu O_{7}$ & $\mu O_{8}$ & $\mu O_{9}$ \\ \hline
+ $MIC_{0}$ & 1 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ \hline
+ $MIC_{1}$ & 1 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 0 & 0 \\ \hline
+ $MIC_{2}$ & 0 & 1 & 0 & 1 & 0 & 1 & 0 & 1 & 0 & 0 \\ \hline
+ $MIC_{3}$ & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 1 & 0 \\ \hline
+ $MIC_{4}$ & 0 & 0 & 1 & 1 & 1 & 1 & 1 & 0 & 0 & 0 \\ \hline
+ $MIC_{5}$ & 0 & 0 & 0 & 1 & 1 & 1 & 1 & 1 & 0 & 0 \\ \hline
+ $MIC_{6}$ & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 1 \\ \hline
+ $MIC_{7}$ & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 1 \\ \hline
+ \end{tabular}
+\end{table}
+
+\begin{table}[H]
+ \centering
+ \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|}
+ \hline
+ $MCC$ & $\mu O_{0}$ & $\mu O_{1}$ & $\mu O_{2}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{5}$ & $\mu O_{6}$ & $\mu O_{7}$ & $\mu O_{8}$ & $\mu O_{9}$ \\ \hline
+ $MCC_{0}$ & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ \hline
+ $MCC_{1}$ & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 \\ \hline
+ $MCC_{2}$ & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 \\ \hline
+ $MCC_{3}$ & 0 & 1 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ \hline
+ $MCC_{4}$ & 0 & 1 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 \\ \hline
+ $MCC_{5}$ & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ \hline
+ $MCC_{6}$ & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 1 \\ \hline
+ $MCC_{7}$ & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\ \hline
+ $MCC_{8}$ & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 \\ \hline
+ $MCC_{9}$ & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 \\ \hline
+ $MCC_{10}$ & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 0 \\ \hline
+ \end{tabular}
+\end{table}
+
+\section*{Solution}
+
+1. Select the maximum compatibility class with the highest cardinality and compute the Associated maximum compatible classes.
+The highest cardinality of maximum incompatible class is 5 ($MIC_{4}$ and $MIC{5}$).
+Let's choose $MIC_{5}$.
+ $AMCC(\mu O_{i} \in MIC_{5}) = \{ MCC_{0}, MCC_{1}, MCC_{2}, MCC_{4}, MCC_{5}, MCC_{6}, MCC_{8}, MCC_{9}, MCC_{10}\}$
+
+ \begin{table}[H]
+ \centering
+ \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|}
+ \hline
+ $MCC$ & $\mu O_{0}$ & $\mu O_{1}$ & $\mu O_{2}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{5}$ & $\mu O_{6}$ & $\mu O_{7}$ & $\mu O_{8}$ & $\mu O_{9}$ \\ \hline
+ $MCC_{0}$ & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ \hline
+ $MCC_{1}$ & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 \\ \hline
+ $MCC_{2}$ & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 \\ \hline
+ $MCC_{4}$ & 0 & 1 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 \\ \hline
+ $MCC_{5}$ & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ \hline
+ $MCC_{6}$ & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 1 \\ \hline
+ $MCC_{8}$ & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 \\ \hline
+ $MCC_{9}$ & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 \\ \hline
+ $MCC_{10}$ & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 0 \\ \hline
+ \end{tabular}
+ \end{table}
+
+2. Eliminate essential maximum compatibility classes and add the the to the solution set.
+The essential compatible classes are the ones that contain a micro-operation that is not in any other compatible class.
+Select the essential compatible classes. In this case $MCC_{0}$ and $MCC_{6}$.
+$S = \{MCC_{0}, MCC_{6}\}$.
+
+\begin{table}[H]
+ \centering
+ \begin{tabular}{|c|c|c|c|c|c|c|}
+ \hline
+ $MCC$ & $\mu O_{1}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{6}$ & $\mu O_{8}$ \\ \hline
+ $MCC_{1}$ & 0 & 0 & 0 & 1 & 1 \\ \hline
+ $MCC_{2}$ & 0 & 0 & 0 & 0 & 0 \\ \hline
+ $MCC_{4}$ & 1 & 0 & 1 & 0 & 0 \\ \hline
+ $MCC_{5}$ & 1 & 0 & 0 & 1 & 0 \\ \hline
+ $MCC_{8}$ & 0 & 1 & 0 & 0 & 1 \\ \hline
+ $MCC_{9}$ & 0 & 1 & 0 & 0 & 0 \\ \hline
+ $MCC_{10}$ & 0 & 0 & 1 & 0 & 1 \\ \hline
+ \end{tabular}
+\end{table}
+
+$MCC_{2}$ and $MCC_{9}$ does not contain any micro-operation that is not in any other compatible class. So we can remove them from the table.
+\begin{table}[H]
+ \centering
+ \begin{tabular}{|c|c|c|c|c|c|c|}
+ \hline
+ $MCC$ & $\mu O_{1}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{6}$ & $\mu O_{8}$ \\ \hline
+ $MCC_{1}$ & 0 & 0 & 0 & 1 & 1 \\ \hline
+ $MCC_{4}$ & 1 & 0 & 1 & 0 & 0 \\ \hline
+ $MCC_{5}$ & 1 & 0 & 0 & 1 & 0 \\ \hline
+ $MCC_{8}$ & 0 & 1 & 0 & 0 & 1 \\ \hline
+ $MCC_{10}$ & 0 & 0 & 1 & 0 & 1 \\ \hline
+ \end{tabular}
+\end{table}
+This makes $MCC_{8}$ an essential compatible class. Remove it from the table and add it to the solution set.
+$S = \{MCC_{0}, MCC_{6}, MCC_{8}\}$.
+
+3. From the remaining compatible classes generate possible solutions.
+
+\begin{table}[H]
+ \centering
+ \begin{tabular}{|c|c|c|c|c|c|c|}
+ \hline
+ $MCC$ & $\mu O_{1}$ & $\mu O_{4}$ & $\mu O_{6}$ \\ \hline
+ $MCC_{1}$ & 0 & 0 & 1 \\ \hline
+ $MCC_{4}$ & 1 & 1 & 0 \\ \hline
+ $MCC_{5}$ & 1 & 0 & 1 \\ \hline
+ $MCC_{10}$ & 0 & 1 & 0 \\ \hline
+ \end{tabular}
+\end{table}
+The possible additions solution sets are: $\{MCC_{1}, MCC_{4}\}$, $\{MCC_{4}, MCC_{5}\}$, $\{MCC_{5}, MCC_{10}\}$.
+The possible sollution sets are: $\{MCC_{0}, MCC_{6}, MCC_{8}, MCC_{1}, MCC_{4}\}$, $\{MCC_{0}, MCC_{6}, MCC_{8}, MCC_{4}, MCC_{5}\}$, $\{MCC_{0}, MCC_{6}, MCC_{8}, MCC_{5}, MCC_{10}\}$.
+
+The table with all micro operations and the selected compatible classes.
+\begin{table}[H]
+ \centering
+ \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|c|}
+ \hline
+ $MCC$ & $\mu O_{0}$ & $\mu O_{1}$ & $\mu O_{2}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{5}$ & $\mu O_{6}$ & $\mu O_{7}$ & $\mu O_{8}$ & $\mu O_{9}$ & $|MCC|$ \\ \hline
+ $MCC_{0}$ & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 2\\ \hline
+ $MCC_{1}$ & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 3\\ \hline
+ $MCC_{4}$ & 0 & 1 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 3\\ \hline
+ $MCC_{5}$ & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 2\\ \hline
+ $MCC_{6}$ & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 3\\ \hline
+ $MCC_{8}$ & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 2\\ \hline
+ $MCC_{10}$ & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 2\\ \hline
+ \end{tabular}
+\end{table}
+Order the maximum compatible classes in the solution set by their cardinality.
+
+The cost for the solutions are:
+\begin{itemize}
+ \item $C(S_{0}) = \{ (\mu O_{2}, \mu O_{7}, \mu O_{9}), (\mu O_{0}, \mu O_{6}, \mu O_{8}), (\mu O_{1}, \mu O_{4}), (\mu O_{3}), (\mu O_{5}) \} = 8$
+ \item $C(S_{1}) = \{ (\mu O_{2}, \mu O_{7}, \mu O_{9}), (\mu O_{0}, \mu O_{5}), (\mu O_{1}, \mu O_{6}), (\mu O_{8}, \mu O_{3}), (\mu O_{4}) \} = 9$
+ \item $C(S_{2}) = \{ (\mu O_{2}, \mu O_{7}, \mu O_{9}), (\mu O_{1}, \mu O_{6}), (\mu O_{0}, \mu O_{5}), (\mu O_{3}, \mu O_{8}), (\mu O_{4}) \} = 9$
+\end{itemize}
+
+The minimal microinstruction coding is $S_{0} = \{MCC_{0}, MCC_{6}, MCC_{8}, MCC_{1}, MCC_{4}\}$ with a cost of 8.
\ No newline at end of file
diff --git a/assignments/exam/microcode/mmc.tex b/assignments/exam/microcode/mmc.tex
new file mode 100644
index 00000000..d3446b25
--- /dev/null
+++ b/assignments/exam/microcode/mmc.tex
@@ -0,0 +1,54 @@
+\subsection*{Problem}
+Given the following set of micro-instruction $\mu P(\mu I)$, with every micro-instruction table of micro-operations $\mu P(\mu O)$ executed in the table.
+How many maximum compatibility classes are?
+
+\begin{align*}
+ \mu P(\mu I) & = \{ \mu I_{0}, \mu I_{1}, \mu I_{2}, \mu I_{3}, \mu I_{4}, \mu I_{5}, \mu I_{6}\} \\
+ \mu P(\mu O) & = \{ \mu O_{0}, \mu O_{1}, \mu O_{2}, \mu O_{3}, \mu O_{4}, \mu O_{5}, \mu O_{6}, \mu O_{7}, \mu O_{8}, \mu O_{9}\}
+\end{align*}
+
+\begin{table}[H]
+ \centering
+ \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|}
+ \hline
+ $\mu I$ & $\mu O_{0}$ & $\mu O_{1}$ & $\mu O_{2}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{5}$ & $\mu O_{6}$ & $\mu O_{7}$ & $\mu O_{8}$ & $\mu O_{9}$ \\
+ \hline
+ \hline
+ $\mu I_{0}$ & 1 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ \hline
+ $\mu I_{1}$ & 1 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ \hline
+ $\mu I_{2}$ & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 1 & 0 \\ \hline
+ $\mu I_{3}$ & 0 & 0 & 0 & 1 & 1 & 0 & 1 & 1 & 0 & 0 \\ \hline
+ $\mu I_{4}$ & 0 & 0 & 1 & 1 & 1 & 1 & 1 & 0 & 0 & 0 \\ \hline
+ $\mu I_{5}$ & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 1 \\ \hline
+ $\mu I_{6}$ & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 \\ \hline
+ \end{tabular}
+\end{table}
+
+\section*{Solution}
+
+1. Find the compatibility between each micro-operation $\mu O_{i}$.
+
+Two micro-operations are compatible if they are not part of the same micro-instruction $\mu I_{j}$.
+We can find them by chosing the micro-operations from the table of incompatible operations and OR their rows.
+The columns contianing 0 are succesible to be in the same compatibility class. We need to try until we can not find
+any more compatible micro-operations.
+\begin{table}[H]
+ \centering
+ \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|}
+ \hline
+ $MCC$ & $\mu O_{0}$ & $\mu O_{1}$ & $\mu O_{2}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{5}$ & $\mu O_{6}$ & $\mu O_{7}$ & $\mu O_{8}$ & $\mu O_{9}$ \\ \hline
+ $MCC_{0}$ & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ \hline
+ $MCC_{1}$ & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 \\ \hline
+ $MCC_{2}$ & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 \\ \hline
+ $MCC_{3}$ & 0 & 1 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ \hline
+ $MCC_{4}$ & 0 & 1 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 \\ \hline
+ $MCC_{5}$ & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ \hline
+ $MCC_{6}$ & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 1 \\ \hline
+ $MCC_{7}$ & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\ \hline
+ $MCC_{8}$ & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 \\ \hline
+ $MCC_{9}$ & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 \\ \hline
+ $MCC_{10}$ & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 0 \\ \hline
+ \end{tabular}
+\end{table}
+
+2. The answer is the number of maximum compatibility classes. In this case, the number of maximum compatibility classes is 11.
\ No newline at end of file
diff --git a/assignments/exam/microcode/sol.tex b/assignments/exam/microcode/sol.tex
new file mode 100644
index 00000000..3124705b
--- /dev/null
+++ b/assignments/exam/microcode/sol.tex
@@ -0,0 +1,233 @@
+
+\begin{frame}
+ \frametitle{Exam Questions}
+ Template: Given the following set of micro-instruction $\mu P(\mu I)$, with every micro-instruction table of micro-operations $\mu P(\mu O)$ executed in the table. Compute the minimal microinstruction coding.
+
+ Example:
+
+ $\mu P(\mu I) = \{ \mu I_{0}, \mu I_{1}, \mu I_{2}, \mu I_{3}, \mu I_{4}, \mu I_{5}, \mu I_{6}\}$
+ $\mu P(\mu O) = \{ \mu O_{0}, \mu O_{1}, \mu O_{2}, \mu O_{3}, \mu O_{4}, \mu O_{5}, \mu O_{6}, \mu O_{7}, \mu O_{8}, \mu O_{9}\}$.
+ \begin{table}
+ \resizebox{0.8\textwidth}{!}{%
+ \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|}
+ \hline
+ $\mu I$ & $\mu O_{0}$ & $\mu O_{1}$ & $\mu O_{2}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{5}$ & $\mu O_{6}$ & $\mu O_{7}$ & $\mu O_{8}$ & $\mu O_{9}$ \\
+ \hline
+ \hline
+ $\mu I_{0}$ & 1 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ \hline
+ $\mu I_{1}$ & 1 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ \hline
+ $\mu I_{2}$ & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 1 & 0 \\ \hline
+ $\mu I_{3}$ & 0 & 0 & 0 & 1 & 1 & 0 & 1 & 1 & 0 & 0 \\ \hline
+ $\mu I_{4}$ & 0 & 0 & 1 & 1 & 1 & 1 & 1 & 0 & 0 & 0 \\ \hline
+ $\mu I_{5}$ & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 1 \\ \hline
+ $\mu I_{6}$ & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 \\ \hline
+ \end{tabular}%
+ }
+ \end{table}
+\end{frame}
+
+\begin{frame}
+ \frametitle{Solution - Table of incompatible operations}
+ \begin{table}
+ \resizebox{0.8\textwidth}{!}{%
+ \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|c|}
+ \hline
+ $\mu O$ & $\mu O_{0}$ & $\mu O_{1}$ & $\mu O_{2}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{5}$ & $\mu O_{6}$ & $\mu O_{7}$ & $\mu O_{8}$ & $\mu O_{9}$ \\ \hline
+ $\mu O_{0}$ & 1 & 1 & 1 & 1 & 1 & 0 & 0 & 0 & 0 & 0 \\ \hline
+ $\mu O_{1}$ & 1 & 1 & 0 & 1 & 0 & 1 & 0 & 1 & 1 & 0 \\ \hline
+ $\mu O_{2}$ & 1 & 0 & 1 & 1 & 1 & 1 & 1 & 0 & 0 & 0 \\ \hline
+ $\mu O_{3}$ & 1 & 1 & 1 & 1 & 1 & 1 & 1 & 1 & 0 & 0 \\ \hline
+ $\mu O_{4}$ & 1 & 0 & 1 & 1 & 1 & 1 & 1 & 1 & 0 & 0 \\ \hline
+ $\mu O_{5}$ & 0 & 1 & 1 & 1 & 1 & 1 & 1 & 1 & 1 & 1 \\ \hline
+ $\mu O_{6}$ & 0 & 0 & 1 & 1 & 1 & 1 & 1 & 1 & 0 & 1 \\ \hline
+ $\mu O_{7}$ & 0 & 1 & 0 & 1 & 1 & 1 & 1 & 1 & 1 & 0 \\ \hline
+ $\mu O_{8}$ & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 1 & 1 \\ \hline
+ $\mu O_{9}$ & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 1 & 1 \\ \hline
+ \end{tabular}%
+ }
+ \end{table}
+\end{frame}
+
+\begin{frame}
+ \frametitle{Solution - Maximum incompatible classes}
+ \begin{table}
+ \resizebox{0.8\textwidth}{!}{%
+ \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|c|}
+ \hline
+ $MIC$ & $\mu O_{0}$ & $\mu O_{1}$ & $\mu O_{2}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{5}$ & $\mu O_{6}$ & $\mu O_{7}$ & $\mu O_{8}$ & $\mu O_{9}$ \\ \hline
+ $MIC_{0}$ & 1 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ \hline
+ $MIC_{1}$ & 1 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 0 & 0 \\ \hline
+ $MIC_{2}$ & 0 & 1 & 0 & 1 & 0 & 1 & 0 & 1 & 0 & 0 \\ \hline
+ $MIC_{3}$ & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 1 & 0 \\ \hline
+ $MIC_{4}$ & 0 & 0 & 1 & 1 & 1 & 1 & 1 & 0 & 0 & 0 \\ \hline
+ $MIC_{5}$ & 0 & 0 & 0 & 1 & 1 & 1 & 1 & 1 & 0 & 0 \\ \hline
+ $MIC_{6}$ & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 1 \\ \hline
+ $MIC_{7}$ & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 1 \\ \hline
+ \end{tabular}%
+ }
+ \end{table}
+ \note{
+ To make incompatible classes we choose micro-operation from the table of incompatible operations and AND their rows.
+ If there is a 1 in the result that micro-operation is incompatible with the other micro-operations and is can be
+ added to the incompatible class. If there are only 0s in the result than the current set of micro-operations is a maximum incompatible class.
+ }
+\end{frame}
+
+\begin{frame}
+ \frametitle{Solution - Maximum compatible classes}
+ \begin{table}
+ \resizebox{0.8\textwidth}{!}{%
+ \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|}
+ \hline
+ $MCC$ & $\mu O_{0}$ & $\mu O_{1}$ & $\mu O_{2}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{5}$ & $\mu O_{6}$ & $\mu O_{7}$ & $\mu O_{8}$ & $\mu O_{9}$ \\ \hline
+ $MCC_{0}$ & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ \hline
+ $MCC_{1}$ & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 \\ \hline
+ $MCC_{2}$ & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 \\ \hline
+ $MCC_{3}$ & 0 & 1 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ \hline
+ $MCC_{4}$ & 0 & 1 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 \\ \hline
+ $MCC_{5}$ & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ \hline
+ $MCC_{6}$ & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 1 \\ \hline
+ $MCC_{7}$ & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\ \hline
+ $MCC_{8}$ & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 \\ \hline
+ $MCC_{9}$ & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 \\ \hline
+ $MCC_{10}$ & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 0 \\ \hline
+ \end{tabular}%
+ }
+ \end{table}
+\end{frame}
+
+\begin{frame}
+ \frametitle{Solution - Associated maximum compatible classes}
+ Select the maximum incompatible class with the biggest cardinality. In this case is $MIC(\mu O_{4})$ or $MIC(\mu O_{5})$.
+ Let's choose $MIC(\mu O_{5})$.
+ $AMCC(\mu O_{i} \in MIC(\mu O_{5})) = \{ MCC_{0}, MCC_{1}, MCC_{2}, MCC_{4}, MCC_{5}, MCC_{6}, MCC_{8}, MCC_{9}, MCC_{10}\}$
+
+ \begin{table}
+ \resizebox{0.8\textwidth}{!}{%
+ \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|}
+ \hline
+ $MCC$ & $\mu O_{0}$ & $\mu O_{1}$ & $\mu O_{2}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{5}$ & $\mu O_{6}$ & $\mu O_{7}$ & $\mu O_{8}$ & $\mu O_{9}$ \\ \hline
+ $MCC_{0}$ & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ \hline
+ $MCC_{1}$ & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 \\ \hline
+ $MCC_{2}$ & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 \\ \hline
+ $MCC_{4}$ & 0 & 1 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 \\ \hline
+ $MCC_{5}$ & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ \hline
+ $MCC_{6}$ & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 1 \\ \hline
+ $MCC_{8}$ & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 \\ \hline
+ $MCC_{9}$ & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 \\ \hline
+ $MCC_{10}$ & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 0 \\ \hline
+ \end{tabular}%
+ }
+ \end{table}
+\end{frame}
+
+\begin{frame}
+ \frametitle{Solution - Essential compatible classes}
+ Select the essential compatible classes. In this case $MCC_{0}$ and $MCC_{6}$.
+ $S = \{MCC_{0}, MCC_{6}\}$.
+ % \begin{table}
+ % \resizebox{0.8\textwidth}{!}{%
+ % \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|}
+ % \hline
+ % $MCC$ & $\mu O_{0}$ & $\mu O_{1}$ & $\mu O_{2}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{5}$ & $\mu O_{6}$ & $\mu O_{7}$ & $\mu O_{8}$ & $\mu O_{9}$ \\ \hline
+ % $MCC_{1}$ & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 \\ \hline
+ % $MCC_{2}$ & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 \\ \hline
+ % $MCC_{4}$ & 0 & 1 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 \\ \hline
+ % $MCC_{5}$ & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ \hline
+ % $MCC_{8}$ & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 \\ \hline
+ % $MCC_{9}$ & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 \\ \hline
+ % $MCC_{10}$ & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 0 \\ \hline
+ % \end{tabular}%
+ % }
+ % \end{table}
+ \begin{table}
+ \resizebox{0.8\textwidth}{!}{%
+ \begin{tabular}{|c|c|c|c|c|c|c|}
+ \hline
+ $MCC$ & $\mu O_{1}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{6}$ & $\mu O_{8}$ \\ \hline
+ $MCC_{1}$ & 0 & 0 & 0 & 1 & 1 \\ \hline
+ $MCC_{2}$ & 0 & 0 & 0 & 0 & 0 \\ \hline
+ $MCC_{4}$ & 1 & 0 & 1 & 0 & 0 \\ \hline
+ $MCC_{5}$ & 1 & 0 & 0 & 1 & 0 \\ \hline
+ $MCC_{8}$ & 0 & 1 & 0 & 0 & 1 \\ \hline
+ $MCC_{9}$ & 0 & 1 & 0 & 0 & 0 \\ \hline
+ $MCC_{10}$ & 0 & 0 & 1 & 0 & 1 \\ \hline
+ \end{tabular}%
+ }
+ \end{table}
+ \note{
+ The essential compatible classes are the ones that contain a micro-operation that is not in any other compatible class.
+ Remove the essential compatible classes from the table and add them to the solution set.
+ }
+\end{frame}
+
+\begin{frame}
+ \frametitle{Solution - Remaining compatible classes}
+ $MCC_{2}$ and $MCC_{9}$ does not contain any micro-operation that is not in any other compatible class. So we can remove them from the table.
+ \begin{table}
+ \resizebox{0.8\textwidth}{!}{%
+ \begin{tabular}{|c|c|c|c|c|c|c|}
+ \hline
+ $MCC$ & $\mu O_{1}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{6}$ & $\mu O_{8}$ \\ \hline
+ $MCC_{1}$ & 0 & 0 & 0 & 1 & 1 \\ \hline
+ $MCC_{4}$ & 1 & 0 & 1 & 0 & 0 \\ \hline
+ $MCC_{5}$ & 1 & 0 & 0 & 1 & 0 \\ \hline
+ $MCC_{8}$ & 0 & 1 & 0 & 0 & 1 \\ \hline
+ $MCC_{10}$ & 0 & 0 & 1 & 0 & 1 \\ \hline
+ \end{tabular}%
+ }
+ \end{table}
+ This makes $MCC_{8}$ an essential compatible class. Remove it from the table and add it to the solution set.
+ $S = \{MCC_{0}, MCC_{6}, MCC_{8}\}$.
+\end{frame}
+
+\begin{frame}
+ \frametitle{Solution - Remaining compatible classes}
+ \begin{table}
+ \resizebox{0.8\textwidth}{!}{%
+ \begin{tabular}{|c|c|c|c|c|c|c|}
+ \hline
+ $MCC$ & $\mu O_{1}$ & $\mu O_{4}$ & $\mu O_{6}$ \\ \hline
+ $MCC_{1}$ & 0 & 0 & 1 \\ \hline
+ $MCC_{4}$ & 1 & 1 & 0 \\ \hline
+ $MCC_{5}$ & 1 & 0 & 1 \\ \hline
+ $MCC_{10}$ & 0 & 1 & 0 \\ \hline
+ \end{tabular}%
+ }
+ \end{table}
+ The possible additions solution sets are: $\{MCC_{1}, MCC_{4}\}$, $\{MCC_{4}, MCC_{5}\}$, $\{MCC_{5}, MCC_{10}\}$.
+ The possible sollution sets are: $\{MCC_{0}, MCC_{6}, MCC_{8}, MCC_{1}, MCC_{4}\}$, $\{MCC_{0}, MCC_{6}, MCC_{8}, MCC_{4}, MCC_{5}\}$, $\{MCC_{0}, MCC_{6}, MCC_{8}, MCC_{5}, MCC_{10}\}$.
+\end{frame}
+
+\begin{frame}
+ \frametitle{Solution - Minimal microinstruction coding}
+ The table with all micro operations and the selected compatible classes.
+ \begin{table}
+ \resizebox{0.8\textwidth}{!}{%
+ \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|c|}
+ \hline
+ $MCC$ & $\mu O_{0}$ & $\mu O_{1}$ & $\mu O_{2}$ & $\mu O_{3}$ & $\mu O_{4}$ & $\mu O_{5}$ & $\mu O_{6}$ & $\mu O_{7}$ & $\mu O_{8}$ & $\mu O_{9}$ & $|MCC|$ \\ \hline
+ $MCC_{0}$ & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 2\\ \hline
+ $MCC_{1}$ & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 3\\ \hline
+ $MCC_{4}$ & 0 & 1 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 3\\ \hline
+ $MCC_{5}$ & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 2\\ \hline
+ $MCC_{6}$ & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 3\\ \hline
+ $MCC_{8}$ & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 2\\ \hline
+ $MCC_{10}$ & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 2\\ \hline
+ \end{tabular}%
+ }
+ \end{table}
+ Order the maximum compatible classes in the solution set by their cardinality.
+\end{frame}
+
+
+\begin{frame}
+ \frametitle{Solution - Minimal microinstruction coding}
+ The cost for the solutions are:
+ \begin{itemize}
+ \item $C(S_{0}) = \{ (\mu O_{2}, \mu O_{7}, \mu O_{9}), (\mu O_{0}, \mu O_{6}, \mu O_{8}), (\mu O_{1}, \mu O_{4}), (\mu O_{3}), (\mu O_{5}) \} = 8$
+ \item $C(S_{1}) = \{ (\mu O_{2}, \mu O_{7}, \mu O_{9}), (\mu O_{0}, \mu O_{5}), (\mu O_{1}, \mu O_{6}), (\mu O_{8}, \mu O_{3}), (\mu O_{4}) \} = 9$
+ \item $C(S_{2}) = \{ (\mu O_{2}, \mu O_{7}, \mu O_{9}), (\mu O_{1}, \mu O_{6}), (\mu O_{0}, \mu O_{5}), (\mu O_{3}, \mu O_{8}), (\mu O_{4}) \} = 9$
+ \end{itemize}
+ The minimal microinstruction coding is $S_{0} = \{MCC_{0}, MCC_{6}, MCC_{8}, MCC_{1}, MCC_{4}\}$.
+\end{frame}
\ No newline at end of file
diff --git a/assignments/exam/multilevelcache/fetch.py b/assignments/exam/multilevelcache/fetch.py
new file mode 100644
index 00000000..afe13c2c
--- /dev/null
+++ b/assignments/exam/multilevelcache/fetch.py
@@ -0,0 +1,101 @@
+import sys, json, random, datetime
+args = {param.split('=')[0]: param.split('=')[1] for param in sys.argv[1:]}
+student_id = args['id']
+# TODO: change for EXAM
+secret = 0
+week=datetime.datetime.now().isocalendar()[0]
+random.seed(secret + week + int(student_id))
+
+def calculate_miss_penalty(access_time, block_size, byte_transfer_times):
+ return access_time + (block_size * byte_transfer_times)
+
+def calculate_amat(hit_time, miss_rate, miss_penalty):
+ return hit_time + (miss_rate * miss_penalty)
+
+
+# Define the possible values for the cache size, block size, cache mapping, and associativity
+cache_sizes_in_KBytes = [16, 32, 64, 128, 256, 512, 1024, 2048, 4096]
+block_sizes_in_bytes = [8, 16, 32, 64, 128, 256, 512, 1024]
+cache_mapping = ['direct', 'set-associative', 'fully-associative']
+associativities = [2, 4, 8]
+main_memory_access_times = [x * 10 for x in range(12, 20)]
+cache_hit_times = [x * 2 for x in range(3, 5)]
+main_memory_byte_transfer_times = [x * 4 for x in cache_hit_times]
+cache_miss_rates = [float(x)/100 for x in range(6, 10)]
+cache2_miss_rates = [float(x)/20 for x in range(8, 12)]
+
+
+# Randomly select one value from each list
+selected_cache_size = random.choice(cache_sizes_in_KBytes)
+selected_block_size = random.choice(block_sizes_in_bytes)
+selected_cache_mapping = 'direct'
+selected_main_memory_access_time = random.choice(main_memory_access_times)
+selected_cache_hit_time = random.choice(cache_hit_times)
+selected_main_memory_byte_transfer_time = random.choice(main_memory_byte_transfer_times)
+selected_cache_miss_rate = random.choice(cache_miss_rates)
+
+# select values for a modified cache in associativity
+selected_new_cache_mapping = 'set-associative'
+selected_new_associativity = random.choice(associativities)
+selected_new_cache_hit_time = selected_cache_hit_time * random.choice([5, 6, 7, 8])
+selected_new_cache_miss_rate = random.choice(cache2_miss_rates)
+selected_new_block_size = selected_block_size
+selected_new_cache_size = selected_cache_size * 16
+
+initial_miss_penalty = calculate_miss_penalty(selected_main_memory_access_time, selected_block_size, selected_main_memory_byte_transfer_time)
+initial_amat = calculate_amat(selected_cache_hit_time, selected_cache_miss_rate, initial_miss_penalty)
+cache2_miss_penalty = calculate_miss_penalty(selected_main_memory_access_time, selected_new_block_size, selected_main_memory_byte_transfer_time)
+cache2_amat = calculate_amat(selected_new_cache_hit_time, selected_new_cache_miss_rate, cache2_miss_penalty)
+new_miss_penalty = cache2_amat
+new_amat = calculate_amat(selected_cache_hit_time, selected_cache_miss_rate, new_miss_penalty)
+speedup = initial_amat / new_amat
+
+selected_new_cache_mapping = str(selected_new_associativity) + '-way set-associative'
+
+# generate the html question
+question = """
+
+
We have a cache system with the following characteristics:
+
+ - One level cache
+ - Main memory access time: {}
+ - Main memory byte transfer time: {}
+ - Cache hit time: {}
+ - Cache miss rate: {}%
+ - Cache block size: {} bytes
+ - Cache size: {} KB
+ - Cache Mapping: {}
+
+
What is the speedup in average memory access time (AMAT) if we add a second-level cache with the following characteristics:
+
+ - Cache hit time: {}
+ - Cache miss rate: {}%
+ - Cache block size: {} bytes
+ - Cache size: {} KB
+ - Cache Mapping: {}
+
+
+""".format(
+ selected_main_memory_access_time,
+ selected_main_memory_byte_transfer_time,
+ selected_cache_hit_time,
+ selected_cache_miss_rate * 100,
+ selected_block_size,
+ selected_cache_size,
+ selected_cache_mapping,
+ selected_new_cache_hit_time,
+ selected_new_cache_miss_rate * 100,
+ selected_new_block_size,
+ selected_new_cache_size,
+ selected_new_cache_mapping
+)
+
+# Print the selected values
+print(
+ json.dumps(
+ {
+ 'question': question,
+ 'result': speedup
+ }
+ )
+)
diff --git a/assignments/exam/multilevelcache/sol.tex b/assignments/exam/multilevelcache/sol.tex
new file mode 100644
index 00000000..2ba33e30
--- /dev/null
+++ b/assignments/exam/multilevelcache/sol.tex
@@ -0,0 +1,76 @@
+\textbf{Problem}
+We have a cache with the following characteristics:
+\begin{itemize}
+ \item Only one cache level
+ \item Main memory access time: 170 cycles $L_{MM}=170$
+ \item Main memory byte transfer time: 24 cycles $BT_{MM}=24$
+ \item Cache hit time: 6 cycle $H_{C}=6$
+ \item Cache miss rate: 8\% $MR_{C}=0.08$
+ \item Cache block size: 256 bytes $BS_{C}=256$
+ \item Cache size: 32 KB $S_{C}=32 \times 1024$
+ \item Cache is Direct Mapped
+\end{itemize}
+
+What is the speedup in average memory access time (AMAT) if we add a second cache level with the following characteristics:
+\begin{itemize}
+ \item Cache hit time: 36 cycle $H_{C2}=36$
+ \item Cache miss rate: 40\% $MR_{C2}=0.40$
+ \item Cache block size: 256 bytes $BS_{C2}=256$
+ \item Cache size: 512 KB $S_{C2}=512 \times 1024$
+ \item Cache is 2-way set associative
+ \item The second cache is accessed only if the first cache misses
+\end{itemize}
+
+\textbf{Solution}
+To calculate the speedup in AMAT, we need to determine the AMAT before and after adding the second cache level and then compute the speedup.
+
+1. Calculate the initial miss penalty:
+\[
+\text{Initial miss penalty} = L_{MM} + BS_{C} \times BT_{MM}
+\]
+\[
+\text{Initial miss penalty} = 170 \text{ cycles} + 256 \text{ bytes} \times 24 \text{ cycles/byte} = 170 + 6144 = 6314 \text{ cycles}
+\]
+
+2. Calculate the initial AMAT:
+\[
+\text{Initial AMAT} = H_{C} + (MR_{C} \times \text{Initial miss penalty})
+\]
+\[
+\text{Initial AMAT} = 6 \text{ cycles} + (0.08 \times 6314 \text{ cycles}) = 6 + 505.12 = 511.12 \text{ cycles}
+\]
+
+3. Calculate the miss penalty for the second cache level:
+\[
+\text{C2 miss penalty} = L_{MM} + BS_{C2} \times BT_{MM}
+\]
+\[
+\text{C2 miss penalty} = 170 \text{ cycles} + 256 \text{ bytes} \times 24 \text{ cycles/byte} = 170 + 6144 = 6314 \text{ cycles}
+\]
+
+4. Calculate the AMAT for the second cache level:
+\[
+\text{C2 AMAT} = H_{C2} + (MR_{C2} \times \text{C2 miss penalty})
+\]
+\[
+\text{C2 AMAT} = 36 \text{ cycles} + (0.40 \times 6314 \text{ cycles}) = 36 + 2525.6 = 2561.6 \text{ cycles}
+\]
+
+5. Calculate the new AMAT considering both cache levels:
+\[
+\text{New AMAT} = H_{C} + (MR_{C} \times \text{C2 AMAT})
+\]
+\[
+\text{New AMAT} = 6 \text{ cycles} + (0.08 \times 2561.6 \text{ cycles}) = 6 + 204.928 = 210.928 \text{ cycles}
+\]
+
+6. Calculate the speedup:
+\[
+\text{Speedup} = \frac{\text{Initial AMAT}}{\text{New AMAT}}
+\]
+\[
+\text{Speedup} = \frac{511.12 \text{ cycles}}{210.928 \text{ cycles}} \approx 2.42
+\]
+
+
+Therefore, the speedup in average memory access time (AMAT) when adding a second cache level is approximately 2.42.
diff --git a/assignments/exam/uart/fetch.py b/assignments/exam/uart/fetch.py
new file mode 100644
index 00000000..84f0b224
--- /dev/null
+++ b/assignments/exam/uart/fetch.py
@@ -0,0 +1,76 @@
+import sys, json, random, datetime
+args = {param.split('=')[0]: param.split('=')[1] for param in sys.argv[1:]}
+student_id = args['id']
+# TODO: change for EXAM
+secret = 0
+week=datetime.datetime.now().isocalendar()[0]
+random.seed(secret + week + int(student_id))
+
+
+def calculate_max_data_rate(baud_rate, data_bits, stop_bits, parity_bits):
+ # Calculate the total bits per frame
+ total_bits_per_frame = 1 + data_bits + parity_bits + stop_bits
+
+ # Calculate the maximum data rate
+ max_data_rate = (baud_rate * data_bits) / total_bits_per_frame
+
+ return max_data_rate
+
+# Given UART configuration
+
+baud_rates = [4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600]
+data_bits_set = [5, 6, 7, 8]
+stop_bits_set = [1, 2]
+parity_bits_set = [0, 1] # None, or [Odd, Even]
+
+baud_rate = random.choice(baud_rates)
+data_bits = random.choice(data_bits_set)
+stop_bits = random.choice(stop_bits_set)
+parity_bits = random.choice(parity_bits_set)
+
+# Calculate the maximum data rate
+max_data_rate = calculate_max_data_rate(baud_rate, data_bits, stop_bits, parity_bits)
+
+# Make a html table from the UART configuration
+uart_configuration_table = """
+
+
+"""
+uart_configuration_table += "Parameter | Value |
\n"
+uart_configuration_table += "Baud Rate | {} |
".format(baud_rate)
+uart_configuration_table += "Data Bits | {} |
".format(data_bits)
+uart_configuration_table += "Stop Bits | {} |
".format(stop_bits)
+if parity_bits == 0:
+ uart_configuration_table += "Parity Bits | None |
"
+else:
+ uart_configuration_table += "Parity Bits | 1 |
"
+uart_configuration_table += "
"
+
+# generate question in html format
+question = """
+
+
Having the following UART configuration, what is the maximum data rate that can be achieved?
+
+
+
UART configurations:
+ {}
+
+""".format(uart_configuration_table)
+
+print(
+ json.dumps(
+ {
+ "question": question,
+ "result": max_data_rate
+ }
+ )
+)
\ No newline at end of file
diff --git a/assignments/exam/uart/sol.tex b/assignments/exam/uart/sol.tex
new file mode 100644
index 00000000..e1c82565
--- /dev/null
+++ b/assignments/exam/uart/sol.tex
@@ -0,0 +1,46 @@
+\section*{Problem}
+Having the following UART configuration, what is the maximum data rate that can be achieved?
+\begin{itemize}
+ \item Baud rate: 115200
+ \item Data bits: 8
+ \item Stop bits: 1
+ \item Parity: None
+ \item Flow control: None
+\end{itemize}
+
+\section*{Solution}
+To determine the maximum data rate that can be achieved with the given UART configuration, we need to consider the baud rate and the number of bits transmitted per frame.
+
+1. Baud Rate:
+\[
+\text{Baud rate} = 115200 \text{ bits per second (bps)}
+\]
+
+2. Frame Structure:
+\begin{itemize}
+ \item Data bits: 8
+ \item Stop bits: 1
+ \item Parity bit: None
+\end{itemize}
+
+Each frame consists of:
+\[
+\text{Total bits per frame} = \text{Start bit} + \text{Data bits} + \text{Parity bit} + \text{Stop bits}
+\]
+\[
+\text{Total bits per frame} = 1 + 8 + 0 + 1 = 10 \text{ bits}
+\]
+
+3. Maximum Data Rate:
+The maximum data rate is determined by the number of data bits transmitted per second. Given the baud rate and the frame structure:
+\[
+\text{Maximum data rate} = \frac{\text{Baud rate} \times \text{Data bits}}{\text{Total bits per frame}}
+\]
+\[
+\text{Maximum data rate} = \frac{115200 \times 8}{10} = 92160 \text{ bps}
+\]
+
+Therefore, the maximum data rate that can be achieved with the given UART configuration is:
+\[
+92160 \text{ bits per second (bps)}
+\]
diff --git a/slides/courses/10/bachelor.tex b/slides/courses/10/bachelor.tex
new file mode 100644
index 00000000..0721705f
--- /dev/null
+++ b/slides/courses/10/bachelor.tex
@@ -0,0 +1,144 @@
+\begin{frame}
+\frametitle{Bachelor Degree}
+\begin{itemize}
+ \item The bachelor's degree is obtained after 4 years of study.
+ \item The bachelor's degree is obtained after 240 credits.
+ \item The bachelor's degree is obtained after defending the bachelor's thesis.
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{What is the bachelor's thesis?}
+The bachelor's thesis is a project that you need to do in the last year of study.
+
+You need to:
+\begin{itemize}
+ \item Choose a professor who will guide you.
+ \item Choose a theme and then a topic.
+ \item Implement the project.
+ \item Write 30-40 pages of documentation.
+ \item Present your work in front of a commission.
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{Bachelor thesis - How to choose a topic?}
+ Choose a topic that you would like to do. (you will work on it for at least 6 months)
+ \begin{itemize}
+ \item Your passion.
+ \item Your hobby.
+ \item Your favorite theme in the faculty.
+ \item Your favorite professor.
+ \end{itemize}
+\end{frame}
+
+\begin{frame}
+ \frametitle{Bachelor thesis - How to choose a topic?}
+ \begin{itemize}
+ \item Choose a topic that you will be proud of. (The only thing that will remain after you leave the university)
+ \item Choose a topic that you will be able to finish.
+ \item To increase your chances of getting into a master's program, choose a topic that is related to the master's program or conclude with a paper.
+ \item If you work in a company, choose a topic from the company.
+ \end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{Bachelor thesis - How to choose a professor?}
+\begin{itemize}
+ \item Choose a professor that you like.
+ \item Asked older students about the professors.
+ \item Choose a professor that is related to the topic.
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{Bachelor thesis - Where to find a topic?}
+\begin{itemize}
+ \item Choose from the university's site at \url{https://connect.upb.ro/propuneri}.
+ \item Go to the professors and propose a topic.
+ \item Go to the companies and propose a topic or get one from them.
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{Bachelor thesis - Extra}
+\begin{itemize}
+ \item You can do the bachelor thesis in a team of students depending on the complexity.
+ \item You can do the bachelor thesis with Erasmus+ internships.
+ \item You can do the bachelor's thesis with any professor from the university or friendly university.
+ \item Try to stay close to your domain of study. The commission at the end is formed from professors from your domain.
+ \item You can write in English or Romanian.
+ \item You can use any programming language or any tool.
+ \item \textbf{You can do the bachelor thesis during the summer practice.}
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{My proposals for bachelor thesis - Blockchain}
+\begin{itemize}
+ \item CuEVM - A new EVM implementation in cuda for Ethereum to run on GPUs. (Minh Ho (NUS))
+ \item MECAnywhere - A cloud service through blockchain for using underused computational resources.
+ \item Post Quantum Blockchain - A blockchain that uses post quantum cryptography.
+ \item Post Quantum Wallet - A wallet that uses post quantum cryptography.
+ \item Post Quantum ID - A blockchain based ID that uses post quantum cryptography. (Ioan Stan (Bitdefender))
+ \item Blockchain High School Platform - A platform for high schools over blockchain for their websites. (Andreea Dobrita (SNSPA))
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{My proposals for bachelor thesis - Quantum Networks and Quantum Computing}
+\begin{itemize}
+ \item Quantum Key Distribution Application - An application that uses QKD for secure communication. (Alin Popa)
+ \item Quantum Entanglement Network Simulator - A simulator for quantum entanglement networks. (Bogdan Ciobanu)
+ \item Quantum Leader Election Benchmark - A benchmark for quantum leader election algorithms. (Daniel Lee (NUS))
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{My proposals for bachelor thesis - Number Representation Systems}
+\begin{itemize}
+ \item Number Representation Systems Software Library (NRS-SL) - A library that implements all number representation systems.
+ \item Number Representation Systems Hardware Library (NRS-HL) - A library that implements all number representation systems in hardware.
+ \item Number Representation Systems Benchmark - A benchmark for number representation systems.
+ \item Audio/Video Compression and Editing using different Number Representation Systems. (Andrei Trasca)
+ \item Artificial intelligence using different Number Representation Systems. (Teodor Neacsu)
+ \item Statistics Analysis using different Number Representation Systems. (Ebru Resul (Keysight))
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{My proposals for bachelor thesis - Computer Architecture}
+\begin{itemize}
+ \item Microcod pipelined RISC-V - A microcode implementation for RISC-V in Verilog. (Nicolae Tapus)
+ \item RISC-V simulator - A simulator for RISC-V. (Nicolae Tapus)
+ \item Cold-Wallet - A hardware wallet for cryptocurrencies. (Rares Ifrim)
+ \item RISC-V Zero-Knowledge Proof - A Zero-Knowledge Proof for RISC-V. (Rares Ifrim)
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{My proposals for bachelor thesis - Robotics and Automotive}
+\begin{itemize}
+ \item Formula Student - A project for the Formula Student competition. (Alexandru Vaduva (Siemens))
+ \item Automotive Security Emulator - An emulator for automotive security. (Alexandru Vaduva (Siemens))
+ \item RONIN - A project to build robots. (Daniel Rosner)
+ \item Humanoid Robots - Use humanoid robots in interaction with humans. (Adriana Tapus (IPP - ParisTech))
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{Proposals for bachelor thesis - Not related to my interests}
+\begin{itemize}
+ \item Healthcare (Flavia Oprea)
+ \item Contests Platform (Stefan Avram (Keysight/Acadnet))
+ \item Federated Learning (Dan Badea (Bitdefender Ambassador))
+ \item Machine Learning Security (Damian Monea (Crowdstrike))
+ \item Machine Learning Privacy (Teodora Baluta (Georgia Tech)/Ana Maria Cretu (ETH))
+ \item Formal Verification (Andreea Costea (Delft))
+ \item Ethical Hacking (Florin Stancu / Radu Mantu / Mihai Chiroiu)
+ \item Rust Programming Language (Alexandru Radovici (OxidOS))
+ \item Computer Vision (Emilian Radoi)
+ \item Natural Language Processing (Mihai Dascalu)
+ \item Privacy Technologies (Razvan Rughinis)
+\end{itemize}
+\end{frame}
\ No newline at end of file
diff --git a/slides/courses/10/main.tex b/slides/courses/10/main.tex
new file mode 100644
index 00000000..247631a4
--- /dev/null
+++ b/slides/courses/10/main.tex
@@ -0,0 +1,117 @@
+%\documentclass[notes,usenames,dvipsnames]{beamer}
+%\documentclass[notes]{beamer} % print frame + notes
+%\documentclass[notes=only]{beamer} % only notes
+\documentclass[usenames,dvipsnames]{beamer} % only frames
+\usepackage[outputdir=out]{minted}
+\usepackage{pgfpages}
+%\setbeameroption{show notes on second screen}
+%\setbeameroption{show notes}
+%subfigures
+\usepackage{caption}
+\usepackage{subcaption}
+
+%tables packages
+\usepackage{multirow}
+
+% math
+\usepackage{amsmath}
+
+% bash command
+\usepackage{graphicx}
+\usepackage{listings}
+% varbatim for ascii figures
+\usepackage[T1]{fontenc}
+\usepackage[utf8]{inputenc}
+%\usepackage{verbatim}
+\usepackage{lipsum} % for context
+\usepackage{fancyvrb}
+\usepackage{varwidth}
+\usepackage{circuitikz}
+\ctikzset{logic ports=ieee}
+\usepackage{listings}
+% \lstset{language=[Motorola68k]Assembler,basicstyle=\ttfamily,keywordstyle=\color{blue}}
+
+\usepackage{shellesc}
+\usepackage{adjustbox}
+\usepackage{hyperref}
+
+\newsavebox{\asciigcn}
+
+% notes prefixed in pympress
+\addtobeamertemplate{note page}{}{\thispdfpagelabel{notes:\insertframenumber}}
+%theme used
+\usetheme{Madrid}
+%Information to be included in the title page:
+\title[Computer Architecture] %optional
+{Computer Architecture}
+
+\subtitle{Course no. 10 - Summer Practice, Bachelor's Degree, Mobility Programs}
+
+\author[Ștefan-Dan Ciocîrlan] % (optional, for multiple authors)
+{}
+
+\institute[NUSTPB] % (optional)
+{
+ \inst{}%
+ National University of Science and Technology\\
+ POLITEHNICA Bucharest
+}
+
+\date[NUSTPB 2024] % (optional)
+{Computer Architecture}
+
+\logo{
+\includegraphics[height=0.9cm]{../../media/LOGO_UNSTPB_en.png}
+\includegraphics[height=0.9cm]{../../media/logoACSQ.jpeg}
+}
+
+
+% Roman numerals
+\newcommand*{\rom}[1]{\expandafter\@slowromancap\romannumeral #1@}
+%split
+\usepackage{amsmath}
+%colors
+%\usepackage[usenames,dvipsnames]{color} %loaded by the dcoument class
+%subfigure
+\usepackage{subcaption}
+% block over block uncover
+\setbeamercovered{invisible}
+%\setbeamercovered{transparent}
+
+%extra slide content
+\AtBeginSection[]
+{
+ \begin{frame}
+ \frametitle{Content}
+ \tableofcontents[currentsection]
+ \end{frame}
+}
+%notes or not
+%\setbeamertemplate{note page}[plain]
+
+\begin{document}
+
+\frame{\titlepage}
+
+\section{Summer Practice}
+\input{practice.tex}
+
+\section{Bachelor Degree}
+\input{bachelor.tex}
+
+\section{Mobility programs}
+\input{mobility.tex}
+
+
+
+\section{Q\&A}
+\begin{frame}
+\end{frame}
+
+%\begin{frame}
+%\frametitle{Table of Contents}
+%\tableofcontents
+%\end{frame}
+
+
+\end{document}
\ No newline at end of file
diff --git a/slides/courses/10/mobility.tex b/slides/courses/10/mobility.tex
new file mode 100644
index 00000000..4d14c2ee
--- /dev/null
+++ b/slides/courses/10/mobility.tex
@@ -0,0 +1,73 @@
+\begin{frame}
+\frametitle{Mobility programs}
+\begin{itemize}
+ \item \href{https://acs.pub.ro/parteneriate/relatii-internationale/acorduri-erasmus/}{Erasmus Opportunities}.
+ \item \href{https://acs.pub.ro/public/21-27-Mobilitate-Studiu-Eplus-UNIVERSITATI-PARTENERE-septembrie-2024.pdf}{Universities List}.
+ \item \href{https://upb.ro/concurs-granturi-erasmus/}{Foreign Language Exams}.
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{Documents}
+\begin{itemize}
+ \item Language certificate or Foreign Language Exam in UNSTPB.
+ \item CV.
+ \item Motivation letter.
+ \item Transcript of records.
+ \item ID card.
+ \item Diploma/Awards (optional).
+ \item GPA.
+ \item \href{https://acs.pub.ro/public/Regulament_Mobilitati_ERASMUS_2024.pdf}{Erasmus UNSTPB Regulation}.
+ \item ASC Contest.
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{Type of mobilities}
+\begin{itemize}
+ \item Study (607/674/707) vs Placement (2 to 4 months 756/824/+250) vs Study-Placement mobilities.
+ \item Short-term (5 to 30 days) vs Long-term mobility (2 to 10 months).
+ \item Travel grant and green travel grant (train/bus/shared car).
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+ \frametitle{Rank of the Universities - R1}
+ \begin{itemize}
+ \item Universitat Politecnica de Catalunya + Universidad Politecnica de Madrid (Spain)
+ \item Ecole Normale Superieure de Cachan (ENS Cachan) + Universite Paris-Saclay (ParisTech) (France)
+ \item Technische Universitat Wien (Austria)
+ \item Universidade Nova de Lisboa (Portugal)
+ \item Technische Universiteit Eindhoven + University of Twente (Netherlands)
+ \item Technische Universitat Ilmenau (Germany)
+ \item Aarhus University (Denmark)
+ \item Istanbul Gelisim Universitesi (Turkey)
+ \item Universita degli Studi di Roma "La Sapienza" + University of Padua (Italy)
+ \item University of Nicosia (Cyprus)
+ \end{itemize}
+\end{frame}
+
+\begin{frame}
+ \frametitle{Rank of the Universities - R2}
+ \begin{itemize}
+ \item Institut National Polytechnique de Grenoble + Universite de Strasbourg + Sorbonne Universite (France)
+ \item Universite de Mons (Belgium)
+ \item Warsaw University of Technology (Poland)
+ \item Universita degli Studi di Torino + Universita degli Studi di Milano-Bicocca (Italy)
+ \item Universidade do Porto (Portugal)
+ \item Universidad de Sevilla (Spain)
+ \item Abo Akademi Universit (Finland)
+ \item Budapest University of Technology and Economics (Hungary)
+ \end{itemize}
+\end{frame}
+
+\begin{frame}
+ \frametitle{Extra}
+ \begin{itemize}
+ \item Erasmus placements for summer practice and bachelor's thesis.
+ \item Erasmus placements for relaxing.
+ \end{itemize}
+\end{frame}
+
+
+
diff --git a/slides/courses/10/practice.tex b/slides/courses/10/practice.tex
new file mode 100644
index 00000000..2a5f826f
--- /dev/null
+++ b/slides/courses/10/practice.tex
@@ -0,0 +1,40 @@
+\begin{frame}
+\frametitle{Summer Practice}
+\begin{itemize}
+ \item The summer practice is a mandatory activity for all students.
+ \item It needs to take 360 hours (45 working days) between 22th of June and 7th of September (last year).
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{Where can I do my summer practice?}
+\begin{enumerate}
+ \item Companies who have an agreement with the university.
+ \item International companies who don't have an agreement with the university.
+ \item Research projects with professors.
+ \item Summer schools.
+ \item Erasmus+ internships.
+ \item Companies who don't have an agreement with the university.
+\end{enumerate}
+\end{frame}
+
+\begin{frame}
+\frametitle{How to find a place for the summer practice?}
+\begin{itemize}
+ \item From the university's site at \url{https://connect.upb.ro/}.
+ \item Erasmus+ internships have open calls \url{https://upb.ro/erasmus/mobilitate-de-plasament-upb/}.
+ \item Stagii pe bune \url{https://www.stagiipebune.ro/}.
+ \item You can find a company by yourself. (international \url{https://leetcode.com/})
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{Necessary documents}
+\begin{itemize}
+ \item \url{https://acs.pub.ro/studenti/stagii-de-practica/}
+ \item Convenție Cadru (company) sau Portofoliu de practică (research project).
+ \item Caiet de practică. (what you did)
+ \item Atestat / adeverința de practică. (evaluation)
+ \item Protocol of collaboration between the university and the company.
+\end{itemize}
+\end{frame}