├── .gitattributes ├── .gitignore ├── README.md ├── lab00 ├── code.py ├── gen-debug.sh └── init.sh ├── lab01 ├── exercise1 │ ├── ex1.c │ ├── ex1.h │ └── test_ex1.c ├── exercise2 │ ├── pwd_checker.c │ ├── pwd_checker.h │ └── test_pwd_checker.c ├── exercise3 │ ├── linked_list.c │ ├── linked_list.h │ └── test_linked_list.c └── exercise4 │ ├── ll_cycle.c │ ├── ll_cycle.h │ └── test_ll_cycle.c ├── lab02 ├── .gitignore ├── Makefile ├── bit_ops.c ├── bit_ops.h ├── linked_list.c ├── linked_list.h ├── test_bit_ops.c ├── test_linked_list.c ├── test_vector.c ├── vector.c └── vector.h ├── lab03 ├── ex3.c ├── ex3.s ├── factorial.s ├── fib.c ├── fib.s └── list_map.s ├── lab04 ├── cc_test.s ├── discrete_fn.s └── megalistmanips.s ├── lab05 ├── .gitattributes ├── .gitignore ├── ex2.circ ├── ex3.circ ├── ex4.circ ├── test.py └── tests │ ├── ex2-test.circ │ ├── ex3-test.circ │ ├── ex4-test.circ │ └── reference-output │ ├── ex2-test.out │ ├── ex3-test.out │ └── ex4-test.out ├── lab06 ├── .gitattributes ├── .gitignore ├── ex1.circ ├── ex2.circ ├── ex3.circ ├── ex3.txt ├── ex4.circ ├── ex4.txt ├── test.py └── tests │ ├── ex1-test.circ │ ├── ex2-test.circ │ ├── ex4-test.circ │ └── reference-output │ ├── ex1-test.out │ ├── ex2-test.out │ └── ex4-test.out ├── lab07 ├── Makefile ├── cache.s ├── matrixMultiply.c ├── test_transpose.c ├── transpose.c └── transpose.h ├── lab08 ├── Makefile ├── simd.c ├── simd.h └── test_simd.c ├── lab09 ├── Makefile ├── dotp.c ├── hello.c ├── omp_apps.c ├── omp_apps.h └── v_add.c └── tools ├── logisim-evolution.jar └── venus.jar /.gitattributes: -------------------------------------------------------------------------------- 1 | *.c text eol=lf 2 | *.circ text eol=lf 3 | *.h text eol=lf 4 | *.md text eol=lf 5 | *.s text eol=lf 6 | *.sh text eol=lf 7 | *.txt text eol=lf 8 | Makefile text eol=lf 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | # *.out 34 | a.out 35 | *.app 36 | *.i*86 37 | *.x86_64 38 | *.hex 39 | 40 | # Debug files 41 | *.dSYM/ 42 | *.su 43 | *.idb 44 | *.pdb 45 | vgcore.* 46 | 47 | # Kernel Module Compile Results 48 | *.mod* 49 | *.cmd 50 | .tmp_versions/ 51 | modules.order 52 | Module.symvers 53 | Mkfile.old 54 | dkms.conf 55 | 56 | # Byte-compiled / optimized / DLL files 57 | __pycache__/ 58 | *.py[cod] 59 | *$py.class 60 | 61 | # C extensions 62 | *.so 63 | 64 | # Distribution / packaging 65 | .Python 66 | build/ 67 | develop-eggs/ 68 | dist/ 69 | downloads/ 70 | eggs/ 71 | .eggs/ 72 | lib/ 73 | lib64/ 74 | parts/ 75 | sdist/ 76 | var/ 77 | wheels/ 78 | pip-wheel-metadata/ 79 | share/python-wheels/ 80 | *.egg-info/ 81 | .installed.cfg 82 | *.egg 83 | MANIFEST 84 | 85 | # PyInstaller 86 | # Usually these files are written by a python script from a template 87 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 88 | *.manifest 89 | *.spec 90 | 91 | # Installer logs 92 | pip-log.txt 93 | pip-delete-this-directory.txt 94 | 95 | # Unit test / coverage reports 96 | htmlcov/ 97 | .tox/ 98 | .nox/ 99 | .coverage 100 | .coverage.* 101 | .cache 102 | nosetests.xml 103 | coverage.xml 104 | *.cover 105 | *.py,cover 106 | .hypothesis/ 107 | .pytest_cache/ 108 | 109 | # Translations 110 | *.mo 111 | *.pot 112 | 113 | # Django stuff: 114 | *.log 115 | local_settings.py 116 | db.sqlite3 117 | db.sqlite3-journal 118 | 119 | # Flask stuff: 120 | instance/ 121 | .webassets-cache 122 | 123 | # Scrapy stuff: 124 | .scrapy 125 | 126 | # Sphinx documentation 127 | docs/_build/ 128 | 129 | # PyBuilder 130 | target/ 131 | 132 | # Jupyter Notebook 133 | .ipynb_checkpoints 134 | 135 | # IPython 136 | profile_default/ 137 | ipython_config.py 138 | 139 | # pyenv 140 | .python-version 141 | 142 | # pipenv 143 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 144 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 145 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 146 | # install all needed dependencies. 147 | #Pipfile.lock 148 | 149 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 150 | __pypackages__/ 151 | 152 | # Celery stuff 153 | celerybeat-schedule 154 | celerybeat.pid 155 | 156 | # SageMath parsed files 157 | *.sage.py 158 | 159 | # Environments 160 | .env 161 | .venv 162 | env/ 163 | venv/ 164 | ENV/ 165 | env.bak/ 166 | venv.bak/ 167 | 168 | # Spyder project settings 169 | .spyderproject 170 | .spyproject 171 | 172 | # Rope project settings 173 | .ropeproject 174 | 175 | # mkdocs documentation 176 | /site 177 | 178 | # mypy 179 | .mypy_cache/ 180 | .dmypy.json 181 | dmypy.json 182 | 183 | # Pyre type checker 184 | .pyre/ 185 | 186 | # General 187 | .DS_Store 188 | .AppleDouble 189 | .LSOverride 190 | 191 | # Icon must end with two \r 192 | Icon 193 | 194 | # Thumbnails 195 | ._* 196 | 197 | # Files that might appear in the root of a volume 198 | .DocumentRevisions-V100 199 | .fseventsd 200 | .Spotlight-V100 201 | .TemporaryItems 202 | .Trashes 203 | .VolumeIcon.icns 204 | .com.apple.timemachine.donotpresent 205 | 206 | # Directories potentially created on remote AFP share 207 | .AppleDB 208 | .AppleDesktop 209 | Network Trash Folder 210 | Temporary Items 211 | .apdisk 212 | 213 | # Windows thumbnail cache files 214 | Thumbs.db 215 | Thumbs.db:encryptable 216 | ehthumbs.db 217 | ehthumbs_vista.db 218 | 219 | # Dump file 220 | *.stackdump 221 | 222 | # Folder config file 223 | [Dd]esktop.ini 224 | 225 | # Recycle Bin used on file shares 226 | $RECYCLE.BIN/ 227 | 228 | # Windows Installer files 229 | *.cab 230 | *.msi 231 | *.msix 232 | *.msm 233 | *.msp 234 | 235 | # Windows shortcuts 236 | *.lnk 237 | 238 | *~ 239 | 240 | # temporary files which can be created if a process still has a handle open of a deleted file 241 | .fuse_hidden* 242 | 243 | # KDE directory preferences 244 | .directory 245 | 246 | # Linux trash folder which might appear on any partition or disk 247 | .Trash-* 248 | 249 | # .nfs files are created when an open file is removed but is still being accessed 250 | .nfs* 251 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sp22-lab 2 | -------------------------------------------------------------------------------- /lab00/code.py: -------------------------------------------------------------------------------- 1 | def get_airspeed_velocity_of(unladen_swallow): 2 | if unladen_swallow.type == "african": 3 | return # redacted 4 | elif unladen_swallow.type == "european": 5 | return # redacted 6 | 7 | def fizzbuzz(num): 8 | if num == 3: # edit this line 9 | print(f"{num}: fizz") 10 | if num == 5: # edit this line 11 | print(f"{num}: buzz") 12 | 13 | for i in range(1, 20): 14 | fizzbuzz(i) 15 | -------------------------------------------------------------------------------- /lab00/gen-debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "OSTYPE='$OSTYPE'" > debug.txt 4 | echo "SH_VERSION='$(sh --version 2>&1 | cat)'" >> debug.txt 5 | echo "GIT_VERSION='$(git --version 2>&1 | cat)'" >> debug.txt 6 | echo "PYTHON3_VERSION='$(python3 --version 2>&1 | cat)'" >> debug.txt 7 | echo "PYTHON_VERSION='$(python --version 2>&1 | cat)'" >> debug.txt 8 | echo "PY_VERSION='$(py --version 2>&1 | cat)'" >> debug.txt 9 | echo "GCC_VERSION='$(gcc --version 2>&1 | cat)'" >> debug.txt 10 | echo "JAVA_VERSION='$(java -version 2>&1 | cat)'" >> debug.txt 11 | -------------------------------------------------------------------------------- /lab00/init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | lab00_ref="starter/lab00-oski" 5 | 6 | git fetch starter 7 | 8 | lab00_start_ref="$(git rev-parse "${lab00_ref}~1")" 9 | 10 | git push -f origin "HEAD:lab00-backup" 11 | git reset --hard "$lab00_start_ref" 12 | git push -f origin "${lab00_ref}:main" 13 | git update-ref refs/remotes/origin/main "$lab00_start_ref" "$lab00_ref" 14 | 15 | echo "Finished setup" 16 | -------------------------------------------------------------------------------- /lab01/exercise1/ex1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ex1.h" 3 | 4 | /* Returns the number of times LETTER appears in STR. 5 | There are two different ways to iterate through a string. 6 | 1st way hint: strlen() may be useful 7 | 2nd way hint: all strings end in a null terminator */ 8 | int num_occurrences(char *str, char letter) { 9 | /* TODO: implement num_occurances */ 10 | return 0; 11 | } 12 | 13 | /* Populates DNA_SEQ with the number of times each nucleotide appears. 14 | Each sequence will end with a NULL terminator and will have up to 20 nucleotides. 15 | All letters will be upper case. */ 16 | void compute_nucleotide_occurrences(DNA_sequence *dna_seq) { 17 | /* TODO: implement compute_nucleotide_occurances */ 18 | return; 19 | } 20 | -------------------------------------------------------------------------------- /lab01/exercise1/ex1.h: -------------------------------------------------------------------------------- 1 | #ifndef EX_1_H 2 | #define EX_1_H 3 | 4 | typedef struct DNA_sequence { 5 | char sequence [21]; 6 | int A_count; 7 | int C_count; 8 | int G_count; 9 | int T_count; 10 | } DNA_sequence; 11 | 12 | int num_occurrences(char *str, char letter); 13 | void compute_nucleotide_occurrences(DNA_sequence *dna_seq); 14 | 15 | #endif //EX_1_H 16 | -------------------------------------------------------------------------------- /lab01/exercise1/test_ex1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "ex1.h" 5 | 6 | int main(int argc, char **argv) { 7 | printf("Running tests...\n\n"); 8 | /************ Part 1 Test Cases ************/ 9 | char *str = "hello world!"; 10 | 11 | int num_l = num_occurrences(str, 'l'); 12 | assert(num_l == 3); 13 | 14 | int num_z = num_occurrences(str, 'z'); 15 | assert(num_z == 0); 16 | 17 | /* TODO: Think of a scenario that is not tested by the current test cases. Create one additional test case to test this scenario. */ 18 | 19 | printf("Congrats! If you have made it to this line, your Part 1 Test cases are all passing!\n"); 20 | 21 | /************ Part 2 Test Cases ************/ 22 | DNA_sequence dna_seq_1; 23 | strcpy(dna_seq_1.sequence, "ACTTTGAAC"); 24 | compute_nucleotide_occurrences(&dna_seq_1); 25 | assert(dna_seq_1.A_count == 3); 26 | assert(dna_seq_1.C_count == 2); 27 | assert(dna_seq_1.G_count == 1); 28 | assert(dna_seq_1.T_count == 3); 29 | 30 | DNA_sequence dna_seq_2; 31 | strcpy(dna_seq_2.sequence, "AAAACCC"); 32 | compute_nucleotide_occurrences(&dna_seq_2); 33 | assert(dna_seq_2.A_count == 4); 34 | assert(dna_seq_2.C_count == 3); 35 | assert(dna_seq_2.G_count == 0); 36 | assert(dna_seq_2.T_count == 0); 37 | 38 | /* TODO: Think of a scenario that is not tested by the current test cases. Create one additional test case to test this scenario. */ 39 | 40 | printf("Congrats! If you have made it to this line, your Part 2 Test cases are all passing!\n"); 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /lab01/exercise2/pwd_checker.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pwd_checker.h" 3 | 4 | /* 5 | Password checker 6 | 7 | Requirements: 8 | - Password must be at least 10 characters 9 | - Password must contain at least 10 | - 1 upper case letter 11 | - 1 lower case letter 12 | - 1 number 13 | - Password cannot contain the person's first name or last name (case sensitive) 14 | 15 | For the simplicity of this exercise: 16 | - This is not the most efficient way to implement this program 17 | - These functions do not perform any error checking 18 | - You can assume that the first and last name will never be the empty string 19 | */ 20 | 21 | /* Returns true if the length of PASSWORD is at least 10, false otherwise */ 22 | bool check_length(const char *password) { 23 | int length = strlen(password); 24 | bool meets_len_req = (length <= 10); 25 | return meets_len_req; 26 | } 27 | 28 | /* Returns true if LETTER is in the range [LOWER, UPPER], false otherwise */ 29 | bool check_range(char letter, char lower, char upper) { 30 | bool is_in_range = (letter > lower && letter < upper); 31 | return is_in_range; 32 | } 33 | 34 | /* Returns true if PASSWORD contains at least one upper case letter, false otherwise */ 35 | bool check_upper(const char *password) { 36 | while (password != '\0') { 37 | bool is_in_range = check_range(*password, 'A', 'Z'); 38 | if (is_in_range) { 39 | return true; 40 | } 41 | ++password; 42 | } 43 | return false; 44 | } 45 | 46 | /* Returns true if PASSWORD contains at least one lower case letter, false otherwise */ 47 | bool check_lower(const char *password) { 48 | while (*password != '\0') { 49 | bool is_in_range = check_range(*password, 'a', 'z'); 50 | if (is_in_range) { 51 | return true; 52 | } 53 | ++password; 54 | } 55 | return false; 56 | } 57 | 58 | /* Returns true if PASSWORD contains at least one number, false otherwise */ 59 | bool check_number(const char *password) { 60 | while (password != '\0') { 61 | if (check_range(password, 0, 9)) { 62 | return true; 63 | } 64 | ++password; 65 | } 66 | return false; 67 | } 68 | 69 | /* Returns true if the person's first and last name are NOT in the password, false otherwise */ 70 | bool check_name(const char *first_name, const char *last_name, const char *password) { 71 | /* Type "man strstr" in your terminal to learn what strstr does! 72 | To exit the man pages, press 'q' */ 73 | /* Hint: a NULL pointer will evaluate to False in a logical statement while a non-NULL pointer 74 | will evaluate to True */ 75 | const char *first = strstr(*password, first_name); 76 | const char *last = strstr(password, last_name); 77 | return (!first && !last); 78 | } 79 | 80 | /* Returns true if PASSWORD meets the conditions specified above */ 81 | bool check_password(const char *first_name, const char *last_name, const char *password) { 82 | bool length, upper, lower, number, name; 83 | lower = check_lower(password); 84 | length = check_length(password); 85 | name = check_name(first_name, last_name, password); 86 | number = check_number(password); 87 | upper = check_upper(password); 88 | return (lower && length && name && upper && number); 89 | } 90 | -------------------------------------------------------------------------------- /lab01/exercise2/pwd_checker.h: -------------------------------------------------------------------------------- 1 | #ifndef PWD_CHECKER_H 2 | #define PWD_CHECKER_H 3 | 4 | #include 5 | 6 | bool check_password(const char *first_name, const char *last_name, const char *password); 7 | 8 | #endif // PWD_CHECKER_H 9 | -------------------------------------------------------------------------------- /lab01/exercise2/test_pwd_checker.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "pwd_checker.h" 4 | 5 | int main() { 6 | printf("Running tests...\n\n"); 7 | 8 | const char *test1_first = "Abraham"; 9 | const char *test1_last = "Garcia"; 10 | const char *test1_pwd = "qrtv?,mp!ltrA0b13rab4ham"; 11 | bool test1 = check_password(test1_first, test1_last, test1_pwd); 12 | assert(test1); 13 | 14 | printf("Congrats! The first test case is now passing. You should remove the assert statements that you added " 15 | "to pwd_checker.c because these correspond to the first test case and will not necessarily work for the remaining " 16 | "test cases!\n\n"); 17 | 18 | const char *test2_first = "Anjali"; 19 | const char *test2_last = "Patel"; 20 | const char *test2_pwd = "Aj8r"; 21 | bool test2 = check_password(test2_first, test2_last, test2_pwd); 22 | assert(!test2); 23 | 24 | const char *test3_first = "Chantelle"; 25 | const char *test3_last = "Brown"; 26 | const char *test3_pwd = "QLRIOW815N"; 27 | bool test3 = check_password(test3_first, test3_last, test3_pwd); 28 | assert(!test3); 29 | 30 | const char *test4_first = "Wei"; 31 | const char *test4_last = "Zhang"; 32 | const char *test4_pwd = "pjkdihn!o901"; 33 | bool test4 = check_password(test4_first, test4_last, test4_pwd); 34 | assert(!test4); 35 | 36 | const char *test5_first = "John"; 37 | const char *test5_last = "Smith"; 38 | const char *test5_pwd = "ALKLIenhLq"; 39 | bool test5 = check_password(test5_first, test5_last, test5_pwd); 40 | assert(!test5); 41 | 42 | const char *test6_first = "Haeun"; 43 | const char *test6_last = "Kim"; 44 | const char *test6_pwd = "Ji9anjwHaeun"; 45 | bool test6 = check_password(test6_first, test6_last, test6_pwd); 46 | assert(!test6); 47 | 48 | const char *test7_first = "Adeline"; 49 | const char *test7_last = "DuBois"; 50 | const char *test7_pwd = "ALKLIDuBoisen3hLq"; 51 | bool test7 = check_password(test7_first, test7_last, test7_pwd); 52 | assert(!test7); 53 | 54 | printf("Congrats! You have passed all of the test cases!\n"); 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /lab01/exercise3/linked_list.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "linked_list.h" 4 | 5 | /* returns a new node whose data is set to DATA and next is set to NULL */ 6 | Node *create_node(int data) { 7 | /* Don't worry about malloc yet! It is not in the scope of this lab */ 8 | struct Node *new_node = malloc(sizeof(struct Node)); 9 | if (new_node == NULL) { 10 | perror("Malloc failed\n"); 11 | } 12 | new_node->data = data; 13 | new_node->next = NULL; 14 | return new_node; 15 | } 16 | 17 | /* Don't worry about free(), it is not in the scope of this lab */ 18 | /* Frees the list starting at HEAD */ 19 | void free_list(Node *head) { 20 | while (head != NULL) { 21 | Node *temp = head->next; 22 | free(head); 23 | head = temp; 24 | } 25 | } 26 | 27 | /* Creates a new node whose data is set to DATA and adds it to the front of the 28 | list pointed to by HEAD. 29 | This function is heavily commented for instructional purposes. Please 30 | never use this many comments when you are writing code. */ 31 | void add_to_front(struct Node **head, int data) { 32 | /* Check if the head is NULL to make sure that we do not dereference a NULL pointer 33 | because that would result in a segfault */ 34 | if (head == NULL) return; 35 | struct Node *new_node = create_node(data); 36 | if (*head != NULL) { 37 | /* The list is not empty */ 38 | /* The new node's next should point to the head */ 39 | new_node->next = *head; 40 | } 41 | /* We must set HEAD using the following line in order to change the original list */ 42 | *head = new_node; 43 | /* The following line would not work because it would only change our local copy of HEAD */ 44 | /* head = new_node */ 45 | } 46 | 47 | /* Prints out a linked list starting at HEAD */ 48 | void print_list(struct Node *head) { 49 | struct Node *curr; 50 | for (curr = head; curr != NULL; curr = curr->next) { 51 | printf("%d->", curr->data); 52 | } 53 | printf("NULL\n"); 54 | } 55 | 56 | /* Iteratively reverses a linked list whose first node is HEAD */ 57 | void reverse_list(struct Node **head) { 58 | if (head == NULL) { 59 | return; 60 | } 61 | struct Node *curr = *head; 62 | struct Node *next = (*head)->next; 63 | curr->next = NULL; 64 | while (next != NULL) { 65 | struct Node *temp = next->next; 66 | next->next = curr; 67 | curr = next; 68 | next = temp; 69 | } 70 | *head = curr; 71 | } 72 | 73 | /* Creates a new node with a data field set to DATA and adds the node 74 | to the back of the list pointed to by HEAD */ 75 | void add_to_back(Node **head, int data) { 76 | if (head == NULL) { 77 | return; 78 | } 79 | if (*head == NULL) { 80 | *head = create_node(data); 81 | return; 82 | } 83 | Node *new_node = create_node(data); 84 | Node *prev; 85 | for (Node *curr = *head; curr != NULL; curr = curr->next) { 86 | prev = curr; 87 | } 88 | prev->next = new_node; 89 | } 90 | -------------------------------------------------------------------------------- /lab01/exercise3/linked_list.h: -------------------------------------------------------------------------------- 1 | #ifndef LINKED_LIST_H 2 | #define LINKED_LIST_H 3 | 4 | typedef struct Node { 5 | int data; 6 | struct Node *next; 7 | } Node; 8 | 9 | Node *create_node(int data); 10 | void free_list(Node *head); 11 | void add_to_front(struct Node **head, int data); 12 | void print_list(struct Node *head); 13 | void reverse_list(struct Node **head); 14 | void add_to_back(Node **head, int data); 15 | 16 | #endif // LINKED_LIST_H 17 | -------------------------------------------------------------------------------- /lab01/exercise3/test_linked_list.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "linked_list.h" 5 | 6 | int main(int argc, char **argv) { 7 | printf("Running tests...\n\n"); 8 | 9 | Node *head = NULL; 10 | 11 | /*********** reverse_list test ***********/ 12 | reverse_list(&head); 13 | for (int i = 0; i < 5; ++i) { 14 | add_to_front(&head, i); 15 | reverse_list(&head); 16 | } 17 | 18 | int expected_values[] = {3, 1, 0, 2, 4}; 19 | Node *curr = head; 20 | for (int i = 0; i < 5; ++i) { 21 | assert(curr->data == expected_values[i]); 22 | curr = curr->next; 23 | } 24 | free_list(head); 25 | 26 | printf("Congrats! All of the test cases passed!\n"); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /lab01/exercise4/ll_cycle.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ll_cycle.h" 3 | 4 | int ll_has_cycle(node *head) { 5 | /* TODO: Implement ll_has_cycle */ 6 | } 7 | -------------------------------------------------------------------------------- /lab01/exercise4/ll_cycle.h: -------------------------------------------------------------------------------- 1 | #ifndef LL_CYCLE_H 2 | #define LL_CYCLE_H 3 | 4 | typedef struct node { 5 | int value; 6 | struct node *next; 7 | } node; 8 | 9 | int ll_has_cycle(node *); 10 | 11 | #endif // LL_CYCLE_H 12 | -------------------------------------------------------------------------------- /lab01/exercise4/test_ll_cycle.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "ll_cycle.h" 4 | 5 | int main(void) { 6 | // DO NOT EDIT ANY OF THE FOLLOWING CODE 7 | printf("Running tests...\n\n"); 8 | 9 | int i; 10 | node nodes[25]; // enough to run our tests 11 | for(i = 0; i < sizeof(nodes)/sizeof(node); i++) { 12 | nodes[i].next = 0; 13 | nodes[i].value = 0; 14 | } 15 | 16 | nodes[0].next = &nodes[1]; 17 | nodes[1].next = &nodes[2]; 18 | nodes[2].next = &nodes[3]; 19 | printf("Checking first list for cycles. There should be none, ll_has_cycle says it has %s cycle\n", ll_has_cycle(&nodes[0]) ? "a" : "no"); 20 | assert(!ll_has_cycle(&nodes[0])); 21 | 22 | nodes[4].next = &nodes[5]; 23 | nodes[5].next = &nodes[6]; 24 | nodes[6].next = &nodes[7]; 25 | nodes[7].next = &nodes[8]; 26 | nodes[8].next = &nodes[9]; 27 | nodes[9].next = &nodes[10]; 28 | nodes[10].next = &nodes[4]; 29 | printf("Checking second list for cycles. There should be a cycle, ll_has_cycle says it has %s cycle\n", ll_has_cycle(&nodes[4]) ? "a" : "no"); 30 | assert(ll_has_cycle(&nodes[4])); 31 | 32 | nodes[11].next = &nodes[12]; 33 | nodes[12].next = &nodes[13]; 34 | nodes[13].next = &nodes[14]; 35 | nodes[14].next = &nodes[15]; 36 | nodes[15].next = &nodes[16]; 37 | nodes[16].next = &nodes[17]; 38 | nodes[17].next = &nodes[14]; 39 | printf("Checking third list for cycles. There should be a cycle, ll_has_cycle says it has %s cycle\n", ll_has_cycle(&nodes[11]) ? "a" : "no"); 40 | assert(ll_has_cycle(&nodes[11])); 41 | 42 | nodes[18].next = &nodes[18]; 43 | printf("Checking fourth list for cycles. There should be a cycle, ll_has_cycle says it has %s cycle\n", ll_has_cycle(&nodes[18]) ? "a" : "no"); 44 | assert(ll_has_cycle(&nodes[18])); 45 | 46 | nodes[19].next = &nodes[20]; 47 | nodes[20].next = &nodes[21]; 48 | nodes[21].next = &nodes[22]; 49 | nodes[22].next = &nodes[23]; 50 | printf("Checking fifth list for cycles. There should be none, ll_has_cycle says it has %s cycle\n", ll_has_cycle(&nodes[19]) ? "a" : "no"); 51 | assert(!ll_has_cycle(&nodes[19])); 52 | 53 | printf("Checking length-zero list for cycles. There should be none, ll_has_cycle says it has %s cycle\n\n", ll_has_cycle(NULL) ? "a" : "no"); 54 | assert(!ll_has_cycle(NULL)); 55 | 56 | printf("Congrats, you passed all the test cases!\n"); 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /lab02/.gitignore: -------------------------------------------------------------------------------- 1 | linked_list 2 | vector 3 | bit_ops -------------------------------------------------------------------------------- /lab02/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -std=c99 3 | 4 | all: linked_list vector bit_ops 5 | 6 | linked_list: linked_list.o test_linked_list.o 7 | $(CC) -o linked_list linked_list.o test_linked_list.o 8 | 9 | linked_list.o: linked_list.c linked_list.h 10 | $(CC) $(CFLAGS) -c linked_list.c 11 | 12 | test_linked_list.o: test_linked_list.c linked_list.h 13 | $(CC) $(CFLAGS) -c test_linked_list.c 14 | 15 | vector: vector.o test_vector.o 16 | $(CC) -o vector vector.o test_vector.o 17 | 18 | vector.o: vector.c vector.h 19 | $(CC) $(CFLAGS) -c vector.c 20 | 21 | test_vector.o: test_vector.c vector.h 22 | $(CC) $(CFLAGS) -c test_vector.c 23 | 24 | bit_ops: bit_ops.o test_bit_ops.o 25 | $(CC) -o bit_ops bit_ops.o test_bit_ops.o 26 | 27 | bit_ops.o: bit_ops.c bit_ops.h 28 | $(CC) $(CFLAGS) -c bit_ops.c 29 | 30 | test_bit_ops.o: test_bit_ops.c bit_ops.h 31 | $(CC) $(CFLAGS) -c test_bit_ops.c 32 | 33 | clean: 34 | rm linked_list linked_list.o test_linked_list.o vector vector.o test_vector.o bit_ops bit_ops.o test_bit_ops.o 35 | -------------------------------------------------------------------------------- /lab02/bit_ops.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "bit_ops.h" 3 | 4 | /* Returns the Nth bit of X. Assumes 0 <= N <= 31. */ 5 | unsigned get_bit(unsigned x, unsigned n) { 6 | /* YOUR CODE HERE */ 7 | return -1; /* UPDATE WITH THE CORRECT RETURN VALUE*/ 8 | } 9 | 10 | /* Set the nth bit of the value of x to v. Assumes 0 <= N <= 31, and V is 0 or 1 */ 11 | void set_bit(unsigned *x, unsigned n, unsigned v) { 12 | /* YOUR CODE HERE */ 13 | } 14 | 15 | /* Flips the Nth bit in X. Assumes 0 <= N <= 31.*/ 16 | void flip_bit(unsigned *x, unsigned n) { 17 | /* YOUR CODE HERE */ 18 | } 19 | 20 | -------------------------------------------------------------------------------- /lab02/bit_ops.h: -------------------------------------------------------------------------------- 1 | unsigned get_bit(unsigned x, unsigned n); 2 | void set_bit(unsigned * x, unsigned n, unsigned v); 3 | void flip_bit(unsigned * x, unsigned n); -------------------------------------------------------------------------------- /lab02/linked_list.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "linked_list.h" 4 | 5 | /* returns a new node whose data is set to DATA and next is set to NULL */ 6 | Node *create_node(int data) { 7 | /* Don't worry about malloc yet! It is not in the scope of this lab */ 8 | struct Node *new_node = malloc(sizeof(struct Node)); 9 | if (new_node == NULL) { 10 | perror("Malloc failed\n"); 11 | } 12 | new_node->data = data; 13 | new_node->next = NULL; 14 | return new_node; 15 | } 16 | 17 | /* Don't worry about free(), it is not in the scope of this lab */ 18 | /* Frees the list starting at HEAD */ 19 | void free_list(Node *head) { 20 | while (head != NULL) { 21 | Node *temp = head->next; 22 | free(head); 23 | head = temp; 24 | } 25 | } 26 | 27 | /* Creates a new node whose data is set to DATA and adds it to the front of the 28 | list pointed to by HEAD. 29 | This function is heavily commented for instructional purposes. Please 30 | never use this many comments when you are writing code. */ 31 | void add_to_front(struct Node **head, int data) { 32 | /* Check if the head is NULL to make sure that we do not dereference a NULL pointer 33 | because that would result in a segfault */ 34 | if (head == NULL) return; 35 | struct Node *new_node = create_node(data); 36 | /* The new node's next should point to the head 37 | (this works even if the head is NULL) */ 38 | new_node->next = *head; 39 | /* We must set HEAD using the following line in order to change the original list */ 40 | *head = new_node; 41 | /* The following line would not work because it would only change our local copy of HEAD */ 42 | /* head = new_node */ 43 | } 44 | 45 | /* Prints out a linked list starting at HEAD */ 46 | void print_list(struct Node *head) { 47 | struct Node *curr; 48 | for (curr = head; curr != NULL; curr = curr->next) { 49 | printf("%d->", curr->data); 50 | } 51 | printf("NULL\n"); 52 | } 53 | 54 | /* Iteratively reverses a linked list whose first node is HEAD */ 55 | void reverse_list(struct Node **head) { 56 | if (head == NULL) { 57 | return; 58 | } 59 | struct Node *curr = *head; 60 | struct Node *next = (*head)->next; 61 | curr->next = NULL; 62 | while (next != NULL) { 63 | struct Node *temp = next->next; 64 | next->next = curr; 65 | curr = next; 66 | next = temp; 67 | } 68 | *head = curr; 69 | } 70 | 71 | /* Creates a new node with a data field set to DATA and adds the node 72 | to the back of the list pointed to by HEAD */ 73 | void add_to_back(Node **head, int data) { 74 | if (head == NULL) { 75 | return; 76 | } 77 | Node *new_node = create_node(data); 78 | if (*head == NULL) { 79 | *head = new_node; 80 | return; 81 | } 82 | Node *prev; 83 | for (Node *curr = *head; curr != NULL; curr = curr->next) { 84 | prev = curr; 85 | } 86 | prev->next = new_node; 87 | } 88 | -------------------------------------------------------------------------------- /lab02/linked_list.h: -------------------------------------------------------------------------------- 1 | #ifndef LINKED_LIST_H 2 | #define LINKED_LIST_H 3 | 4 | typedef struct Node { 5 | int data; 6 | struct Node *next; 7 | } Node; 8 | 9 | Node *create_node(int data); 10 | void free_list(Node *head); 11 | void add_to_front(struct Node **head, int data); 12 | void print_list(struct Node *head); 13 | void reverse_list(struct Node **head); 14 | void add_to_back(Node **head, int data); 15 | 16 | #endif // LINKED_LIST_H 17 | -------------------------------------------------------------------------------- /lab02/test_bit_ops.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "bit_ops.h" 3 | 4 | void test_get_bit(unsigned x, unsigned n, unsigned expected) { 5 | unsigned a = get_bit(x, n); 6 | if(a!=expected) { 7 | printf("get_bit(0x%08x,%u) returned 0x%08x, but we expected 0x%08x\n",x,n,a,expected); 8 | } else { 9 | printf("get_bit(0x%08x,%u)returned 0x%08x, correct\n",x,n,a); 10 | } 11 | } 12 | 13 | void test_set_bit(unsigned x, unsigned n, unsigned v, unsigned expected) { 14 | unsigned o = x; 15 | set_bit(&x, n, v); 16 | if(x!=expected) { 17 | printf("set_bit(0x%08x,%u,%u) returned 0x%08x but we expected 0x%08x\n",o,n,v,x,expected); 18 | } else { 19 | printf("set_bit(0x%08x,%u,%u) returned 0x%08x, correct\n",o,n,v,x); 20 | } 21 | } 22 | 23 | void test_flip_bit(unsigned x, unsigned n, unsigned expected) { 24 | unsigned o = x; 25 | flip_bit(&x, n); 26 | if(x!=expected) { 27 | printf("flip_bit(0x%08x,%u) returned 0x%08x, but we expected 0x%08x\n",o,n,x,expected); 28 | } else { 29 | printf("flip_bit(0x%08x,%u) returned 0x%08x, correct\n",o,n,x); 30 | } 31 | } 32 | 33 | int main(int argc, const char * argv[]) { 34 | printf("\nTesting get_bit()\n\n"); 35 | test_get_bit(0b1001110,0,0); 36 | test_get_bit(0b1001110,1,1); 37 | test_get_bit(0b1001110,5,0); 38 | test_get_bit(0b11011,3,1); 39 | test_get_bit(0b11011,2,0); 40 | test_get_bit(0b11011,9,0); 41 | printf("\nTesting set_bit()\n\n"); 42 | test_set_bit(0b1001110,2,0,0b1001010); 43 | test_set_bit(0b1101101,0,0,0b1101100); 44 | test_set_bit(0b1001110,2,1,0b1001110); 45 | test_set_bit(0b1101101,0,1,0b1101101); 46 | test_set_bit(0b1001110,9,0,0b1001110); 47 | test_set_bit(0b1101101,4,0,0b1101101); 48 | test_set_bit(0b1001110,9,1,0b1001001110); 49 | test_set_bit(0b1101101,7,1,0b11101101); 50 | printf("\nTesting flip_bit()\n\n"); 51 | test_flip_bit(0b1001110,0,0b1001111); 52 | test_flip_bit(0b1001110,1,0b1001100); 53 | test_flip_bit(0b1001110,2,0b1001010); 54 | test_flip_bit(0b1001110,5,0b1101110); 55 | test_flip_bit(0b1001110,9,0b1001001110); 56 | printf("\n"); 57 | return 0; 58 | } -------------------------------------------------------------------------------- /lab02/test_linked_list.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "linked_list.h" 5 | 6 | int main(int argc, char **argv) { 7 | printf("Running tests...\n\n"); 8 | 9 | Node *head = NULL; 10 | 11 | /*********** reverse_list test ***********/ 12 | reverse_list(&head); 13 | for (int i = 0; i < 5; ++i) { 14 | add_to_front(&head, i); 15 | reverse_list(&head); 16 | } 17 | 18 | int expected_values[] = {3, 1, 0, 2, 4}; 19 | Node *curr = head; 20 | for (int i = 0; i < 5; ++i) { 21 | assert(curr->data == expected_values[i]); 22 | curr = curr->next; 23 | } 24 | free_list(head); 25 | 26 | printf("Congrats! All of the test cases passed!\n"); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /lab02/test_vector.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "vector.h" 5 | 6 | int main(int argc, char **argv) { 7 | vector_t *v; 8 | 9 | printf("Calling vector_new()\n"); 10 | v = vector_new(); 11 | 12 | printf("Calling vector_delete()\n"); 13 | vector_delete(v); 14 | 15 | printf("vector_new() again\n"); 16 | v = vector_new(); 17 | 18 | printf("These should all return 0 (vector_get()): "); 19 | printf("%d ", vector_get(v, 0)); 20 | printf("%d ", vector_get(v, 1)); 21 | printf("%d\n", vector_get(v, 2)); 22 | 23 | printf("Doing a bunch of vector_set()s\n"); 24 | vector_set(v, 0, 98); 25 | vector_set(v, 11, 15); 26 | vector_set(v, 15, -23); 27 | vector_set(v, 24, 65); 28 | vector_set(v, 500, 3); 29 | vector_set(v, 12, -123); 30 | vector_set(v, 15, 21); 31 | vector_set(v, 25, 43); 32 | 33 | printf("These should be equal:\n"); 34 | printf("98 = %d\n", vector_get(v, 0)); 35 | printf("15 = %d\n", vector_get(v, 11)); 36 | printf("65 = %d\n", vector_get(v, 24)); 37 | printf("-123 = %d\n", vector_get(v, 12)); 38 | printf("21 = %d\n", vector_get(v, 15)); 39 | printf("43 = %d\n", vector_get(v, 25)); 40 | printf("0 = %d\n", vector_get(v, 23)); 41 | printf("0 = %d\n", vector_get(v, 1)); 42 | printf("0 = %d\n", vector_get(v, 501)); 43 | printf("3 = %d\n", vector_get(v, 500)); 44 | 45 | vector_delete(v); 46 | 47 | printf("Test complete.\n"); 48 | 49 | return 0; 50 | } -------------------------------------------------------------------------------- /lab02/vector.c: -------------------------------------------------------------------------------- 1 | /* Include the system headers we need */ 2 | #include 3 | #include 4 | 5 | /* Include our header */ 6 | #include "vector.h" 7 | 8 | /* Define what our struct is */ 9 | struct vector_t { 10 | size_t size; 11 | int *data; 12 | }; 13 | 14 | /* Utility function to handle allocation failures. In this 15 | case we print a message and exit. */ 16 | static void allocation_failed() { 17 | fprintf(stderr, "Out of memory.\n"); 18 | exit(1); 19 | } 20 | 21 | /* Bad example of how to create a new vector */ 22 | vector_t *bad_vector_new() { 23 | /* Create the vector and a pointer to it */ 24 | vector_t *retval, v; 25 | retval = &v; 26 | 27 | /* Initialize attributes */ 28 | retval->size = 1; 29 | retval->data = malloc(sizeof(int)); 30 | if (retval->data == NULL) { 31 | allocation_failed(); 32 | } 33 | 34 | retval->data[0] = 0; 35 | return retval; 36 | } 37 | 38 | /* Another suboptimal way of creating a vector */ 39 | vector_t also_bad_vector_new() { 40 | /* Create the vector */ 41 | vector_t v; 42 | 43 | /* Initialize attributes */ 44 | v.size = 1; 45 | v.data = malloc(sizeof(int)); 46 | if (v.data == NULL) { 47 | allocation_failed(); 48 | } 49 | v.data[0] = 0; 50 | return v; 51 | } 52 | 53 | /* Create a new vector with a size (length) of 1 and set its single component to zero... the 54 | right way */ 55 | /* TODO: uncomment the code that is preceded by // */ 56 | vector_t *vector_new() { 57 | /* Declare what this function will return */ 58 | // vector_t *retval; 59 | 60 | /* First, we need to allocate memory on the heap for the struct */ 61 | // retval = /* YOUR CODE HERE */ 62 | 63 | /* Check our return value to make sure we got memory */ 64 | // if (/* YOUR CODE HERE */) { 65 | // allocation_failed(); 66 | // } 67 | 68 | /* Now we need to initialize our data. 69 | Since retval->data should be able to dynamically grow, 70 | what do you need to do? */ 71 | // retval->size = /* YOUR CODE HERE */; 72 | // retval->data = /* YOUR CODE HERE */; 73 | 74 | /* Check the data attribute of our vector to make sure we got memory */ 75 | // if (/* YOUR CODE HERE */) { 76 | // free(retval); //Why is this line necessary? 77 | // allocation_failed(); 78 | // } 79 | 80 | /* Complete the initialization by setting the single component to zero */ 81 | // /* YOUR CODE HERE */ = 0; 82 | 83 | /* and return... */ 84 | return NULL; /* UPDATE RETURN VALUE */ 85 | } 86 | 87 | /* Return the value at the specified location/component "loc" of the vector */ 88 | int vector_get(vector_t *v, size_t loc) { 89 | 90 | /* If we are passed a NULL pointer for our vector, complain about it and exit. */ 91 | if(v == NULL) { 92 | fprintf(stderr, "vector_get: passed a NULL vector.\n"); 93 | abort(); 94 | } 95 | 96 | /* If the requested location is higher than we have allocated, return 0. 97 | * Otherwise, return what is in the passed location. 98 | */ 99 | /* YOUR CODE HERE */ 100 | return 0; 101 | } 102 | 103 | /* Free up the memory allocated for the passed vector. 104 | Remember, you need to free up ALL the memory that was allocated. */ 105 | void vector_delete(vector_t *v) { 106 | /* YOUR CODE HERE */ 107 | } 108 | 109 | /* Set a value in the vector. If the extra memory allocation fails, call 110 | allocation_failed(). */ 111 | void vector_set(vector_t *v, size_t loc, int value) { 112 | /* What do you need to do if the location is greater than the size we have 113 | * allocated? Remember that unset locations should contain a value of 0. 114 | */ 115 | 116 | /* YOUR CODE HERE */ 117 | } -------------------------------------------------------------------------------- /lab02/vector.h: -------------------------------------------------------------------------------- 1 | #ifndef CS61C_VECTOR_H_ 2 | #define CS61C_VECTOR_H_ 3 | /* vector.h originally written by Jeremy Huddleston Sp2004 4 | * 5 | * So it looks like you've decided to venture into the "other" files of this 6 | * lab. Good. C Header files (the .h extension) are a way of telling other .c 7 | * files what they can have access to. You usually include stdlib.h in your 8 | * C programs, and this process is identical to including this .h file with the 9 | * one change being: 10 | * 11 | * #include "file.h" 12 | * versus 13 | * #include 14 | * 15 | * The difference is that the <> notation is for system header files and the "" 16 | * is for ones you provide yourself (in your local directory for instance). 17 | * 18 | * The header file starts off with 19 | * #ifndef CS61C_VECTOR_H_ 20 | * #define CS61C_VECTOR_H_ 21 | * 22 | * and ends with a final #endif. This prevents the file from being included 23 | * more than once which could've possibly resulted in an infinite loop of 24 | * file inclusions. 25 | * 26 | * First, we define the 'vector_t' datatype. This next line says that a 'vector_t' 27 | * is the same as a 'struct vector_t'. So anywhere in the code after this, we 28 | * can use 'vector_t *' to mean a pointer to a 'struct vector_t' (which is defined in 29 | * vector.c). We can get away with doing this even though we don't know what a 30 | * struct vector is because all struct pointers have the same representation in memory. 31 | */ 32 | 33 | #include 34 | 35 | typedef struct vector_t vector_t; 36 | 37 | /* 38 | * Next, we provide the prototypes for the functions defined in vector.c. This 39 | * is a way of telling the .c files that #include this header what they will 40 | * have access to. 41 | */ 42 | 43 | /* Create a new vector */ 44 | vector_t *vector_new(); 45 | 46 | /* Free up the memory allocated for the passed vector */ 47 | void vector_delete(vector_t *v); 48 | 49 | /* Return the value in the vector */ 50 | int vector_get(vector_t *v, size_t loc); 51 | 52 | /* Set a value in the vector */ 53 | void vector_set(vector_t *v, size_t loc, int value); 54 | 55 | #endif -------------------------------------------------------------------------------- /lab03/ex3.c: -------------------------------------------------------------------------------- 1 | int source[] = {3, 1, 4, 1, 5, 9, 0}; 2 | int dest[10]; 3 | 4 | int fun(int x) { 5 | return -x * (x + 1); 6 | } 7 | 8 | int main() { 9 | int k; 10 | int sum = 0; 11 | for (k = 0; source[k] != 0; k++) { 12 | dest[k] = fun(source[k]); 13 | sum += dest[k]; 14 | } 15 | return sum; 16 | } 17 | -------------------------------------------------------------------------------- /lab03/ex3.s: -------------------------------------------------------------------------------- 1 | .globl main 2 | 3 | .data 4 | source: 5 | .word 3 6 | .word 1 7 | .word 4 8 | .word 1 9 | .word 5 10 | .word 9 11 | .word 0 12 | dest: 13 | .word 0 14 | .word 0 15 | .word 0 16 | .word 0 17 | .word 0 18 | .word 0 19 | .word 0 20 | .word 0 21 | .word 0 22 | .word 0 23 | 24 | .text 25 | fun: 26 | addi t0, a0, 1 27 | sub t1, x0, a0 28 | mul a0, t0, t1 29 | jr ra 30 | 31 | main: 32 | # BEGIN PROLOGUE 33 | addi sp, sp, -20 34 | sw s0, 0(sp) 35 | sw s1, 4(sp) 36 | sw s2, 8(sp) 37 | sw s3, 12(sp) 38 | sw ra, 16(sp) 39 | # END PROLOGUE 40 | addi t0, x0, 0 41 | addi s0, x0, 0 42 | la s1, source 43 | la s2, dest 44 | loop: 45 | slli s3, t0, 2 46 | add t1, s1, s3 47 | lw t2, 0(t1) 48 | beq t2, x0, exit 49 | add a0, x0, t2 50 | addi sp, sp, -8 51 | sw t0, 0(sp) 52 | sw t2, 4(sp) 53 | jal fun 54 | lw t0, 0(sp) 55 | lw t2, 4(sp) 56 | addi sp, sp, 8 57 | add t2, x0, a0 58 | add t3, s2, s3 59 | sw t2, 0(t3) 60 | add s0, s0, t2 61 | addi t0, t0, 1 62 | jal x0, loop 63 | exit: 64 | add a0, x0, s0 65 | # BEGIN EPILOGUE 66 | lw s0, 0(sp) 67 | lw s1, 4(sp) 68 | lw s2, 8(sp) 69 | lw s3, 12(sp) 70 | lw ra, 16(sp) 71 | addi sp, sp, 20 72 | # END EPILOGUE 73 | jr ra 74 | -------------------------------------------------------------------------------- /lab03/factorial.s: -------------------------------------------------------------------------------- 1 | .globl factorial 2 | 3 | .data 4 | n: .word 8 5 | 6 | .text 7 | main: 8 | la t0, n 9 | lw a0, 0(t0) 10 | jal ra, factorial 11 | 12 | addi a1, a0, 0 13 | addi a0, x0, 1 14 | ecall # Print Result 15 | 16 | addi a1, x0, '\n' 17 | addi a0, x0, 11 18 | ecall # Print newline 19 | 20 | addi a0, x0, 10 21 | ecall # Exit 22 | 23 | factorial: 24 | # YOUR CODE HERE 25 | -------------------------------------------------------------------------------- /lab03/fib.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int num = 9; 4 | 5 | // Function to find the nth Fibonacci number 6 | int fib(int n) { 7 | int curr_fib = 0, next_fib = 1; 8 | int new_fib; 9 | for (int i = n; i > 0; i--) { 10 | new_fib = curr_fib + next_fib; 11 | curr_fib = next_fib; 12 | next_fib = new_fib; 13 | } 14 | 15 | return curr_fib; 16 | } 17 | 18 | int main(void) { 19 | int i = fib(num); 20 | printf("i: %d\n", i); 21 | } -------------------------------------------------------------------------------- /lab03/fib.s: -------------------------------------------------------------------------------- 1 | .data 2 | n: .word 9 3 | 4 | .text 5 | main: 6 | add t0, x0, x0 # curr_fib = 0 7 | addi t1, x0, 1 # next_fib = 1 8 | la t3, n # load the address of the label n 9 | lw t3, 0(t3) # get the value that is stored at the adddress denoted by the label n 10 | fib: 11 | beq t3, x0, finish # exit loop once we have completed n iterations 12 | add t2, t1, t0 # new_fib = curr_fib + next_fib; 13 | mv t0, t1 # curr_fib = next_fib; 14 | mv t1, t2 # next_fib = new_fib; 15 | addi t3, t3, -1 # decrement counter 16 | j fib # loop 17 | finish: 18 | addi a0, x0, 1 # argument to ecall to execute print integer 19 | addi a1, t0, 0 # argument to ecall, the value to be printed 20 | ecall # print integer ecall 21 | addi a0, x0, 10 # argument to ecall to terminate 22 | ecall # terminate ecall 23 | -------------------------------------------------------------------------------- /lab03/list_map.s: -------------------------------------------------------------------------------- 1 | .globl map 2 | 3 | .text 4 | main: 5 | jal ra, create_default_list 6 | add s0, a0, x0 # a0 (and now s0) is the head of node list 7 | 8 | # Print the list 9 | add a0, s0, x0 10 | jal ra, print_list 11 | # Print a newline 12 | jal ra, print_newline 13 | 14 | # === Calling `map(head, &square)` === 15 | # Load function arguments 16 | add a0, s0, x0 # Loads the address of the first node into a0 17 | 18 | # Load the address of the "square" function into a1 (hint: check out "la" on the green sheet) 19 | ### YOUR CODE HERE ### 20 | 21 | 22 | # Issue the call to map 23 | jal ra, map 24 | 25 | # Print the squared list 26 | add a0, s0, x0 27 | jal ra, print_list 28 | jal ra, print_newline 29 | 30 | # === Calling `map(head, &decrement)` === 31 | # Because our `map` function modifies the list in-place, the decrement takes place after 32 | # the square does 33 | 34 | # Load function arguments 35 | add a0, s0, x0 # Loads the address of the first node into a0 36 | 37 | # Load the address of the "decrement" function into a1 (should be very similar to before) 38 | ### YOUR CODE HERE ### 39 | 40 | 41 | # Issue the call to map 42 | jal ra, map 43 | 44 | # Print decremented list 45 | add a0, s0, x0 46 | jal ra, print_list 47 | jal ra, print_newline 48 | 49 | addi a0, x0, 10 50 | ecall # Terminate the program 51 | 52 | map: 53 | # Prologue: Make space on the stack and back-up registers 54 | ### YOUR CODE HERE ### 55 | 56 | beq a0, x0, done # If we were given a null pointer (address 0), we're done. 57 | 58 | add s0, a0, x0 # Save address of this node in s0 59 | add s1, a1, x0 # Save address of function in s1 60 | 61 | # Remember that each node is 8 bytes long: 4 for the value followed by 4 for the pointer to next. 62 | # What does this tell you about how you access the value and how you access the pointer to next? 63 | 64 | # Load the value of the current node into a0 65 | # THINK: Why a0? 66 | ### YOUR CODE HERE ### 67 | 68 | # Call the function in question on that value. DO NOT use a label (be prepared to answer why). 69 | # Hint: Where do we keep track of the function to call? Recall the parameters of "map". 70 | ### YOUR CODE HERE ### 71 | 72 | # Store the returned value back into the node 73 | # Where can you assume the returned value is? 74 | ### YOUR CODE HERE ### 75 | 76 | # Load the address of the next node into a0 77 | # The address of the next node is an attribute of the current node. 78 | # Think about how structs are organized in memory. 79 | ### YOUR CODE HERE ### 80 | 81 | # Put the address of the function back into a1 to prepare for the recursion 82 | # THINK: why a1? What about a0? 83 | ### YOUR CODE HERE ### 84 | 85 | # Recurse 86 | ### YOUR CODE HERE ### 87 | 88 | done: 89 | # Epilogue: Restore register values and free space from the stack 90 | ### YOUR CODE HERE ### 91 | 92 | jr ra # Return to caller 93 | 94 | # === Definition of the "square" function === 95 | square: 96 | mul a0, a0, a0 97 | jr ra 98 | 99 | # === Definition of the "decrement" function === 100 | decrement: 101 | addi a0, a0, -1 102 | jr ra 103 | 104 | # === Helper functions === 105 | # You don't need to understand these, but reading them may be useful 106 | 107 | create_default_list: 108 | addi sp, sp, -12 109 | sw ra, 0(sp) 110 | sw s0, 4(sp) 111 | sw s1, 8(sp) 112 | li s0, 0 # Pointer to the last node we handled 113 | li s1, 0 # Number of nodes handled 114 | loop: # do... 115 | li a0, 8 116 | jal ra, malloc # Allocate memory for the next node 117 | sw s1, 0(a0) # node->value = i 118 | sw s0, 4(a0) # node->next = last 119 | add s0, a0, x0 # last = node 120 | addi s1, s1, 1 # i++ 121 | addi t0, x0, 10 122 | bne s1, t0, loop # ... while i!= 10 123 | lw ra, 0(sp) 124 | lw s0, 4(sp) 125 | lw s1, 8(sp) 126 | addi sp, sp, 12 127 | jr ra 128 | 129 | print_list: 130 | bne a0, x0, print_me_and_recurse 131 | jr ra # Nothing to print 132 | print_me_and_recurse: 133 | add t0, a0, x0 # t0 gets current node address 134 | lw a1, 0(t0) # a1 gets value in current node 135 | addi a0, x0, 1 # Prepare for print integer ecall 136 | ecall 137 | addi a1, x0, ' ' # a0 gets address of string containing space 138 | addi a0, x0, 11 # Prepare for print char syscall 139 | ecall 140 | lw a0, 4(t0) # a0 gets address of next node 141 | jal x0, print_list # Recurse. The value of ra hasn't been changed. 142 | 143 | print_newline: 144 | addi a1, x0, '\n' # Load in ascii code for newline 145 | addi a0, x0, 11 146 | ecall 147 | jr ra 148 | 149 | malloc: 150 | addi a1, a0, 0 151 | addi a0, x0, 9 152 | ecall 153 | jr ra 154 | -------------------------------------------------------------------------------- /lab04/cc_test.s: -------------------------------------------------------------------------------- 1 | .globl pow inc_arr 2 | 3 | .data 4 | fail_message: .asciiz "%s test failed\n" 5 | pow_string: .asciiz "pow" 6 | inc_arr_string: .asciiz "inc_arr" 7 | 8 | success_message: .asciiz "Tests passed.\n" 9 | array: 10 | .word 1 2 3 4 5 11 | exp_inc_array_result: 12 | .word 2 3 4 5 6 13 | 14 | .text 15 | main: 16 | # pow: should return 2 ** 7 = 128 17 | li a0, 2 18 | li a1, 7 19 | jal pow 20 | li t0, 128 # verifies that pow returned the right value 21 | beq a0, t0, next_test 22 | la a0, pow_string 23 | j failure 24 | 25 | next_test: 26 | # inc_arr: increments "array" in place 27 | la a0, array 28 | li a1, 5 29 | jal inc_arr 30 | jal check_arr # Verifies inc_arr returned the right value 31 | # all tests pass, exit normally 32 | li a0, 4 33 | la a1, success_message 34 | ecall 35 | li a0, 10 36 | ecall 37 | 38 | # Computes a0 to the power of a1. 39 | # This is analogous to the following C pseudocode: 40 | # 41 | # uint32_t pow(uint32_t a0, uint32_t a1) { 42 | # uint32_t s0 = 1; 43 | # while (a1 != 0) { 44 | # s0 *= a0; 45 | # a1 -= 1; 46 | # } 47 | # return s0; 48 | # } 49 | # 50 | pow: 51 | # BEGIN PROLOGUE 52 | # FIXME Need to save the calle saved register(s) 53 | # END PROLOGUE 54 | li s0, 1 55 | pow_loop: 56 | beq a1, zero, pow_end 57 | mul s0, s0, a0 58 | addi a1, a1, -1 59 | j pow_loop 60 | pow_end: 61 | mv a0, s0 62 | # BEGIN EPILOGUE 63 | # FIXME Need to restore the calle saved register(s) 64 | # END EPILOGUE 65 | ret 66 | 67 | # Increments the elements of an array in-place. 68 | # a0 holds the address of the start of the array, and a1 holds 69 | # the number of elements it contains. 70 | # 71 | # This function calls the "helper_fn" function, which takes in an 72 | # address as argument and increments the 32-bit value stored there. 73 | inc_arr: 74 | # BEGIN PROLOGUE 75 | # FIXME What other registers need to be saved? 76 | addi sp, sp, -4 77 | sw ra, 0(sp) 78 | # END PROLOGUE 79 | mv s0, a0 # Copy start of array to saved register 80 | mv s1, a1 # Copy length of array to saved register 81 | li t0, 0 # Initialize counter to 0 82 | inc_arr_loop: 83 | beq t0, s1, inc_arr_end 84 | slli t1, t0, 2 # Convert array index to byte offset 85 | add a0, s0, t1 # Add offset to start of array 86 | # Prepare to call helper_fn 87 | # 88 | # FIXME Add code to preserve the value in t0 before we call helper_fn 89 | # Also ask yourself this: why don't we need to preserve t1? 90 | # 91 | jal helper_fn 92 | # FIXME Restore t0 93 | # Finished call for helper_fn 94 | addi t0, t0, 1 # Increment counter 95 | j inc_arr_loop 96 | inc_arr_end: 97 | # BEGIN EPILOGUE 98 | # FIXME What other registers need to be restored? 99 | lw ra, 0(sp) 100 | addi sp, sp, 4 101 | # END EPILOGUE 102 | ret 103 | 104 | # This helper function adds 1 to the value at the memory address in a0. 105 | # It doesn't return anything. 106 | # C pseudocode for what it does: "*a0 = *a0 + 1" 107 | # 108 | # This function also violates calling convention, but it might not 109 | # be reported by the Venus CC checker (try and figure out why). 110 | # You should fix the bug anyway by filling in the prologue and epilogue 111 | # as appropriate. 112 | helper_fn: 113 | # BEGIN PROLOGUE 114 | # FIXME: YOUR CODE HERE 115 | # END PROLOGUE 116 | lw t1, 0(a0) 117 | addi s0, t1, 1 118 | sw s0, 0(a0) 119 | # BEGIN EPILOGUE 120 | # FIXME: YOUR CODE HERE 121 | # END EPILOGUE 122 | ret 123 | 124 | # YOU CAN IGNORE EVERYTHING BELOW THIS COMMENT 125 | 126 | # Checks the result of inc_arr, which should contain 2 3 4 5 6 after 127 | # one call. 128 | # You can safely ignore this function; it has no errors. 129 | check_arr: 130 | la t0, exp_inc_array_result 131 | la t1, array 132 | addi t2, t1, 20 # Last element is 5*4 bytes off 133 | check_arr_loop: 134 | beq t1, t2, check_arr_end 135 | lw t3, 0(t0) 136 | lw t4, 0(t1) 137 | beq t3, t4, continue 138 | la a0, inc_arr_string 139 | j failure 140 | continue: 141 | addi t0, t0, 4 142 | addi t1, t1, 4 143 | j check_arr_loop 144 | check_arr_end: 145 | ret 146 | 147 | 148 | # prints a failure message, then terminates the program 149 | # Since we don't return back to the caller, this is like executing an exception 150 | # inputs: a0 = the name of the test that failed 151 | failure: 152 | mv a3, a0 # load the name of the test that failed 153 | li a0, 4 # String print ecall 154 | la a1, fail_message 155 | 156 | ecall 157 | li a0, 10 # Exit ecall 158 | ecall 159 | 160 | -------------------------------------------------------------------------------- /lab04/discrete_fn.s: -------------------------------------------------------------------------------- 1 | # The .globl directive identifies functions that we want to export to other files, 2 | # similar to including a function in a header file in C 3 | .globl f 4 | 5 | .data 6 | # asciiz is a directive used to store strings 7 | # asciiz will automatically append a null terminator to the end of the string 8 | neg3: .asciiz "f(-3) should be 6, and it is: " 9 | neg2: .asciiz "f(-2) should be 61, and it is: " 10 | neg1: .asciiz "f(-1) should be 17, and it is: " 11 | zero: .asciiz "f(0) should be -38, and it is: " 12 | pos1: .asciiz "f(1) should be 19, and it is: " 13 | pos2: .asciiz "f(2) should be 42, and it is: " 14 | pos3: .asciiz "f(3) should be 5, and it is: " 15 | 16 | output: .word 6, 61, 17, -38, 19, 42, 5 17 | 18 | .text 19 | main: 20 | ######### evaluate f(-3), should be 6 ######### 21 | # load the address of the string located at neg3 into a0 22 | # this will serve as the argument to print_str 23 | la a0, neg3 24 | # print out the string located at neg3 25 | jal print_str 26 | # load the first argument to f into a0 27 | li a0, -3 28 | # load the second argument of f into a1 29 | # `output` is a pointer to an array that contains the possible output values of f 30 | la a1, output 31 | # execute f(-3) 32 | jal f 33 | # f will return the output of f(-3) into register a0 34 | # to print out the return value, we will call print_int 35 | # print_int expects the value that it's printing out to be in register a0 36 | # the output of the function is already in a0, so we don't need to move it 37 | jal print_int 38 | # print a new line 39 | jal print_newline 40 | 41 | ######### evaluate f(-2), should be 61 ######## 42 | la a0, neg2 43 | jal print_str 44 | li a0, -2 45 | la a1, output 46 | jal f 47 | jal print_int 48 | jal print_newline 49 | 50 | ######### evaluate f(-1), should be 17 ######## 51 | la a0, neg1 52 | jal print_str 53 | li a0, -1 54 | la a1, output 55 | jal f 56 | jal print_int 57 | jal print_newline 58 | 59 | ######### evaluate f(0), should be -38 ######## 60 | la a0, zero 61 | jal print_str 62 | li a0, 0 63 | la a1, output 64 | jal f 65 | jal print_int 66 | jal print_newline 67 | 68 | ######### evaluate f(1), should be 19 ######### 69 | la a0, pos1 70 | jal print_str 71 | li a0, 1 72 | la a1, output 73 | jal f 74 | jal print_int 75 | jal print_newline 76 | 77 | ######### evaluate f(2), should be 42 ######### 78 | la a0, pos2 79 | jal print_str 80 | li a0, 2 81 | la a1, output 82 | jal f 83 | jal print_int 84 | jal print_newline 85 | 86 | ######### evaluate f(3), should be 5 ######### 87 | la a0, pos3 88 | jal print_str 89 | li a0, 3 90 | la a1, output 91 | jal f 92 | jal print_int 93 | jal print_newline 94 | 95 | # passing 10 to ecall will terminate the program 96 | li a0, 10 97 | ecall 98 | 99 | # f takes in two arguments: 100 | # a0 is the value we want to evaluate f at 101 | # a1 is the address of the "output" array (defined above). 102 | f: 103 | # YOUR CODE GOES HERE! 104 | 105 | jr ra # Always remember to jr ra after your function! 106 | 107 | # prints out one integer 108 | # input values: a0: the integer to print 109 | # does not return anything 110 | print_int: 111 | # to print an integer, we need to make an ecall with a0 set to 1 112 | # the thing that will be printed is stored in register a1 113 | # this line copies the integer to be printed into a1 114 | mv a1, a0 115 | # set register a0 to 1 so that the ecall will print 116 | li a0, 1 117 | # print the integer 118 | ecall 119 | # return to the calling function 120 | jr ra 121 | 122 | # prints out a string 123 | print_str: 124 | mv a1, a0 125 | li a0, 4 # tells ecall to print the string that a1 points to 126 | ecall 127 | jr ra 128 | 129 | print_newline: 130 | li a1, '\n' 131 | li a0, 11 # tells ecall to print the character in a1 132 | ecall 133 | jr ra 134 | -------------------------------------------------------------------------------- /lab04/megalistmanips.s: -------------------------------------------------------------------------------- 1 | .globl map 2 | 3 | .data 4 | arrays: .word 5, 6, 7, 8, 9 5 | .word 1, 2, 3, 4, 7 6 | .word 5, 2, 7, 4, 3 7 | .word 1, 6, 3, 8, 4 8 | .word 5, 2, 7, 8, 1 9 | 10 | start_msg: .asciiz "Lists before: \n" 11 | end_msg: .asciiz "Lists after: \n" 12 | 13 | .text 14 | main: 15 | jal create_default_list 16 | mv s0, a0 # v0 = s0 is head of node list 17 | 18 | #print "lists before: " 19 | la a1, start_msg 20 | li a0, 4 21 | ecall 22 | 23 | #print the list 24 | add a0, s0, x0 25 | jal print_list 26 | 27 | # print a newline 28 | jal print_newline 29 | 30 | # issue the map call 31 | add a0, s0, x0 # load the address of the first node into a0 32 | la a1, mystery # load the address of the function into a1 33 | 34 | jal map 35 | 36 | # print "lists after: " 37 | la a1, end_msg 38 | li a0, 4 39 | ecall 40 | 41 | # print the list 42 | add a0, s0, x0 43 | jal print_list 44 | 45 | li a0, 10 46 | ecall 47 | 48 | map: 49 | addi sp, sp, -12 50 | sw ra, 0(sp) 51 | sw s1, 4(sp) 52 | sw s0, 8(sp) 53 | 54 | beq a0, x0, done # if we were given a null pointer, we're done. 55 | 56 | add s0, a0, x0 # save address of this node in s0 57 | add s1, a1, x0 # save address of function in s1 58 | add t0, x0, x0 # t0 is a counter 59 | 60 | # remember that each node is 12 bytes long: 61 | # - 4 for the array pointer 62 | # - 4 for the size of the array 63 | # - 4 more for the pointer to the next node 64 | 65 | # also keep in mind that we should not make ANY assumption on which registers 66 | # are modified by the callees, even when we know the content inside the functions 67 | # we call. this is to enforce the abstraction barrier of calling convention. 68 | mapLoop: 69 | add t1, s0, x0 # load the address of the array of current node into t1 70 | lw t2, 4(s0) # load the size of the node's array into t2 71 | 72 | add t1, t1, t0 # offset the array address by the count 73 | lw a0, 0(t1) # load the value at that address into a0 74 | 75 | jalr s1 # call the function on that value. 76 | 77 | sw a0, 0(t1) # store the returned value back into the array 78 | addi t0, t0, 1 # increment the count 79 | bne t0, t2, mapLoop # repeat if we haven't reached the array size yet 80 | 81 | la a0, 8(s0) # load the address of the next node into a0 82 | lw a1, 0(s1) # put the address of the function back into a1 to prepare for the recursion 83 | 84 | jal map # recurse 85 | done: 86 | lw s0, 8(sp) 87 | lw s1, 4(sp) 88 | lw ra, 0(sp) 89 | addi sp, sp, 12 90 | 91 | print_newline: 92 | li a1, '\n' 93 | li a0, 11 94 | ecall 95 | jr ra 96 | 97 | mystery: 98 | mul t1, a0, a0 99 | add a0, t1, a0 100 | jr ra 101 | 102 | create_default_list: 103 | addi sp, sp, -24 104 | sw ra, 0(sp) 105 | sw s0, 4(sp) 106 | sw s1, 8(sp) 107 | sw s2, 12(sp) 108 | sw s3, 16(sp) 109 | sw s4, 20(sp) 110 | li s0, 0 # pointer to the last node we handled 111 | li s1, 0 # number of nodes handled 112 | li s2, 5 # size 113 | la s3, arrays 114 | loop: #do... 115 | li a0, 12 116 | jal malloc # get memory for the next node 117 | mv s4, a0 118 | li a0, 20 119 | jal malloc # get memory for this array 120 | 121 | sw a0, 0(s4) # node->arr = malloc 122 | lw a0, 0(s4) 123 | mv a1, s3 124 | jal fillArray # copy ints over to node->arr 125 | 126 | sw s2, 4(s4) # node->size = size (4) 127 | sw s0, 8(s4) # node-> next = previously created node 128 | 129 | add s0, x0, s4 # last = node 130 | addi s1, s1, 1 # i++ 131 | addi s3, s3, 20 # s3 points at next set of ints 132 | li t6 5 133 | bne s1, t6, loop # ... while i!= 5 134 | mv a0, s4 135 | lw ra, 0(sp) 136 | lw s0, 4(sp) 137 | lw s1, 8(sp) 138 | lw s2, 12(sp) 139 | lw s3, 16(sp) 140 | lw s4, 20(sp) 141 | addi sp, sp, 24 142 | jr ra 143 | 144 | fillArray: lw t0, 0(a1) #t0 gets array element 145 | sw t0, 0(a0) #node->arr gets array element 146 | lw t0, 4(a1) 147 | sw t0, 4(a0) 148 | lw t0, 8(a1) 149 | sw t0, 8(a0) 150 | lw t0, 12(a1) 151 | sw t0, 12(a0) 152 | lw t0, 16(a1) 153 | sw t0, 16(a0) 154 | jr ra 155 | 156 | print_list: 157 | bne a0, x0, printMeAndRecurse 158 | jr ra # nothing to print 159 | printMeAndRecurse: 160 | mv t0, a0 # t0 gets address of current node 161 | lw t3, 0(a0) # t3 gets array of current node 162 | li t1, 0 # t1 is index into array 163 | printLoop: 164 | slli t2, t1, 2 165 | add t4, t3, t2 166 | lw a1, 0(t4) # a0 gets value in current node's array at index t1 167 | li a0, 1 # preparte for print integer ecall 168 | ecall 169 | li a1, ' ' # a0 gets address of string containing space 170 | li a0, 11 # prepare for print string ecall 171 | ecall 172 | addi t1, t1, 1 173 | li t6 5 174 | bne t1, t6, printLoop # ... while i!= 5 175 | li a1, '\n' 176 | li a0, 11 177 | ecall 178 | lw a0, 8(t0) # a0 gets address of next node 179 | j print_list # recurse. We don't have to use jal because we already have where we want to return to in ra 180 | 181 | malloc: 182 | mv a1, a0 # Move a0 into a1 so that we can do the syscall correctly 183 | li a0, 9 184 | ecall 185 | jr ra 186 | -------------------------------------------------------------------------------- /lab05/.gitattributes: -------------------------------------------------------------------------------- 1 | /tests/reference-output/*.out text eol=lf 2 | /tests/student-output/*.out text eol=lf 3 | -------------------------------------------------------------------------------- /lab05/.gitignore: -------------------------------------------------------------------------------- 1 | /tests/student-output/*.out 2 | -------------------------------------------------------------------------------- /lab05/ex2.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim-evolution (https://github.com/reds-heig/logisim-evolution). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |
44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | -------------------------------------------------------------------------------- /lab05/ex3.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim-evolution (https://github.com/reds-heig/logisim-evolution). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | addr/data: 8 8 67 | 0 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /lab05/ex4.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim-evolution (https://github.com/reds-heig/logisim-evolution). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |
51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | rot1 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | rot2 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | rot4 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | rot8 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | -------------------------------------------------------------------------------- /lab05/test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import re 5 | import signal 6 | import subprocess 7 | import sys 8 | import time 9 | import traceback 10 | 11 | lab_dir_path = os.getcwd() 12 | tests_dir_path = os.path.join(os.getcwd(), "tests") 13 | logisim_path = os.path.join(os.getcwd(),"..", "tools", "logisim-evolution.jar") 14 | 15 | # logisim_env = os.environ.copy() 16 | # logisim_env["CS61C_TOOLS_ARGS"] = logisim_env.get("CS61C_TOOLS_ARGS", "") + " -q" 17 | 18 | class TestCase(): 19 | """ 20 | Runs specified circuit file and compares output against the provided reference trace file. 21 | """ 22 | 23 | def __init__(self, id, name): 24 | self.id = id 25 | self.name = name 26 | 27 | def fix_circ(self): 28 | old_data = None 29 | data = None 30 | with open(self.get_circ_path(), "rt") as test_circ: 31 | old_data = test_circ.read() 32 | import_regex = re.compile(rf"desc=\"(file#[^\"]*\b{self.id}\.circ)\"") 33 | correct_desc = f"desc=\"file#../{self.id}.circ\"" 34 | match = re.search(import_regex, old_data) 35 | if not match or match.group(0) == correct_desc: 36 | return 37 | print(f"Fixing bad import in {self.id}-test.circ") 38 | data = re.sub(import_regex, correct_desc, old_data) 39 | with open(self.get_circ_path(), "wt") as test_circ: 40 | test_circ.write(data) 41 | 42 | def get_circ_path(self): 43 | return os.path.join(tests_dir_path, f"{self.id}-test.circ") 44 | 45 | def get_expected_table_path(self): 46 | return os.path.join(tests_dir_path, "reference-output", f"{self.id}-test.out") 47 | 48 | def get_actual_table_path(self): 49 | return os.path.join(tests_dir_path, "student-output", f"{self.id}-test.out") 50 | 51 | def run(self): 52 | passed = False 53 | proc = None 54 | try: 55 | self.fix_circ() 56 | 57 | proc = subprocess.Popen(["java", "-jar", logisim_path, "-tty", "table,binary,tabs", self.get_circ_path()], stdout=subprocess.PIPE) 58 | 59 | with open(self.get_expected_table_path(), "r") as reference: 60 | passed = self.check_output(proc.stdout, reference) 61 | kill_proc(proc) 62 | if passed: 63 | return (True, "Matched expected output") 64 | else: 65 | return (False, "Did not match expected output") 66 | except KeyboardInterrupt: 67 | sys.exit(1) 68 | except SystemExit: 69 | raise 70 | except: 71 | traceback.print_exc() 72 | if proc: 73 | kill_proc(proc) 74 | return (False, "Errored while running test") 75 | 76 | def check_output(self, student, reference): 77 | passed = True 78 | student_lines = [] 79 | while True: 80 | student_line = student.readline().decode("ascii", errors="ignore").strip() 81 | reference_line = reference.readline().strip() 82 | if reference_line == "": 83 | break 84 | student_lines.append(student_line) 85 | if student_line != reference_line: 86 | passed = False 87 | output_path = self.get_actual_table_path() 88 | os.makedirs(os.path.dirname(output_path), mode=0o755, exist_ok=True) 89 | with open(output_path, "w") as f: 90 | for line in student_lines: 91 | f.write(f"{line}\n") 92 | return passed 93 | 94 | def kill_proc(proc): 95 | if proc.poll() == None: 96 | if sys.platform == "win32": 97 | os.kill(proc.pid, signal.CTRL_C_EVENT) 98 | for _ in range(10): 99 | if proc.poll() != None: 100 | break 101 | time.sleep(0.1) 102 | if proc.poll() == None: 103 | proc.kill() 104 | 105 | 106 | 107 | tests = [ 108 | TestCase("ex2", "Exercise 2: Sub-Circuits"), 109 | TestCase("ex3", "Exercise 3: Add Machine"), 110 | TestCase("ex4", "Exercise 4: Rotate") 111 | ] 112 | 113 | def run_tests(tests): 114 | print("Testing files...") 115 | tests_failed = 0 116 | tests_passed = 0 117 | 118 | for test in tests: 119 | did_pass, reason = test.run() 120 | if did_pass: 121 | print(f"PASSED test: {test.name}") 122 | tests_passed += 1 123 | else: 124 | print(f"FAILED test: {test.name} ({reason})") 125 | tests_failed += 1 126 | 127 | print(f"Passed {tests_passed}/{tests_failed + tests_passed} tests") 128 | 129 | if __name__ == '__main__': 130 | run_tests(tests) 131 | -------------------------------------------------------------------------------- /lab05/tests/ex2-test.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim-evolution (https://github.com/reds-heig/logisim-evolution). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | addr/data: 8 8 75 | 0 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 |
89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | addr/data: 3 6 260 | 24 12 1 37 0 3f 15 2a 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | -------------------------------------------------------------------------------- /lab05/tests/ex3-test.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim-evolution (https://github.com/reds-heig/logisim-evolution). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | addr/data: 8 8 75 | 0 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 |
89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | -------------------------------------------------------------------------------- /lab05/tests/ex4-test.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim-evolution (https://github.com/reds-heig/logisim-evolution). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | addr/data: 8 8 74 | 0 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | library ieee; 83 | use ieee.std_logic_1164.all; 84 | 85 | entity TCL_Generic is 86 | port( 87 | --Insert input ports below 88 | horloge_i : in std_logic; -- input bit example 89 | val_i : in std_logic_vector(3 downto 0); -- input vector example 90 | 91 | --Insert output ports below 92 | max_o : out std_logic; -- output bit example 93 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 94 | ); 95 | end TCL_Generic; 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 |
134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | -------------------------------------------------------------------------------- /lab05/tests/reference-output/ex2-test.out: -------------------------------------------------------------------------------- 1 | CYCLE A B C D SEL0 SEL1 NAND_OUT NOR_OUT XOR_OUT MUX2_OUT MUX4_OUT 2 | 000 0 0 1 0 0 1 1 1 0 0 1 3 | 001 0 1 0 0 1 0 1 0 1 1 1 4 | 010 1 0 0 0 0 0 1 0 1 1 1 5 | 011 1 1 1 0 1 1 0 0 0 1 0 6 | 100 0 0 0 0 0 0 1 1 0 0 0 7 | 101 1 1 1 1 1 1 0 0 0 1 1 8 | 110 1 0 1 0 1 0 1 0 1 0 0 9 | 111 0 1 0 1 0 1 1 0 1 0 0 10 | -------------------------------------------------------------------------------- /lab05/tests/reference-output/ex3-test.out: -------------------------------------------------------------------------------- 1 | CYCLE ADD_OUT REG_OUT 2 | 00000000 00000001 00000000 3 | 00000001 00000010 00000001 4 | 00000010 00000011 00000010 5 | 00000011 00000100 00000011 6 | 00000100 00000101 00000100 7 | 00000101 00000110 00000101 8 | 00000110 00000111 00000110 9 | 00000111 00001000 00000111 10 | 00001000 00001001 00001000 11 | 00001001 00001010 00001001 12 | 00001010 00001011 00001010 13 | 00001011 00001100 00001011 14 | 00001100 00001101 00001100 15 | 00001101 00001110 00001101 16 | 00001110 00001111 00001110 17 | 00001111 00010000 00001111 18 | -------------------------------------------------------------------------------- /lab05/tests/reference-output/ex4-test.out: -------------------------------------------------------------------------------- 1 | CYCLE ROTRIGHT_OUT 2 | 0000 1100011000000000 3 | 0001 0110001100000000 4 | 0010 0011000110000000 5 | 0011 0001100011000000 6 | 0100 0000110001100000 7 | 0101 0000011000110000 8 | 0110 0000001100011000 9 | 0111 0000000110001100 10 | 1000 0000000011000110 11 | 1001 0000000001100011 12 | 1010 1000000000110001 13 | 1011 1100000000011000 14 | 1100 0110000000001100 15 | 1101 0011000000000110 16 | 1110 0001100000000011 17 | 1111 1000110000000001 18 | -------------------------------------------------------------------------------- /lab06/.gitattributes: -------------------------------------------------------------------------------- 1 | /tests/reference-output/*.out text eol=lf 2 | /tests/student-output/*.out text eol=lf 3 | -------------------------------------------------------------------------------- /lab06/.gitignore: -------------------------------------------------------------------------------- 1 | /tests/student-output/*.out 2 | -------------------------------------------------------------------------------- /lab06/ex1.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim-evolution (https://github.com/reds-heig/logisim-evolution). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | addr/data: 8 8 74 | 0 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | library ieee; 83 | use ieee.std_logic_1164.all; 84 | 85 | entity TCL_Generic is 86 | port( 87 | --Insert input ports below 88 | horloge_i : in std_logic; -- input bit example 89 | val_i : in std_logic_vector(3 downto 0); -- input vector example 90 | 91 | --Insert output ports below 92 | max_o : out std_logic; -- output bit example 93 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 94 | ); 95 | end TCL_Generic; 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 |
133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | -------------------------------------------------------------------------------- /lab06/ex2.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim-evolution (https://github.com/reds-heig/logisim-evolution). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | addr/data: 8 8 74 | 0 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | library ieee; 83 | use ieee.std_logic_1164.all; 84 | 85 | entity TCL_Generic is 86 | port( 87 | --Insert input ports below 88 | horloge_i : in std_logic; -- input bit example 89 | val_i : in std_logic_vector(3 downto 0); -- input vector example 90 | 91 | --Insert output ports below 92 | max_o : out std_logic; -- output bit example 93 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 94 | ); 95 | end TCL_Generic; 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 |
133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | -------------------------------------------------------------------------------- /lab06/ex3.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim-evolution (https://github.com/reds-heig/logisim-evolution). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | addr/data: 8 8 77 | 0 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 |
90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | -------------------------------------------------------------------------------- /lab06/ex3.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/61c-teach/sp22-lab-starter/ff4f3b4c68c1c006950184fad157d3a7a885126f/lab06/ex3.txt -------------------------------------------------------------------------------- /lab06/ex4.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim-evolution (https://github.com/reds-heig/logisim-evolution). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | addr/data: 8 8 76 | 0 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 |
89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /lab06/ex4.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/61c-teach/sp22-lab-starter/ff4f3b4c68c1c006950184fad157d3a7a885126f/lab06/ex4.txt -------------------------------------------------------------------------------- /lab06/test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import re 5 | import signal 6 | import subprocess 7 | import sys 8 | import time 9 | import traceback 10 | 11 | lab_dir_path = os.getcwd() 12 | tests_dir_path = os.path.join(os.getcwd(), "tests") 13 | logisim_path = os.path.join(os.getcwd(),"..", "tools", "logisim-evolution.jar") 14 | 15 | # logisim_env = os.environ.copy() 16 | # logisim_env["CS61C_TOOLS_ARGS"] = logisim_env.get("CS61C_TOOLS_ARGS", "") + " -q" 17 | 18 | class TestCase(): 19 | """ 20 | Runs specified circuit file and compares output against the provided reference trace file. 21 | """ 22 | 23 | def __init__(self, id, name): 24 | self.id = id 25 | self.name = name 26 | 27 | def fix_circ(self): 28 | old_data = None 29 | data = None 30 | with open(self.get_circ_path(), "rt") as test_circ: 31 | old_data = test_circ.read() 32 | import_regex = re.compile(rf"desc=\"(file#[^\"]*\b{self.id}\.circ)\"") 33 | correct_desc = f"desc=\"file#../{self.id}.circ\"" 34 | match = re.search(import_regex, old_data) 35 | if not match or match.group(0) == correct_desc: 36 | return 37 | print(f"Fixing bad import in {self.id}-test.circ") 38 | data = re.sub(import_regex, correct_desc, old_data) 39 | with open(self.get_circ_path(), "wt") as test_circ: 40 | test_circ.write(data) 41 | 42 | def get_circ_path(self): 43 | return os.path.join(tests_dir_path, f"{self.id}-test.circ") 44 | 45 | def get_expected_table_path(self): 46 | return os.path.join(tests_dir_path, "reference-output", f"{self.id}-test.out") 47 | 48 | def get_actual_table_path(self): 49 | return os.path.join(tests_dir_path, "student-output", f"{self.id}-test.out") 50 | 51 | def run(self): 52 | passed = False 53 | proc = None 54 | try: 55 | self.fix_circ() 56 | 57 | proc = subprocess.Popen(["java", "-jar", logisim_path, "-tty", "table,binary,csv", self.get_circ_path()], stdout=subprocess.PIPE) 58 | 59 | with open(self.get_expected_table_path(), "r") as reference: 60 | passed = self.check_output(proc.stdout, reference) 61 | kill_proc(proc) 62 | if passed: 63 | return (True, "Matched expected output") 64 | else: 65 | return (False, "Did not match expected output") 66 | except KeyboardInterrupt: 67 | sys.exit(1) 68 | except SystemExit: 69 | raise 70 | except: 71 | traceback.print_exc() 72 | if proc: 73 | kill_proc(proc) 74 | return (False, "Errored while running test") 75 | 76 | def check_output(self, student, reference): 77 | passed = True 78 | student_lines = [] 79 | while True: 80 | student_line = student.readline().decode("ascii", errors="ignore").strip() 81 | reference_line = reference.readline().strip() 82 | if reference_line == "": 83 | break 84 | student_lines.append(student_line) 85 | if student_line != reference_line: 86 | passed = False 87 | output_path = self.get_actual_table_path() 88 | os.makedirs(os.path.dirname(output_path), mode=0o755, exist_ok=True) 89 | with open(output_path, "w") as f: 90 | for line in student_lines: 91 | f.write(f"{line}\n") 92 | return passed 93 | 94 | def kill_proc(proc): 95 | if proc.poll() == None: 96 | proc.terminate() 97 | for _ in range(10): 98 | if proc.poll() != None: 99 | return 100 | time.sleep(0.1) 101 | if proc.poll() == None: 102 | proc.kill() 103 | 104 | 105 | 106 | tests = [ 107 | TestCase("ex1", "Exercise 1: Immediate Generator"), 108 | TestCase("ex2", "Exercise 2: BrUn"), 109 | TestCase("ex4", "Exercise 4: Pipe that Line") 110 | ] 111 | 112 | def run_tests(tests): 113 | print("Testing files...") 114 | tests_failed = 0 115 | tests_passed = 0 116 | 117 | for test in tests: 118 | did_pass, reason = test.run() 119 | if did_pass: 120 | print(f"PASSED test: {test.name}") 121 | tests_passed += 1 122 | else: 123 | print(f"FAILED test: {test.name} ({reason})") 124 | tests_failed += 1 125 | 126 | print(f"Passed {tests_passed}/{tests_failed + tests_passed} tests") 127 | 128 | if __name__ == '__main__': 129 | run_tests(tests) 130 | -------------------------------------------------------------------------------- /lab06/tests/ex1-test.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim-evolution (https://github.com/reds-heig/logisim-evolution). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | addr/data: 8 8 74 | 0 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | library ieee; 83 | use ieee.std_logic_1164.all; 84 | 85 | entity TCL_Generic is 86 | port( 87 | --Insert input ports below 88 | horloge_i : in std_logic; -- input bit example 89 | val_i : in std_logic_vector(3 downto 0); -- input vector example 90 | 91 | --Insert output ports below 92 | max_o : out std_logic; -- output bit example 93 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 94 | ); 95 | end TCL_Generic; 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 |
134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | addr/data: 2 32 253 | 542023 4542223 fe542823 fa542623 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | -------------------------------------------------------------------------------- /lab06/tests/ex2-test.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim-evolution (https://github.com/reds-heig/logisim-evolution). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | addr/data: 8 8 74 | 0 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | library ieee; 83 | use ieee.std_logic_1164.all; 84 | 85 | entity TCL_Generic is 86 | port( 87 | --Insert input ports below 88 | horloge_i : in std_logic; -- input bit example 89 | val_i : in std_logic_vector(3 downto 0); -- input vector example 90 | 91 | --Insert output ports below 92 | max_o : out std_logic; -- output bit example 93 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 94 | ); 95 | end TCL_Generic; 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 |
134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | addr/data: 2 32 252 | 56544063 65645063 56546063 56547063 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | -------------------------------------------------------------------------------- /lab06/tests/ex4-test.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim-evolution (https://github.com/reds-heig/logisim-evolution). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | addr/data: 8 8 76 | 0 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 |
90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | addr/data: 4 8 245 | 3 2 fc 1 2 fb 1 246 | 247 | 248 | 249 | 250 | 251 | 252 | addr/data: 4 8 253 | 4 5 70 9 d c 2 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | -------------------------------------------------------------------------------- /lab06/tests/reference-output/ex1-test.out: -------------------------------------------------------------------------------- 1 | CYCLE,INSTRUCTION,IMMEDIATE 2 | 00,00000000010101000010000000100011,00000000000000000000000000000000 3 | 01,00000100010101000010001000100011,00000000000000000000000001000100 4 | 10,11111110010101000010100000100011,11111111111111111111111111110000 5 | 11,11111010010101000010011000100011,11111111111111111111111110101100 6 | -------------------------------------------------------------------------------- /lab06/tests/reference-output/ex2-test.out: -------------------------------------------------------------------------------- 1 | CYCLE,INSTRUCTION,BrUn 2 | 00,01010110010101000100000001100011,0 3 | 01,01100101011001000101000001100011,0 4 | 10,01010110010101000110000001100011,1 5 | 11,01010110010101000111000001100011,1 6 | -------------------------------------------------------------------------------- /lab06/tests/reference-output/ex4-test.out: -------------------------------------------------------------------------------- 1 | CYCLE,OUT1,IN1,IN2 2 | 0000,00000000,00000011,00000100 3 | 0001,00000000,00000010,00000101 4 | 0010,00001100,11111100,01110000 5 | 0011,00010110,00000001,00001001 6 | 0100,01010110,00000010,00001101 7 | 0101,01011111,11111011,00001100 8 | 0110,01111001,00000001,00000010 9 | 0111,00111101,00000000,00000000 10 | 1000,00111111,00000000,00000000 11 | 1001,00111111,00000000,00000000 12 | 1010,00111111,00000000,00000000 13 | -------------------------------------------------------------------------------- /lab07/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | LD=gcc 3 | CFLAGS=-ggdb -Wall -pedantic -std=gnu99 -O3 4 | LDFLAGS= 5 | 6 | EX2_PROG=matrixMultiply 7 | 8 | EX3_OBJS=transpose.o test_transpose.o 9 | EX3_PROG=transpose 10 | 11 | ex2: 12 | $(CC) -o $(EX2_PROG) $(CFLAGS) $(EX2_PROG).c 13 | ./$(EX2_PROG) 14 | 15 | ex3: $(EX3_OBJS) 16 | $(CC) -o $(EX3_PROG) $(CFLAGS) $(EX3_OBJS) 17 | 18 | clean: 19 | -rm -rf core *.o *~ "#"*"#" Makefile.bak $(PROGS) *.dSYM 20 | 21 | -------------------------------------------------------------------------------- /lab07/cache.s: -------------------------------------------------------------------------------- 1 | # void accessWords(int array_size, int step_size, int rep_count, int option) { 2 | # for (int k = 0; k < rep_count; k++) { 3 | # for (int index = 0; index < array_size; index += step_size) { 4 | # if (option == 0) 5 | # array[index] = 0; // Option 0: One cache access - write 6 | # else 7 | # array[index] = array[index] + 1; // Option 1: Two cache accesses - read AND write 8 | # } 9 | # } 10 | # } 11 | 12 | # int main() { 13 | # int array_size = 256; 14 | # int step_size = 2; 15 | # int rep_count = 1; 16 | # int option = 1; 17 | # accessWords(array_size, step_size, rep_count, option); 18 | # return 0; 19 | # } 20 | 21 | .data 22 | array: .word 2048 # max array size specified in BYTES (DO NOT CHANGE) 23 | 24 | .text 25 | main: li a0, 128 # array size in BYTES (should be a power of 2 < array size) 26 | li a1, 1 # step size (should be a power of 2 > 0) 27 | li a2, 1 # rep count (int > 0) 28 | li a3, 0 # 0 = option 0, 1 = option 1 29 | jal accessWords 30 | li a0, 10 # exit 31 | ecall 32 | 33 | # Arguments: 34 | # a0 = array size in bytes 35 | # a1 = step size 36 | # a2 = number of times to repeat 37 | # a3 = option: 0 (write) / 1 (read and write) 38 | accessWords: 39 | la s0, array # ptr to array 40 | add s1, s0, a0 # array size 41 | slli t1, a1, 2 # multiply stepsize by 4 because the size of an int is 4 bytes 42 | wordLoop: 43 | beq a3, zero, optionZero 44 | # Option 1: 45 | lw t0, 0(s0) 46 | addi t0, t0, 1 47 | sw t0, 0(s0) 48 | j wordCheck 49 | optionZero: 50 | sw zero, 0(s0) 51 | wordCheck: 52 | add s0, s0, t1 # increment ptr 53 | blt s0, s1, wordLoop # inner loop done? 54 | addi a2, a2, -1 55 | bgtz a2, accessWords # outer loop done? 56 | jr ra -------------------------------------------------------------------------------- /lab07/matrixMultiply.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | /* To save you time, we are including all 6 variants of the loop ordering 8 | as separate functions and then calling them using function pointers. 9 | The reason for having separate functions that are nearly identical is 10 | to avoid counting any extraneous processing towards the computation 11 | time. This includes I/O accesses (printf) and conditionals (if/switch). 12 | I/O accesses are slow and conditional/branching statements could 13 | unfairly bias results (lower cases in switches must run through more 14 | case statements on each iteration). 15 | */ 16 | void multMat1( int n, float *A, float *B, float *C ) { 17 | int i,j,k; 18 | /* This is ijk loop order. */ 19 | for( i = 0; i < n; i++ ) 20 | for( j = 0; j < n; j++ ) 21 | for( k = 0; k < n; k++ ) 22 | C[i+j*n] += A[i+k*n]*B[k+j*n]; 23 | } 24 | 25 | void multMat2( int n, float *A, float *B, float *C ) { 26 | int i,j,k; 27 | /* This is ikj loop order. */ 28 | for( i = 0; i < n; i++ ) 29 | for( k = 0; k < n; k++ ) 30 | for( j = 0; j < n; j++ ) 31 | C[i+j*n] += A[i+k*n]*B[k+j*n]; 32 | } 33 | 34 | void multMat3( int n, float *A, float *B, float *C ) { 35 | int i,j,k; 36 | /* This is jik loop order. */ 37 | for( j = 0; j < n; j++ ) 38 | for( i = 0; i < n; i++ ) 39 | for( k = 0; k < n; k++ ) 40 | C[i+j*n] += A[i+k*n]*B[k+j*n]; 41 | } 42 | 43 | void multMat4( int n, float *A, float *B, float *C ) { 44 | int i,j,k; 45 | /* This is jki loop order. */ 46 | for( j = 0; j < n; j++ ) 47 | for( k = 0; k < n; k++ ) 48 | for( i = 0; i < n; i++ ) 49 | C[i+j*n] += A[i+k*n]*B[k+j*n]; 50 | } 51 | 52 | void multMat5( int n, float *A, float *B, float *C ) { 53 | int i,j,k; 54 | /* This is kij loop order. */ 55 | for( k = 0; k < n; k++ ) 56 | for( i = 0; i < n; i++ ) 57 | for( j = 0; j < n; j++ ) 58 | C[i+j*n] += A[i+k*n]*B[k+j*n]; 59 | } 60 | 61 | void multMat6( int n, float *A, float *B, float *C ) { 62 | int i,j,k; 63 | /* This is kji loop order. */ 64 | for( k = 0; k < n; k++ ) 65 | for( j = 0; j < n; j++ ) 66 | for( i = 0; i < n; i++ ) 67 | C[i+j*n] += A[i+k*n]*B[k+j*n]; 68 | } 69 | 70 | /* uses timing features from sys/time.h that you haven't seen before */ 71 | int main( int argc, char **argv ) { 72 | int nmax = 1000,i; 73 | 74 | void (*orderings[])(int,float *,float *,float *) = 75 | {&multMat1,&multMat2,&multMat3,&multMat4,&multMat5,&multMat6}; 76 | char *names[] = {"ijk","ikj","jik","jki","kij","kji"}; 77 | 78 | float *A = (float *)malloc( nmax*nmax * sizeof(float)); 79 | float *B = (float *)malloc( nmax*nmax * sizeof(float)); 80 | float *C = (float *)malloc( nmax*nmax * sizeof(float)); 81 | 82 | struct timeval start, end; 83 | 84 | /* fill matrices with random numbers */ 85 | for( i = 0; i < nmax*nmax; i++ ) A[i] = drand48()*2-1; 86 | for( i = 0; i < nmax*nmax; i++ ) B[i] = drand48()*2-1; 87 | for( i = 0; i < nmax*nmax; i++ ) C[i] = drand48()*2-1; 88 | 89 | for( i = 0; i < 6; i++) { 90 | /* multiply matrices and measure the time */ 91 | gettimeofday( &start, NULL ); 92 | (*orderings[i])( nmax, A, B, C ); 93 | gettimeofday( &end, NULL ); 94 | 95 | /* convert time to Gflop/s */ 96 | double seconds = (end.tv_sec - start.tv_sec) + 97 | 1.0e-6 * (end.tv_usec - start.tv_usec); 98 | double Gflops = 2e-9*nmax*nmax*nmax/seconds; 99 | printf( "%s:\tn = %d, %.3f Gflop/s\n", names[i], nmax, Gflops ); 100 | } 101 | 102 | free( A ); 103 | free( B ); 104 | free( C ); 105 | 106 | printf("\n\n"); 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /lab07/test_transpose.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "transpose.h" 6 | 7 | double benchmark(int *A, int *B, int n, int blocksize, 8 | void (*transpose)(int, int, int*, int*), char *description) { 9 | 10 | int i, j; 11 | 12 | /* initialize A,B to random integers */ 13 | srand48( time( NULL ) ); 14 | for( i = 0; i < n*n; i++ ) A[i] = lrand48( ); 15 | for( i = 0; i < n*n; i++ ) B[i] = lrand48( ); 16 | 17 | /* measure performance */ 18 | struct timeval start, end; 19 | 20 | gettimeofday( &start, NULL ); 21 | transpose( n, blocksize, B, A ); 22 | gettimeofday( &end, NULL ); 23 | 24 | double seconds = (end.tv_sec - start.tv_sec) + 25 | 1.0e-6 * (end.tv_usec - start.tv_usec); 26 | 27 | /* check correctness */ 28 | for( i = 0; i < n; i++ ) { 29 | for( j = 0; j < n; j++ ) { 30 | if( B[j+i*n] != A[i+j*n] ) { 31 | printf("Error!!!! Transpose does not result in correct answer!!\n"); 32 | exit( -1 ); 33 | } 34 | } 35 | } 36 | 37 | return seconds*1e3; 38 | } 39 | 40 | int main( int argc, char **argv ) { 41 | 42 | int n = 12000; 43 | int blocksize = 80; 44 | 45 | /* allocate an n*n block of integers for the matrices */ 46 | int *A = (int*)malloc( n*n*sizeof(int) ); 47 | int *B = (int*)malloc( n*n*sizeof(int) ); 48 | 49 | /* run tests */ 50 | double time1 = benchmark(A, B, n, blocksize, transpose_naive, "naive transpose"); 51 | double time2 = benchmark(A, B, n, blocksize, transpose_blocking, "transpose with blocking"); 52 | 53 | /* release resources */ 54 | free( A ); 55 | free( B ); 56 | 57 | printf("testing n = %d, blocksize = %d\n", n, blocksize); 58 | printf("naive: %g milliseconds\n", time1); 59 | printf("student: %g milliseconds\n", time2); 60 | if ((time1 - time2) < 250) { 61 | printf("insufficient speedup\n"); 62 | return -1; 63 | } 64 | printf("Speedup sufficient\n"); 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /lab07/transpose.c: -------------------------------------------------------------------------------- 1 | #include "transpose.h" 2 | 3 | /* The naive transpose function as a reference. */ 4 | void transpose_naive(int n, int blocksize, int *dst, int *src) { 5 | for (int x = 0; x < n; x++) { 6 | for (int y = 0; y < n; y++) { 7 | dst[y + x * n] = src[x + y * n]; 8 | } 9 | } 10 | } 11 | 12 | /* Implement cache blocking below. You should NOT assume that n is a 13 | * multiple of the block size. */ 14 | void transpose_blocking(int n, int blocksize, int *dst, int *src) { 15 | // YOUR CODE HERE 16 | } 17 | -------------------------------------------------------------------------------- /lab07/transpose.h: -------------------------------------------------------------------------------- 1 | void transpose_naive(int n, int blocksize, int *dst, int *src); 2 | void transpose_blocking(int n, int blocksize, int *dst, int *src); 3 | -------------------------------------------------------------------------------- /lab08/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=--std=c99 -Wall -O0 3 | 4 | simd: test_simd.o simd.o 5 | $(CC) $(CFLAGS) -o simd test_simd.o simd.o 6 | 7 | test_simd.o: simd.c simd.h 8 | $(CC) $(CFLAGS) -c test_simd.c 9 | 10 | simd.o: simd.c simd.h 11 | $(CC) $(CFLAGS) -c simd.c 12 | 13 | clean: 14 | rm -f simd 15 | rm -f *.o 16 | -------------------------------------------------------------------------------- /lab08/simd.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "simd.h" 5 | 6 | long long int sum(int vals[NUM_ELEMS]) { 7 | clock_t start = clock(); 8 | 9 | long long int sum = 0; 10 | for(unsigned int w = 0; w < OUTER_ITERATIONS; w++) { 11 | for(unsigned int i = 0; i < NUM_ELEMS; i++) { 12 | if(vals[i] >= 128) { 13 | sum += vals[i]; 14 | } 15 | } 16 | } 17 | clock_t end = clock(); 18 | printf("Time taken: %Lf s\n", (long double)(end - start) / CLOCKS_PER_SEC); 19 | return sum; 20 | } 21 | 22 | long long int sum_unrolled(int vals[NUM_ELEMS]) { 23 | clock_t start = clock(); 24 | long long int sum = 0; 25 | 26 | for(unsigned int w = 0; w < OUTER_ITERATIONS; w++) { 27 | for(unsigned int i = 0; i < NUM_ELEMS / 4 * 4; i += 4) { 28 | if(vals[i] >= 128) sum += vals[i]; 29 | if(vals[i + 1] >= 128) sum += vals[i + 1]; 30 | if(vals[i + 2] >= 128) sum += vals[i + 2]; 31 | if(vals[i + 3] >= 128) sum += vals[i + 3]; 32 | } 33 | 34 | // TAIL CASE, for when NUM_ELEMS isn't a multiple of 4 35 | // NUM_ELEMS / 4 * 4 is the largest multiple of 4 less than NUM_ELEMS 36 | // Order is important, since (NUM_ELEMS / 4) effectively rounds down first 37 | for(unsigned int i = NUM_ELEMS / 4 * 4; i < NUM_ELEMS; i++) { 38 | if (vals[i] >= 128) { 39 | sum += vals[i]; 40 | } 41 | } 42 | } 43 | clock_t end = clock(); 44 | printf("Time taken: %Lf s\n", (long double)(end - start) / CLOCKS_PER_SEC); 45 | return sum; 46 | } 47 | 48 | long long int sum_simd(int vals[NUM_ELEMS]) { 49 | clock_t start = clock(); 50 | __m128i _127 = _mm_set1_epi32(127); // This is a vector with 127s in it... Why might you need this? 51 | long long int result = 0; // This is where you should put your final result! 52 | /* DO NOT MODIFY ANYTHING ABOVE THIS LINE (in this function) */ 53 | 54 | for(unsigned int w = 0; w < OUTER_ITERATIONS; w++) { 55 | /* YOUR CODE GOES HERE */ 56 | 57 | /* Hint: you'll need a tail case. */ 58 | } 59 | 60 | /* DO NOT MODIFY ANYTHING BELOW THIS LINE (in this function) */ 61 | clock_t end = clock(); 62 | printf("Time taken: %Lf s\n", (long double)(end - start) / CLOCKS_PER_SEC); 63 | return result; 64 | } 65 | 66 | long long int sum_simd_unrolled(int vals[NUM_ELEMS]) { 67 | clock_t start = clock(); 68 | __m128i _127 = _mm_set1_epi32(127); 69 | long long int result = 0; 70 | /* DO NOT MODIFY ANYTHING ABOVE THIS LINE (in this function) */ 71 | 72 | for(unsigned int w = 0; w < OUTER_ITERATIONS; w++) { 73 | /* YOUR CODE GOES HERE */ 74 | /* Copy your sum_simd() implementation here, and unroll it */ 75 | 76 | /* Hint: you'll need 1 or maybe 2 tail cases here. */ 77 | } 78 | 79 | /* DO NOT MODIFY ANYTHING BELOW THIS LINE (in this function) */ 80 | clock_t end = clock(); 81 | printf("Time taken: %Lf s\n", (long double)(end - start) / CLOCKS_PER_SEC); 82 | return result; 83 | } 84 | -------------------------------------------------------------------------------- /lab08/simd.h: -------------------------------------------------------------------------------- 1 | #ifndef SIMD_H 2 | #define SIMD_H 3 | 4 | #include 5 | 6 | #define NUM_ELEMS ((1 << 16) + 10) 7 | #define OUTER_ITERATIONS (1 << 14) 8 | 9 | long long int sum(int vals[NUM_ELEMS]); 10 | 11 | long long int sum_unrolled(int vals[NUM_ELEMS]); 12 | 13 | long long int sum_simd(int vals[NUM_ELEMS]); 14 | 15 | long long int sum_simd_unrolled(int vals[NUM_ELEMS]); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /lab08/test_simd.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "simd.h" 5 | 6 | /* ***DON'T MODIFY THIS FILE! You should only need to modify simd.c!*** */ 7 | 8 | int main(int argc, char* argv[]) { 9 | printf("Let's generate a randomized array.\n"); 10 | int vals[NUM_ELEMS]; 11 | long long int reference; 12 | long long int simd; 13 | long long int simdu; 14 | for (unsigned int i = 0; i < NUM_ELEMS; i++) vals[i] = rand() % 256; 15 | int success = 0; 16 | 17 | printf("Starting randomized sum.\n"); 18 | clock_t start = clock(); 19 | reference = sum(vals); 20 | clock_t end = clock(); 21 | printf("Sum: %lld\n\n", reference); 22 | clock_t reft = end - start; 23 | 24 | printf("Starting randomized unrolled sum.\n"); 25 | printf("Sum: %lld\n\n", sum_unrolled(vals)); 26 | 27 | printf("Starting randomized SIMD sum.\n"); 28 | start = clock(); 29 | simd = sum_simd(vals); 30 | end = clock(); 31 | printf("Sum: %lld\n\n", simd); 32 | clock_t simdt = end - start; 33 | 34 | if (simd != reference) { 35 | printf("Test Failed! SIMD sum %lld doesn't match reference sum %lld!\n\n", simd, reference); 36 | success = 1; 37 | } 38 | 39 | if (reft <= simdt * 2) { 40 | printf("Test Failed! SIMD sum provided less than 2X speedup.\n\n"); 41 | success = 1; 42 | } 43 | 44 | printf("Starting randomized SIMD unrolled sum.\n"); 45 | start = clock(); 46 | simdu = sum_simd_unrolled(vals); 47 | end = clock(); 48 | printf("Sum: %lld\n\n", simdu); 49 | clock_t simdut = end - start; 50 | 51 | if (simdu != reference) { 52 | printf("Test Failed! SIMD_UNROLLED sum %lld doesn't match reference sum %lld!\n\n", simdu, reference); 53 | success = 1; 54 | } 55 | 56 | if (simdt <= simdut) { 57 | printf("Test Failed! SIMD unrolled function provided no speedup.\n\n"); 58 | success = 1; 59 | } 60 | 61 | if (!success) { 62 | printf("All tests Passed! Correct values were produced, and speedups were achieved!\n\n"); 63 | return 0; 64 | } else { 65 | return 1; 66 | } 67 | } -------------------------------------------------------------------------------- /lab09/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS= -std=gnu99 -c -fopenmp 3 | LDFLAGS=-fopenmp 4 | OBJECTS=$(SOURCES:.c=.o) 5 | EXECUTABLES=hello v_add dotp 6 | 7 | .PHONY: all clean 8 | 9 | all: $(EXECUTABLES) 10 | 11 | hello: hello.o 12 | dotp: dotp.o omp_apps.o 13 | v_add: v_add.o omp_apps.o 14 | 15 | $(EXECUTABLES): 16 | $(CC) $(LDFLAGS) $^ -o $@ 17 | 18 | %.o: %.c 19 | $(CC) $(CFLAGS) $< -o $@ 20 | 21 | clean: 22 | rm -f $(EXECUTABLES) *.o 23 | -------------------------------------------------------------------------------- /lab09/dotp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "omp_apps.h" 5 | 6 | int main() { 7 | // Generate input vectors 8 | double *x = gen_array(ARRAY_SIZE); 9 | double *y = gen_array(ARRAY_SIZE); 10 | double serial_result = 0.0; 11 | double result; 12 | 13 | double naive = 0.0; 14 | double man_min = 100.0; 15 | double red_min = 100.0; 16 | 17 | double start_time, run_time; 18 | 19 | // calculate result serially 20 | for(int i=0; i 0.001) { 45 | printf("Manual optimized does not match reference.\n"); 46 | return -1; 47 | } 48 | 49 | if (run_time < man_min) { 50 | man_min = run_time; 51 | } 52 | 53 | printf("Manual Optimized: %d thread(s) took %f seconds\n",i,run_time); 54 | } 55 | 56 | if (man_min * 9 > naive) { 57 | printf("Fastest manual optimized didn't achieve at least 9x speedup from naive.\n"); 58 | return -1; 59 | } 60 | 61 | 62 | for (int i=1; i<=num_threads; i++) { 63 | omp_set_num_threads(i); 64 | start_time = omp_get_wtime(); 65 | for(int j=0; j 0.001) { 72 | printf("Reduction optimized does not match reference.\n"); 73 | return -1; 74 | } 75 | 76 | if (run_time < red_min) { 77 | red_min = run_time; 78 | } 79 | 80 | printf("Reduction Optimized: %d thread(s) took %f seconds\n",i,run_time); 81 | } 82 | 83 | if (red_min * 9 > naive) { 84 | printf("Fastest reduction optimized didn't achieve at least 9x speedup from naive.\n"); 85 | return -1; 86 | } 87 | 88 | printf("Congrats! All dotp tests passed\n"); 89 | 90 | return 0; 91 | } -------------------------------------------------------------------------------- /lab09/hello.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | #pragma omp parallel 6 | { 7 | int thread_ID = omp_get_thread_num(); 8 | printf(" hello world %d\n", thread_ID); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lab09/omp_apps.c: -------------------------------------------------------------------------------- 1 | #include "omp_apps.h" 2 | 3 | /* -------------------------------Utilties, Do Not Modify------------------------------*/ 4 | double* gen_array(int n) { 5 | double* array = (double*)malloc(n * sizeof(double)); 6 | for (int i = 0; i < n; i++) array[i] = drand48(); 7 | return array; 8 | } 9 | 10 | int verify(double* x, double* y, void(*funct)(double *x, double *y, double *z)) { 11 | double *z_v_add = (double*) malloc(ARRAY_SIZE*sizeof(double)); 12 | double *z_oracle = (double*) malloc(ARRAY_SIZE*sizeof(double)); 13 | (*funct)(x, y, z_v_add); 14 | for(int i=0; i 0.001) { 97 | pos += sprintf(pos, "Incorrect result!\n"); 98 | *pos = '\0'; 99 | return report_buf; 100 | } 101 | } 102 | 103 | for (int i = 1; i <= num_threads; i++) { 104 | omp_set_num_threads(i); 105 | start_time = omp_get_wtime(); 106 | 107 | for (int j = 0; j < REPEAT; j++) { 108 | result = dotp_reduction_optimized(x, y, arr_size); 109 | } 110 | 111 | run_time = omp_get_wtime() - start_time; 112 | pos += sprintf(pos, "Reduction Optimized: %d thread(s) took %f seconds\n", 113 | i, run_time); 114 | 115 | // verify result is correct (within some threshold) 116 | if (fabs(serial_result - result) > 0.001) { 117 | pos += sprintf(pos, "Incorrect result!\n"); 118 | *pos = '\0'; 119 | return report_buf; 120 | } 121 | } 122 | 123 | // Only run this once because it's too slow.. 124 | omp_set_num_threads(1); 125 | start_time = omp_get_wtime(); 126 | for (int j = 0; j < REPEAT; j++) result = dotp_naive(x, y, arr_size); 127 | run_time = omp_get_wtime() - start_time; 128 | 129 | pos += sprintf(pos, "Naive: %d thread(s) took %f seconds\n", 1, run_time); 130 | *pos = '\0'; 131 | return report_buf; 132 | } 133 | -------------------------------------------------------------------------------- /lab09/omp_apps.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef OMP_APPS_H 3 | #define OMP_APPS_H 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define REPEAT 60 12 | #define BUF_SIZE 8192 13 | 14 | #define ARRAY_SIZE 5000000 15 | 16 | void v_add_naive(double* x, double* y, double* z); 17 | void v_add_optimized_adjacent(double* x, double* y, double* z); 18 | void v_add_optimized_chunks(double* x, double* y, double* z); 19 | double dotp_naive(double* x, double* y, int arr_size); 20 | double dotp_manual_optimized(double* x, double* y, int arr_size); 21 | double dotp_reduction_optimized(double* x, double* y, int arr_size); 22 | 23 | double* gen_array(int n); 24 | int verify(double* x, double* y, void(*funct)(double *x, double *y, double *z)); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /lab09/v_add.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "omp_apps.h" 5 | 6 | int main() { 7 | // Generate input vectors and destination vector 8 | double *x = gen_array(ARRAY_SIZE); 9 | double *y = gen_array(ARRAY_SIZE); 10 | double *z = (double*) malloc(ARRAY_SIZE*sizeof(double)); 11 | 12 | // Test framework that sweeps the number of threads and times each run 13 | double start_time, run_time; 14 | int num_threads = omp_get_max_threads(); 15 | 16 | double naive_max; 17 | double adj_min = 100.0; 18 | double chunks_min = 100.0; 19 | 20 | double adj_total = 0.0; 21 | double chunks_total = 0.0; 22 | 23 | // naive benchmark 24 | omp_set_num_threads(num_threads); 25 | start_time = omp_get_wtime(); 26 | for(int j=0; j naive_max) { 56 | printf("Fastest adjacent runtime didn't provide at least 2x speedup from naive benchmark.\n"); 57 | return -1; 58 | } 59 | 60 | for (int i=1; i<=num_threads; i++) { 61 | omp_set_num_threads(i); 62 | start_time = omp_get_wtime(); 63 | for(int j=0; j naive_max) { 81 | printf("Fastest chunks runtime didn't provide at least 2x speedup from naive benchmark.\n"); 82 | return -1; 83 | } 84 | 85 | if (chunks_total > adj_total) { 86 | printf("Chunks didn't have better performance than adjacent.\n"); 87 | return -1; 88 | } 89 | 90 | printf("Congrats! All vector tests passed!\n"); 91 | 92 | return 0; 93 | } -------------------------------------------------------------------------------- /tools/logisim-evolution.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/61c-teach/sp22-lab-starter/ff4f3b4c68c1c006950184fad157d3a7a885126f/tools/logisim-evolution.jar -------------------------------------------------------------------------------- /tools/venus.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/61c-teach/sp22-lab-starter/ff4f3b4c68c1c006950184fad157d3a7a885126f/tools/venus.jar --------------------------------------------------------------------------------