├── .gitattributes ├── .gitignore ├── README.md ├── lab00 ├── answers.txt └── first_set.txt ├── lab01 ├── .gitignore ├── eccentric.c ├── gdb.txt ├── hello.c ├── interactive_hello.c ├── ll_cycle.c ├── ll_cycle.h ├── no_segfault_ex.c ├── segfault_ex.c └── test_ll_cycle.c ├── lab02 ├── Makefile ├── bit_ops.c ├── bit_ops.h ├── lfsr.c ├── lfsr.h ├── make.txt ├── test_bit_ops.c ├── test_lfsr.c ├── vector-test.c ├── vector.c └── vector.h ├── lab03 ├── cc_test.s ├── ex1.s ├── ex2.c ├── ex2.s ├── factorial.s └── list_map.s ├── lab04 ├── discrete_fn.s └── megalistmanips.s ├── lab05 ├── ex1.circ ├── ex2.circ ├── ex3.circ ├── ex4.circ ├── ex5.circ ├── logisim-evolution.jar ├── test.sh └── testing │ ├── circ_files │ ├── ex1_test.circ │ ├── ex2_test.circ │ ├── ex3_test.circ │ ├── ex4_test.circ │ └── ex5_test.circ │ ├── logisim-evolution.jar │ ├── reference_output │ ├── ex1_test.out │ ├── ex2_test.out │ ├── ex3_test.out │ ├── ex4_test.out │ └── ex5_test.out │ └── test.py ├── lab06 ├── ROMdata └── ex1.circ ├── lab07 ├── Makefile ├── cache.s ├── exercise1.txt ├── exercise2.txt ├── exercise3.txt ├── matrixMultiply.c ├── test_transpose.c ├── transpose.c └── transpose.h ├── lab08 └── answers.txt ├── lab09 ├── Makefile ├── simd.c ├── simd.h └── test_simd.c ├── lab10 ├── .gitignore ├── Makefile ├── assets │ ├── process.png │ ├── sample_output.jpg │ └── threads.png ├── dotp.c ├── files │ ├── fruit.bmp │ ├── girl.bmp │ ├── index.html │ ├── lena.bmp │ ├── monarch.bmp │ ├── my_documents │ │ ├── click_here.txt │ │ ├── credit.txt │ │ ├── git-poem.jpg │ │ ├── multi-processing.jpeg │ │ ├── multithread-everything.jpeg │ │ ├── style.css │ │ ├── theslowwinter.pdf │ │ └── wholesome_facts.txt │ ├── template.html │ └── test.bmp ├── hello.c ├── libbmp │ ├── libbmp.c │ └── libbmp.h ├── libhttp │ ├── libhttp.c │ └── libhttp.h ├── omp_apps.c ├── omp_apps.h ├── server.c ├── server_utils.c ├── server_utils.h ├── timer.sh └── v_add.c ├── lab11 ├── Makefile ├── createIndices.py ├── mostPopular.py ├── perWordDocumentCount.py ├── seqFiles │ ├── billOfRights.txt.seq │ └── complete-works-mark-twain.txt.seq ├── submit ├── textFiles │ ├── billOfRights.txt │ └── complete-works-mark-twain.txt ├── textImporter │ ├── Importer.java │ └── wc.jar └── wordCount.py └── tools └── venus.jar /.gitattributes: -------------------------------------------------------------------------------- 1 | *.c text eol=lf 2 | *.h text eol=lf 3 | *.md text eol=lf 4 | *.s text eol=lf 5 | *.sh text eol=lf 6 | *.txt text eol=lf 7 | Makefile text eol=lf 8 | -------------------------------------------------------------------------------- /.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 | 252 | # lab13 program 253 | server_basic server_process 254 | **/*._sobel.bmp 255 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fa20-lab 2 | -------------------------------------------------------------------------------- /lab00/answers.txt: -------------------------------------------------------------------------------- 1 | 1. 2 | 2. 3 | 3. 4 | 4. 5 | -------------------------------------------------------------------------------- /lab00/first_set.txt: -------------------------------------------------------------------------------- 1 | Which command walks a file hierarchy in search of a keyword? 2 | Which command displays information about processes running on your machine? 3 | Which command terminates a process? 4 | Which command can help you find the difference between two files? 5 | -------------------------------------------------------------------------------- /lab01/.gitignore: -------------------------------------------------------------------------------- 1 | eccentric 2 | hello 3 | int_hello 4 | segfault_ex 5 | no_segfault_ex 6 | test_ll_cycle -------------------------------------------------------------------------------- /lab01/eccentric.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* Only change any of these 4 values */ 4 | #define V0 0 5 | #define V1 -1 6 | #define V2 0 7 | #define V3 0 8 | 9 | int main(void) { 10 | int a; 11 | char *s; 12 | 13 | /* This is a print statement. Notice the little 'f' at the end! 14 | * It might be worthwhile to look up how printf works for your future 15 | * debugging needs... */ 16 | printf("Berkeley eccentrics:\n====================\n"); 17 | 18 | /* for loop */ 19 | for (a = 0; a < V0; a++) 20 | { 21 | printf("Happy "); 22 | } 23 | printf("\n"); 24 | 25 | /* switch statement */ 26 | switch (V1) 27 | { 28 | case 0: 29 | printf("Yoshua\n"); 30 | case 1: 31 | printf("Triangle Man\n"); 32 | break; 33 | case 2: 34 | printf("Chinese Erhu Guy\n"); 35 | case 3: 36 | printf("Yoshua\n"); 37 | break; 38 | case 4: 39 | printf("Dr. Jokemon\n"); 40 | break; 41 | case 5: 42 | printf("Hat Lady\n"); 43 | default: 44 | printf("I don't know these people!\n"); 45 | } 46 | 47 | /* ternary operator */ 48 | s = (V3 == 3) ? "Go" : "Boo"; 49 | 50 | /* if statement */ 51 | if (V2) { 52 | printf("%s BEARS!\n", s); 53 | } else { 54 | printf("%s CARDINAL!\n", s); 55 | } 56 | 57 | return 0; 58 | } -------------------------------------------------------------------------------- /lab01/gdb.txt: -------------------------------------------------------------------------------- 1 | 1. 2 | 2. 3 | 3. 4 | 4. 5 | 5. 6 | 6. 7 | 7. 8 | 8. 9 | 9. -------------------------------------------------------------------------------- /lab01/hello.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char *argv[]) { 4 | int i; 5 | int count = 0; 6 | int *p = &count; 7 | 8 | for (i = 0; i < 10; i++) { 9 | (*p)++; // Do you understand this line of code and all the other permutations of the operators? ;) 10 | } 11 | 12 | printf("Thanks for waddling through this program. Have a nice day."); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /lab01/interactive_hello.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define MAX_LEN 80 4 | 5 | int main(int argc, char *argv[]) { 6 | char a_word[MAX_LEN]; 7 | 8 | printf("What's your name?\n"); 9 | fgets(a_word, MAX_LEN, stdin); 10 | printf("Hey, %sI just really wanted to say hello to you.\nI hope you have a wonderful day.", a_word); 11 | 12 | return 0; 13 | } -------------------------------------------------------------------------------- /lab01/ll_cycle.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ll_cycle.h" 3 | 4 | int ll_has_cycle(node *head) { 5 | /* your code here */ 6 | return 0; 7 | } -------------------------------------------------------------------------------- /lab01/ll_cycle.h: -------------------------------------------------------------------------------- 1 | #ifndef LL_CYCLE_H 2 | #define LL_CYCLE_H 3 | typedef struct node { 4 | int value; 5 | struct node *next; 6 | } node; 7 | 8 | int ll_has_cycle(node *); 9 | #endif -------------------------------------------------------------------------------- /lab01/no_segfault_ex.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() { 3 | int a[5] = {1, 2, 3, 4, 5}; 4 | unsigned total = 0; 5 | for (int j = 0; j < sizeof(a); j++) { 6 | total += a[j]; 7 | } 8 | printf("sum of array is %d\n", total); 9 | } -------------------------------------------------------------------------------- /lab01/segfault_ex.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a[20]; 3 | for (int i = 0; ; i++) { 4 | a[i] = i; 5 | } 6 | } -------------------------------------------------------------------------------- /lab01/test_ll_cycle.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ll_cycle.h" 3 | 4 | int main(void) { 5 | // DO NOT EDIT ANY OF THE FOLLOWING CODE 6 | 7 | int i; 8 | node nodes[25]; //enough to run our tests 9 | for(i=0; i < sizeof(nodes)/sizeof(node); i++) { 10 | nodes[i].next = 0; 11 | nodes[i].value = 0; 12 | } 13 | int is_correct; 14 | 15 | nodes[0].next = &nodes[1]; 16 | nodes[1].next = &nodes[2]; 17 | nodes[2].next = &nodes[3]; 18 | is_correct = !ll_has_cycle(&nodes[0]); 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 | 21 | nodes[4].next = &nodes[5]; 22 | nodes[5].next = &nodes[6]; 23 | nodes[6].next = &nodes[7]; 24 | nodes[7].next = &nodes[8]; 25 | nodes[8].next = &nodes[9]; 26 | nodes[9].next = &nodes[10]; 27 | nodes[10].next = &nodes[4]; 28 | is_correct = is_correct && ll_has_cycle(&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 | 31 | nodes[11].next = &nodes[12]; 32 | nodes[12].next = &nodes[13]; 33 | nodes[13].next = &nodes[14]; 34 | nodes[14].next = &nodes[15]; 35 | nodes[15].next = &nodes[16]; 36 | nodes[16].next = &nodes[17]; 37 | nodes[17].next = &nodes[14]; 38 | is_correct = is_correct && ll_has_cycle(&nodes[11]); 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 | 41 | nodes[18].next = &nodes[18]; 42 | is_correct = is_correct && ll_has_cycle(&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 | 45 | nodes[19].next = &nodes[20]; 46 | nodes[20].next = &nodes[21]; 47 | nodes[21].next = &nodes[22]; 48 | nodes[22].next = &nodes[23]; 49 | is_correct = is_correct && !ll_has_cycle(&nodes[19]); 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 | 52 | is_correct = is_correct && !ll_has_cycle(NULL); 53 | printf("Checking length-zero list for cycles. There should be none, ll_has_cycle says it has %s cycle\n", ll_has_cycle(NULL)?"a":"no"); 54 | 55 | return is_correct ? 0 : 1; 56 | } -------------------------------------------------------------------------------- /lab02/Makefile: -------------------------------------------------------------------------------- 1 | UNAME_S := $(shell uname -s) 2 | CC=gcc 3 | LD=gcc 4 | CFLAGS=-ggdb -Wall -std=c99 5 | LDFLAGS= 6 | 7 | ifeq ($(UNAME_S), Darwin) 8 | MEMCHECK=valgrind --tool=memcheck --leak-check=full --track-origins=yes --dsymutil=yes 9 | endif 10 | 11 | ifeq ($(UNAME_S), Linux) 12 | MEMCHECK=valgrind --tool=memcheck --leak-check=full --track-origins=yes 13 | endif 14 | 15 | BIT_OPS_OBJS = bit_ops.o test_bit_ops.o 16 | BIT_OPS_PROG = bit_ops 17 | 18 | LFSR_OBJS = lfsr.o test_lfsr.o 19 | LFSR_PROG = lfsr 20 | 21 | VECTOR_OBJS=vector.o vector-test.o 22 | VECTOR_PROG=vector-test 23 | 24 | BINARIES=$(VECTOR_PROG) $(BIT_OPS_PROG) $(LFSR_PROG) 25 | 26 | all: $(BINARIES) 27 | 28 | $(BIT_OPS_PROG): $(BIT_OPS_OBJS) 29 | $(CC) $(CFLAGS) -g -o $(BIT_OPS_PROG) $(BIT_OPS_OBJS) $(LDFLAGS) 30 | 31 | $(LFSR_PROG): $(LFSR_OBJS) 32 | $(CC) $(CFLAGS) -g -o $(LFSR_PROG) $(LFSR_OBJS) $(LDFLAGS) 33 | 34 | lfsr.c: lfsr.h 35 | test_lfsr.c: lfsr.h 36 | 37 | bit_ops.c: bit_ops.h 38 | test_bit_ops.c: bit_ops.h 39 | 40 | .c.o: 41 | $(CC) -c $(CFLAGS) $< 42 | 43 | vector-memcheck: $(VECTOR_PROG) 44 | $(MEMCHECK) ./$(VECTOR_PROG) 45 | 46 | clean: 47 | -rm -rf core *.o *~ "#"*"#" Makefile.bak $(BINARIES) *.dSYM 48 | 49 | vector.c: vector.h 50 | vector-test.c: vector.h 51 | -------------------------------------------------------------------------------- /lab02/bit_ops.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "bit_ops.h" 3 | 4 | // Return the nth bit of x. 5 | // Assume 0 <= n <= 31 6 | unsigned get_bit(unsigned x, 7 | unsigned n) { 8 | // YOUR CODE HERE 9 | // Returning -1 is a placeholder (it makes 10 | // no sense, because get_bit only returns 11 | // 0 or 1) 12 | return -1; 13 | } 14 | // Set the nth bit of the value of x to v. 15 | // Assume 0 <= n <= 31, and v is 0 or 1 16 | void set_bit(unsigned * x, 17 | unsigned n, 18 | unsigned v) { 19 | // YOUR CODE HERE 20 | } 21 | // Flip the nth bit of the value of x. 22 | // Assume 0 <= n <= 31 23 | void flip_bit(unsigned * x, 24 | unsigned n) { 25 | // YOUR CODE HERE 26 | } 27 | 28 | -------------------------------------------------------------------------------- /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/lfsr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "lfsr.h" 6 | 7 | void lfsr_calculate(uint16_t *reg) { 8 | /* YOUR CODE HERE */ 9 | } 10 | 11 | -------------------------------------------------------------------------------- /lab02/lfsr.h: -------------------------------------------------------------------------------- 1 | void lfsr_calculate(uint16_t *reg); -------------------------------------------------------------------------------- /lab02/make.txt: -------------------------------------------------------------------------------- 1 | 1. 2 | 2. 3 | 3. 4 | 4. 5 | 5. 6 | 6. 7 | 7. -------------------------------------------------------------------------------- /lab02/test_bit_ops.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "bit_ops.h" 3 | 4 | void test_get_bit(unsigned x, 5 | unsigned n, 6 | unsigned expected) { 7 | unsigned a = get_bit(x, n); 8 | if(a!=expected) { 9 | printf("get_bit(0x%08x,%u): 0x%08x, expected 0x%08x\n",x,n,a,expected); 10 | } else { 11 | printf("get_bit(0x%08x,%u): 0x%08x, correct\n",x,n,a); 12 | } 13 | } 14 | void test_set_bit(unsigned x, 15 | unsigned n, 16 | unsigned v, 17 | unsigned expected) { 18 | unsigned o = x; 19 | set_bit(&x, n, v); 20 | if(x!=expected) { 21 | printf("set_bit(0x%08x,%u,%u): 0x%08x, expected 0x%08x\n",o,n,v,x,expected); 22 | } else { 23 | printf("set_bit(0x%08x,%u,%u): 0x%08x, correct\n",o,n,v,x); 24 | } 25 | } 26 | void test_flip_bit(unsigned x, 27 | unsigned n, 28 | unsigned expected) { 29 | unsigned o = x; 30 | flip_bit(&x, n); 31 | if(x!=expected) { 32 | printf("flip_bit(0x%08x,%u): 0x%08x, expected 0x%08x\n",o,n,x,expected); 33 | } else { 34 | printf("flip_bit(0x%08x,%u): 0x%08x, correct\n",o,n,x); 35 | } 36 | } 37 | int main(int argc, 38 | const char * argv[]) { 39 | printf("\nTesting get_bit()\n\n"); 40 | test_get_bit(0b1001110,0,0); 41 | test_get_bit(0b1001110,1,1); 42 | test_get_bit(0b1001110,5,0); 43 | test_get_bit(0b11011,3,1); 44 | test_get_bit(0b11011,2,0); 45 | test_get_bit(0b11011,9,0); 46 | printf("\nTesting set_bit()\n\n"); 47 | test_set_bit(0b1001110,2,0,0b1001010); 48 | test_set_bit(0b1101101,0,0,0b1101100); 49 | test_set_bit(0b1001110,2,1,0b1001110); 50 | test_set_bit(0b1101101,0,1,0b1101101); 51 | test_set_bit(0b1001110,9,0,0b1001110); 52 | test_set_bit(0b1101101,4,0,0b1101101); 53 | test_set_bit(0b1001110,9,1,0b1001001110); 54 | test_set_bit(0b1101101,7,1,0b11101101); 55 | printf("\nTesting flip_bit()\n\n"); 56 | test_flip_bit(0b1001110,0,0b1001111); 57 | test_flip_bit(0b1001110,1,0b1001100); 58 | test_flip_bit(0b1001110,2,0b1001010); 59 | test_flip_bit(0b1001110,5,0b1101110); 60 | test_flip_bit(0b1001110,9,0b1001001110); 61 | printf("\n"); 62 | return 0; 63 | } -------------------------------------------------------------------------------- /lab02/test_lfsr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "lfsr.h" 6 | 7 | int main() { 8 | int8_t *numbers = (int8_t*) malloc(sizeof(int8_t) * 65535); 9 | if (numbers == NULL) { 10 | printf("Memory allocation failed!"); 11 | exit(1); 12 | } 13 | 14 | memset(numbers, 0, sizeof(int8_t) * 65535); 15 | uint16_t reg = 0x1; 16 | uint32_t count = 0; 17 | int i; 18 | 19 | do { 20 | count++; 21 | numbers[reg] = 1; 22 | if (count < 24) { 23 | printf("My number is: %u\n", reg); 24 | } else if (count == 24) { 25 | printf(" ... etc etc ... \n"); 26 | } 27 | for (i = 0; i < 32; i++) 28 | lfsr_calculate(®); 29 | } while (numbers[reg] != 1); 30 | 31 | printf("Got %u numbers before cycling!\n", count); 32 | 33 | if (count == 65535) { 34 | printf("Congratulations! It works!\n"); 35 | } else { 36 | printf("Did I miss something?\n"); 37 | } 38 | 39 | free(numbers); 40 | 41 | return 0; 42 | } -------------------------------------------------------------------------------- /lab02/vector-test.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 54 | and set its single component to zero... the 55 | RIGHT WAY */ 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 retval; 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 | if (loc < /* YOUR CODE HERE */) { 100 | return /* YOUR CODE HERE */; 101 | } else { 102 | return 0; 103 | } 104 | } 105 | 106 | /* Free up the memory allocated for the passed vector. 107 | Remember, you need to free up ALL the memory that was allocated. */ 108 | void vector_delete(vector_t *v) { 109 | /* YOUR SOLUTION HERE */ 110 | } 111 | 112 | /* Set a value in the vector. If the extra memory allocation fails, call 113 | allocation_failed(). */ 114 | void vector_set(vector_t *v, size_t loc, int value) { 115 | /* What do you need to do if the location is greater than the size we have 116 | * allocated? Remember that unset locations should contain a value of 0. 117 | */ 118 | 119 | /* YOUR SOLUTION HERE */ 120 | } -------------------------------------------------------------------------------- /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 | /* YOUR CODE HERE */ 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 | /* YOUR CODE HERE */ 54 | 55 | #endif -------------------------------------------------------------------------------- /lab03/cc_test.s: -------------------------------------------------------------------------------- 1 | .globl simple_fn naive_pow inc_arr 2 | 3 | .data 4 | failure_message: .asciiz "Test failed for some reason.\n" 5 | success_message: .asciiz "Sanity checks passed! Make sure there are no CC violations.\n" 6 | array: 7 | .word 1 2 3 4 5 8 | exp_inc_array_result: 9 | .word 2 3 4 5 6 10 | 11 | .text 12 | main: 13 | # We test our program by loading a bunch of random values 14 | # into a few saved registers - if any of these are modified 15 | # after these functions return, then we know calling 16 | # convention was broken by one of these functions 17 | li s0, 2623 18 | li s1, 2910 19 | # ... skipping middle registers so the file isn't too long 20 | # If we wanted to be rigorous, we would add checks for 21 | # s2-s20 as well 22 | li s11, 134 23 | # Now, we call some functions 24 | # simple_fn: should return 1 25 | jal simple_fn # Shorthand for "jal ra, simple_fn" 26 | li t0, 1 27 | bne a0, t0, failure 28 | # naive_pow: should return 2 ** 7 = 128 29 | li a0, 2 30 | li a1, 7 31 | jal naive_pow 32 | li t0, 128 33 | bne a0, t0, failure 34 | # inc_arr: increments "array" in place 35 | la a0, array 36 | li a1, 5 37 | jal inc_arr 38 | jal check_arr # Verifies inc_arr and jumps to "failure" on failure 39 | # Check the values in the saved registers for sanity 40 | li t0, 2623 41 | li t1, 2910 42 | li t2, 134 43 | bne s0, t0, failure 44 | bne s1, t1, failure 45 | bne s11, t2, failure 46 | # If none of those branches were hit, print a message and exit normally 47 | li a0, 4 48 | la a1, success_message 49 | ecall 50 | li a0, 10 51 | ecall 52 | 53 | # Just a simple function. Returns 1. 54 | # 55 | # FIXME Fix the reported error in this function (you can delete lines 56 | # if necessary, as long as the function still returns 1 in a0). 57 | simple_fn: 58 | mv a0, t0 59 | li a0, 1 60 | ret 61 | 62 | # Computes a0 to the power of a1. 63 | # This is analogous to the following C pseudocode: 64 | # 65 | # uint32_t naive_pow(uint32_t a0, uint32_t a1) { 66 | # uint32_t s0 = 1; 67 | # while (a1 != 0) { 68 | # s0 *= a0; 69 | # a1 -= 1; 70 | # } 71 | # return s0; 72 | # } 73 | # 74 | # FIXME There's a CC error with this function! 75 | # The big all-caps comments should give you a hint about what's 76 | # missing. Another hint: what does the "s" in "s0" stand for? 77 | naive_pow: 78 | # BEGIN PROLOGUE 79 | # END PROLOGUE 80 | li s0, 1 81 | naive_pow_loop: 82 | beq a1, zero, naive_pow_end 83 | mul s0, s0, a0 84 | addi a1, a1, -1 85 | j naive_pow_loop 86 | naive_pow_end: 87 | mv a0, s0 88 | # BEGIN EPILOGUE 89 | # END EPILOGUE 90 | ret 91 | 92 | # Increments the elements of an array in-place. 93 | # a0 holds the address of the start of the array, and a1 holds 94 | # the number of elements it contains. 95 | # 96 | # This function calls the "helper_fn" function, which takes in an 97 | # address as argument and increments the 32-bit value stored there. 98 | inc_arr: 99 | # BEGIN PROLOGUE 100 | # 101 | # FIXME What other registers need to be saved? 102 | # 103 | addi sp, sp, -4 104 | sw ra, 0(sp) 105 | # END PROLOGUE 106 | mv s0, a0 # Copy start of array to saved register 107 | mv s1, a1 # Copy length of array to saved register 108 | li t0, 0 # Initialize counter to 0 109 | inc_arr_loop: 110 | beq t0, s1, inc_arr_end 111 | slli t1, t0, 2 # Convert array index to byte offset 112 | add a0, s0, t1 # Add offset to start of array 113 | # Prepare to call helper_fn 114 | # 115 | # FIXME Add code to preserve the value in t0 before we call helper_fn 116 | # Hint: What does the "t" in "t0" stand for? 117 | # Also ask yourself this: why don't we need to preserve t1? 118 | # 119 | jal helper_fn 120 | # Finished call for helper_fn 121 | addi t0, t0, 1 # Increment counter 122 | j inc_arr_loop 123 | inc_arr_end: 124 | # BEGIN EPILOGUE 125 | lw ra, 0(sp) 126 | addi sp, sp, 4 127 | # END EPILOGUE 128 | ret 129 | 130 | # This helper function adds 1 to the value at the memory address in a0. 131 | # It doesn't return anything. 132 | # C pseudocode for what it does: "*a0 = *a0 + 1" 133 | # 134 | # FIXME This function also violates calling convention, but it might not 135 | # be reported by the Venus CC checker (try and figure out why). 136 | # You should fix the bug anyway by filling in the prologue and epilogue 137 | # as appropriate. 138 | helper_fn: 139 | # BEGIN PROLOGUE 140 | # END PROLOGUE 141 | lw t1, 0(a0) 142 | addi s0, t1, 1 143 | sw s0, 0(a0) 144 | # BEGIN EPILOGUE 145 | # END EPILOGUE 146 | ret 147 | 148 | # YOU CAN IGNORE EVERYTHING BELOW THIS COMMENT 149 | 150 | # Checks the result of inc_arr, which should contain 2 3 4 5 6 after 151 | # one call. 152 | # You can safely ignore this function; it has no errors. 153 | check_arr: 154 | la t0, exp_inc_array_result 155 | la t1, array 156 | addi t2, t1, 20 # Last element is 5*4 bytes off 157 | check_arr_loop: 158 | beq t1, t2, check_arr_end 159 | lw t3, 0(t0) 160 | lw t4, 0(t1) 161 | bne t3, t4, failure 162 | addi t0, t0, 4 163 | addi t1, t1, 4 164 | j check_arr_loop 165 | check_arr_end: 166 | ret 167 | 168 | 169 | # This isn't really a function - it just prints a message, then 170 | # terminates the program on failure. Think of it like an exception. 171 | failure: 172 | li a0, 4 # String print ecall 173 | la a1, failure_message 174 | ecall 175 | li a0, 10 # Exit ecall 176 | ecall 177 | 178 | -------------------------------------------------------------------------------- /lab03/ex1.s: -------------------------------------------------------------------------------- 1 | .data 2 | .word 2, 4, 6, 8 3 | n: .word 9 4 | 5 | .text 6 | main: 7 | add t0, x0, x0 8 | addi t1, x0, 1 9 | la t3, n 10 | lw t3, 0(t3) 11 | fib: 12 | beq t3, x0, finish 13 | add t2, t1, t0 14 | mv t0, t1 15 | mv t1, t2 16 | addi t3, t3, -1 17 | j fib 18 | finish: 19 | addi a0, x0, 1 20 | addi a1, t0, 0 21 | ecall # print integer ecall 22 | addi a0, x0, 10 23 | ecall # terminate ecall 24 | -------------------------------------------------------------------------------- /lab03/ex2.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 | } -------------------------------------------------------------------------------- /lab03/ex2.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 -------------------------------------------------------------------------------- /lab03/list_map.s: -------------------------------------------------------------------------------- 1 | .globl map 2 | 3 | .text 4 | main: 5 | jal ra, create_default_list 6 | add s0, a0, x0 # a0 = s0 is head of node list 7 | 8 | #print the list 9 | add a0, s0, x0 10 | jal ra, print_list 11 | 12 | # print a newline 13 | jal ra, print_newline 14 | 15 | # load your args 16 | add a0, s0, x0 # load the address of the first node into a0 17 | 18 | # load the address of the function in question into a1 (check out la on the green sheet) 19 | ### YOUR CODE HERE ### 20 | 21 | # issue the call to map 22 | jal ra, map 23 | 24 | # print the list 25 | add a0, s0, x0 26 | jal ra, print_list 27 | 28 | # print another newline 29 | jal ra, print_newline 30 | 31 | addi a0, x0, 10 32 | ecall #Terminate the program 33 | 34 | map: 35 | # Prologue: Make space on the stack and back-up registers 36 | ### YOUR CODE HERE ### 37 | 38 | beq a0, x0, done # If we were given a null pointer (address 0), we're done. 39 | 40 | add s0, a0, x0 # Save address of this node in s0 41 | add s1, a1, x0 # Save address of function in s1 42 | 43 | # Remember that each node is 8 bytes long: 4 for the value followed by 4 for the pointer to next. 44 | # What does this tell you about how you access the value and how you access the pointer to next? 45 | 46 | # load the value of the current node into a0 47 | # THINK: why a0? 48 | ### YOUR CODE HERE ### 49 | 50 | # Call the function in question on that value. DO NOT use a label (be prepared to answer why). 51 | # What function? Recall the parameters of "map" 52 | ### YOUR CODE HERE ### 53 | 54 | # store the returned value back into the node 55 | # Where can you assume the returned value is? 56 | ### YOUR CODE HERE ### 57 | 58 | # Load the address of the next node into a0 59 | # The Address of the next node is an attribute of the current node. 60 | # Think about how structs are organized in memory. 61 | ### YOUR CODE HERE ### 62 | 63 | # Put the address of the function back into a1 to prepare for the recursion 64 | # THINK: why a1? What about a0? 65 | ### YOUR CODE HERE ### 66 | 67 | # recurse 68 | ### YOUR CODE HERE ### 69 | 70 | done: 71 | # Epilogue: Restore register values and free space from the stack 72 | ### YOUR CODE HERE ### 73 | 74 | jr ra # Return to caller 75 | 76 | square: 77 | mul a0 ,a0, a0 78 | jr ra 79 | 80 | create_default_list: 81 | addi sp, sp, -12 82 | sw ra, 0(sp) 83 | sw s0, 4(sp) 84 | sw s1, 8(sp) 85 | li s0, 0 # pointer to the last node we handled 86 | li s1, 0 # number of nodes handled 87 | loop: #do... 88 | li a0, 8 89 | jal ra, malloc # get memory for the next node 90 | sw s1, 0(a0) # node->value = i 91 | sw s0, 4(a0) # node->next = last 92 | add s0, a0, x0 # last = node 93 | addi s1, s1, 1 # i++ 94 | addi t0, x0, 10 95 | bne s1, t0, loop # ... while i!= 10 96 | lw ra, 0(sp) 97 | lw s0, 4(sp) 98 | lw s1, 8(sp) 99 | addi sp, sp, 12 100 | jr ra 101 | 102 | print_list: 103 | bne a0, x0, printMeAndRecurse 104 | jr ra # nothing to print 105 | printMeAndRecurse: 106 | add t0, a0, x0 # t0 gets current node address 107 | lw a1, 0(t0) # a1 gets value in current node 108 | addi a0, x0, 1 # prepare for print integer ecall 109 | ecall 110 | addi a1, x0, ' ' # a0 gets address of string containing space 111 | addi a0, x0, 11 # prepare for print string syscall 112 | ecall 113 | lw a0, 4(t0) # a0 gets address of next node 114 | jal x0, print_list # recurse. We don't have to use jal because we already have where we want to return to in ra 115 | 116 | print_newline: 117 | addi a1, x0, '\n' # Load in ascii code for newline 118 | addi a0, x0, 11 119 | ecall 120 | jr ra 121 | 122 | malloc: 123 | addi a1, a0, 0 124 | addi a0, x0 9 125 | ecall 126 | jr ra -------------------------------------------------------------------------------- /lab04/discrete_fn.s: -------------------------------------------------------------------------------- 1 | .globl f 2 | 3 | .data 4 | neg3: .asciiz "f(-3) should be 6, and it is: " 5 | neg2: .asciiz "f(-2) should be 61, and it is: " 6 | neg1: .asciiz "f(-1) should be 17, and it is: " 7 | zero: .asciiz "f(0) should be -38, and it is: " 8 | pos1: .asciiz "f(1) should be 19, and it is: " 9 | pos2: .asciiz "f(2) should be 42, and it is: " 10 | pos3: .asciiz "f(3) should be 5, and it is: " 11 | 12 | output: .word 6, 61, 17, -38, 19, 42, 5 13 | .text 14 | main: 15 | la a0, neg3 16 | jal print_str 17 | li a0, -3 18 | la a1, output 19 | jal f # evaluate f(-3); should be 6 20 | jal print_int 21 | jal print_newline 22 | 23 | la a0, neg2 24 | jal print_str 25 | li a0, -2 26 | la a1, output 27 | jal f # evaluate f(-2); should be 61 28 | jal print_int 29 | jal print_newline 30 | 31 | la a0, neg1 32 | jal print_str 33 | li a0, -1 34 | la a1, output 35 | jal f # evaluate f(-1); should be 17 36 | jal print_int 37 | jal print_newline 38 | 39 | la a0, zero 40 | jal print_str 41 | li a0, 0 42 | la a1, output 43 | jal f # evaluate f(0); should be -38 44 | jal print_int 45 | jal print_newline 46 | 47 | la a0, pos1 48 | jal print_str 49 | li a0, 1 50 | la a1, output 51 | jal f # evaluate f(1); should be 19 52 | jal print_int 53 | jal print_newline 54 | 55 | la a0, pos2 56 | jal print_str 57 | li a0, 2 58 | la a1, output 59 | jal f # evaluate f(2); should be 42 60 | jal print_int 61 | jal print_newline 62 | 63 | la a0, pos3 64 | jal print_str 65 | li a0, 3 66 | la a1, output 67 | jal f # evaluate f(3); should be 5 68 | jal print_int 69 | jal print_newline 70 | 71 | li a0, 10 72 | ecall 73 | 74 | # f takes in two arguments: 75 | # a0 is the value we want to evaluate f at 76 | # a1 is the address of the "output" array (defined above). 77 | # Think: why might having a1 be useful? 78 | f: 79 | # YOUR CODE GOES HERE! 80 | 81 | jr ra # Always remember to jr ra after your function! 82 | 83 | print_int: 84 | mv a1, a0 85 | li a0, 1 86 | ecall 87 | jr ra 88 | 89 | print_str: 90 | mv a1, a0 91 | li a0, 4 92 | ecall 93 | jr ra 94 | 95 | print_newline: 96 | li a1, '\n' 97 | li a0, 11 98 | ecall 99 | jr ra 100 | -------------------------------------------------------------------------------- /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 | jr ra 91 | 92 | mystery: 93 | mul t1, a0, a0 94 | add a0, t1, a0 95 | jr ra 96 | 97 | create_default_list: 98 | addi sp, sp, -4 99 | sw ra, 0(sp) 100 | li s0, 0 # pointer to the last node we handled 101 | li s1, 0 # number of nodes handled 102 | li s2, 5 # size 103 | la s3, arrays 104 | loop: #do... 105 | li a0, 12 106 | jal malloc # get memory for the next node 107 | mv s4, a0 108 | li a0, 20 109 | jal malloc # get memory for this array 110 | 111 | sw a0, 0(s4) # node->arr = malloc 112 | lw a0, 0(s4) 113 | mv a1, s3 114 | jal fillArray # copy ints over to node->arr 115 | 116 | sw s2, 4(s4) # node->size = size (4) 117 | sw s0, 8(s4) # node-> next = previously created node 118 | 119 | add s0, x0, s4 # last = node 120 | addi s1, s1, 1 # i++ 121 | addi s3, s3, 20 # s3 points at next set of ints 122 | li t6 5 123 | bne s1, t6, loop # ... while i!= 5 124 | mv a0, s4 125 | lw ra, 0(sp) 126 | addi sp, sp, 4 127 | jr ra 128 | 129 | fillArray: lw t0, 0(a1) #t0 gets array element 130 | sw t0, 0(a0) #node->arr gets array element 131 | lw t0, 4(a1) 132 | sw t0, 4(a0) 133 | lw t0, 8(a1) 134 | sw t0, 8(a0) 135 | lw t0, 12(a1) 136 | sw t0, 12(a0) 137 | lw t0, 16(a1) 138 | sw t0, 16(a0) 139 | jr ra 140 | 141 | print_list: 142 | bne a0, x0, printMeAndRecurse 143 | jr ra # nothing to print 144 | printMeAndRecurse: 145 | mv t0, a0 # t0 gets address of current node 146 | lw t3, 0(a0) # t3 gets array of current node 147 | li t1, 0 # t1 is index into array 148 | printLoop: 149 | slli t2, t1, 2 150 | add t4, t3, t2 151 | lw a1, 0(t4) # a0 gets value in current node's array at index t1 152 | li a0, 1 # preparte for print integer ecall 153 | ecall 154 | li a1, ' ' # a0 gets address of string containing space 155 | li a0, 11 # prepare for print string ecall 156 | ecall 157 | addi t1, t1, 1 158 | li t6 5 159 | bne t1, t6, printLoop # ... while i!= 5 160 | li a1, '\n' 161 | li a0, 11 162 | ecall 163 | lw a0, 8(t0) # a0 gets address of next node 164 | j print_list # recurse. We don't have to use jal because we already have where we want to return to in ra 165 | 166 | print_newline: 167 | li a1, '\n' 168 | li a0, 11 169 | ecall 170 | jr ra 171 | 172 | malloc: 173 | mv a1, a0 # Move a0 into a1 so that we can do the syscall correctly 174 | li a0, 9 175 | ecall 176 | jr ra 177 | -------------------------------------------------------------------------------- /lab05/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 | addr/data: 8 8 42 | 0 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- 50 | -- HEIG-VD, institute REDS, 1400 Yverdon-les-Bains 51 | -- Project : 52 | -- File : 53 | -- Autor : 54 | -- Date : 55 | -- 56 | -------------------------------------------------------------------------------- 57 | -- Description : 58 | -- 59 | -------------------------------------------------------------------------------- 60 | 61 | library ieee; 62 | use ieee.std_logic_1164.all; 63 | --use ieee.numeric_std.all; 64 | 65 | entity VHDL_Component is 66 | port( 67 | ------------------------------------------------------------------------------ 68 | --Insert input ports below 69 | horloge_i : in std_logic; -- input bit example 70 | val_i : in std_logic_vector(3 downto 0); -- input vector example 71 | ------------------------------------------------------------------------------ 72 | --Insert output ports below 73 | max_o : out std_logic; -- output bit example 74 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 75 | ); 76 | end VHDL_Component; 77 | 78 | -------------------------------------------------------------------------------- 79 | --Complete your VHDL description below 80 | architecture type_architecture of VHDL_Component is 81 | 82 | 83 | begin 84 | 85 | 86 | end type_architecture; 87 | 88 | 89 | 90 | 91 | 92 | library ieee; 93 | use ieee.std_logic_1164.all; 94 | 95 | entity TCL_Generic is 96 | port( 97 | --Insert input ports below 98 | horloge_i : in std_logic; -- input bit example 99 | val_i : in std_logic_vector(3 downto 0); -- input vector example 100 | 101 | --Insert output ports below 102 | max_o : out std_logic; -- output bit example 103 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 104 | ); 105 | end TCL_Generic; 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 | 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 | -------------------------------------------------------------------------------- /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 | addr/data: 8 8 43 | 0 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- 51 | -- HEIG-VD, institute REDS, 1400 Yverdon-les-Bains 52 | -- Project : 53 | -- File : 54 | -- Autor : 55 | -- Date : 56 | -- 57 | -------------------------------------------------------------------------------- 58 | -- Description : 59 | -- 60 | -------------------------------------------------------------------------------- 61 | 62 | library ieee; 63 | use ieee.std_logic_1164.all; 64 | --use ieee.numeric_std.all; 65 | 66 | entity VHDL_Component is 67 | port( 68 | ------------------------------------------------------------------------------ 69 | --Insert input ports below 70 | horloge_i : in std_logic; -- input bit example 71 | val_i : in std_logic_vector(3 downto 0); -- input vector example 72 | ------------------------------------------------------------------------------ 73 | --Insert output ports below 74 | max_o : out std_logic; -- output bit example 75 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 76 | ); 77 | end VHDL_Component; 78 | 79 | -------------------------------------------------------------------------------- 80 | --Complete your VHDL description below 81 | architecture type_architecture of VHDL_Component is 82 | 83 | 84 | begin 85 | 86 | 87 | end type_architecture; 88 | 89 | 90 | 91 | 92 | 93 | library ieee; 94 | use ieee.std_logic_1164.all; 95 | 96 | entity TCL_Generic is 97 | port( 98 | --Insert input ports below 99 | horloge_i : in std_logic; -- input bit example 100 | val_i : in std_logic_vector(3 downto 0); -- input vector example 101 | 102 | --Insert output ports below 103 | max_o : out std_logic; -- output bit example 104 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 105 | ); 106 | end TCL_Generic; 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 | -------------------------------------------------------------------------------- /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 | addr/data: 8 8 43 | 0 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- 51 | -- HEIG-VD, institute REDS, 1400 Yverdon-les-Bains 52 | -- Project : 53 | -- File : 54 | -- Autor : 55 | -- Date : 56 | -- 57 | -------------------------------------------------------------------------------- 58 | -- Description : 59 | -- 60 | -------------------------------------------------------------------------------- 61 | 62 | library ieee; 63 | use ieee.std_logic_1164.all; 64 | --use ieee.numeric_std.all; 65 | 66 | entity VHDL_Component is 67 | port( 68 | ------------------------------------------------------------------------------ 69 | --Insert input ports below 70 | horloge_i : in std_logic; -- input bit example 71 | val_i : in std_logic_vector(3 downto 0); -- input vector example 72 | ------------------------------------------------------------------------------ 73 | --Insert output ports below 74 | max_o : out std_logic; -- output bit example 75 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 76 | ); 77 | end VHDL_Component; 78 | 79 | -------------------------------------------------------------------------------- 80 | --Complete your VHDL description below 81 | architecture type_architecture of VHDL_Component is 82 | 83 | 84 | begin 85 | 86 | 87 | end type_architecture; 88 | 89 | 90 | 91 | 92 | 93 | library ieee; 94 | use ieee.std_logic_1164.all; 95 | 96 | entity TCL_Generic is 97 | port( 98 | --Insert input ports below 99 | horloge_i : in std_logic; -- input bit example 100 | val_i : in std_logic_vector(3 downto 0); -- input vector example 101 | 102 | --Insert output ports below 103 | max_o : out std_logic; -- output bit example 104 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 105 | ); 106 | end TCL_Generic; 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 | -------------------------------------------------------------------------------- /lab05/ex5.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 | addr/data: 8 8 43 | 0 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- 51 | -- HEIG-VD, institute REDS, 1400 Yverdon-les-Bains 52 | -- Project : 53 | -- File : 54 | -- Autor : 55 | -- Date : 56 | -- 57 | -------------------------------------------------------------------------------- 58 | -- Description : 59 | -- 60 | -------------------------------------------------------------------------------- 61 | 62 | library ieee; 63 | use ieee.std_logic_1164.all; 64 | --use ieee.numeric_std.all; 65 | 66 | entity VHDL_Component is 67 | port( 68 | ------------------------------------------------------------------------------ 69 | --Insert input ports below 70 | horloge_i : in std_logic; -- input bit example 71 | val_i : in std_logic_vector(3 downto 0); -- input vector example 72 | ------------------------------------------------------------------------------ 73 | --Insert output ports below 74 | max_o : out std_logic; -- output bit example 75 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 76 | ); 77 | end VHDL_Component; 78 | 79 | -------------------------------------------------------------------------------- 80 | --Complete your VHDL description below 81 | architecture type_architecture of VHDL_Component is 82 | 83 | 84 | begin 85 | 86 | 87 | end type_architecture; 88 | 89 | 90 | 91 | 92 | 93 | library ieee; 94 | use ieee.std_logic_1164.all; 95 | 96 | entity TCL_Generic is 97 | port( 98 | --Insert input ports below 99 | horloge_i : in std_logic; -- input bit example 100 | val_i : in std_logic_vector(3 downto 0); -- input vector example 101 | 102 | --Insert output ports below 103 | max_o : out std_logic; -- output bit example 104 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 105 | ); 106 | end TCL_Generic; 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 | -------------------------------------------------------------------------------- /lab05/logisim-evolution.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/61c-teach/fa20-lab-starter/e4545d88812dcc2c618f0b194f5acc2b6681b9e2/lab05/logisim-evolution.jar -------------------------------------------------------------------------------- /lab05/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Just run this file and you can test your circ files! 4 | # Make sure your files are in the directory above this one though! 5 | 6 | cp ex1.circ ex2.circ ex3.circ ex4.circ ex5.circ testing/circ_files 7 | 8 | cd testing 9 | rm -rf student_output 10 | mkdir student_output 11 | ./test.py 12 | cd .. 13 | -------------------------------------------------------------------------------- /lab05/testing/circ_files/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 | 75 | addr/data: 8 8 76 | 0 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- 84 | -- HEIG-VD, institute REDS, 1400 Yverdon-les-Bains 85 | -- Project : 86 | -- File : 87 | -- Autor : 88 | -- Date : 89 | -- 90 | -------------------------------------------------------------------------------- 91 | -- Description : 92 | -- 93 | -------------------------------------------------------------------------------- 94 | 95 | library ieee; 96 | use ieee.std_logic_1164.all; 97 | --use ieee.numeric_std.all; 98 | 99 | entity VHDL_Component is 100 | port( 101 | ------------------------------------------------------------------------------ 102 | --Insert input ports below 103 | horloge_i : in std_logic; -- input bit example 104 | val_i : in std_logic_vector(3 downto 0); -- input vector example 105 | ------------------------------------------------------------------------------ 106 | --Insert output ports below 107 | max_o : out std_logic; -- output bit example 108 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 109 | ); 110 | end VHDL_Component; 111 | 112 | -------------------------------------------------------------------------------- 113 | --Complete your VHDL description below 114 | architecture type_architecture of VHDL_Component is 115 | 116 | 117 | begin 118 | 119 | 120 | end type_architecture; 121 | 122 | 123 | 124 | 125 | 126 | library ieee; 127 | use ieee.std_logic_1164.all; 128 | 129 | entity TCL_Generic is 130 | port( 131 | --Insert input ports below 132 | horloge_i : in std_logic; -- input bit example 133 | val_i : in std_logic_vector(3 downto 0); -- input vector example 134 | 135 | --Insert output ports below 136 | max_o : out std_logic; -- output bit example 137 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 138 | ); 139 | end TCL_Generic; 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 | -------------------------------------------------------------------------------- /lab05/testing/circ_files/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 | 75 | addr/data: 8 8 76 | 0 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- 84 | -- HEIG-VD, institute REDS, 1400 Yverdon-les-Bains 85 | -- Project : 86 | -- File : 87 | -- Autor : 88 | -- Date : 89 | -- 90 | -------------------------------------------------------------------------------- 91 | -- Description : 92 | -- 93 | -------------------------------------------------------------------------------- 94 | 95 | library ieee; 96 | use ieee.std_logic_1164.all; 97 | --use ieee.numeric_std.all; 98 | 99 | entity VHDL_Component is 100 | port( 101 | ------------------------------------------------------------------------------ 102 | --Insert input ports below 103 | horloge_i : in std_logic; -- input bit example 104 | val_i : in std_logic_vector(3 downto 0); -- input vector example 105 | ------------------------------------------------------------------------------ 106 | --Insert output ports below 107 | max_o : out std_logic; -- output bit example 108 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 109 | ); 110 | end VHDL_Component; 111 | 112 | -------------------------------------------------------------------------------- 113 | --Complete your VHDL description below 114 | architecture type_architecture of VHDL_Component is 115 | 116 | 117 | begin 118 | 119 | 120 | end type_architecture; 121 | 122 | 123 | 124 | 125 | 126 | library ieee; 127 | use ieee.std_logic_1164.all; 128 | 129 | entity TCL_Generic is 130 | port( 131 | --Insert input ports below 132 | horloge_i : in std_logic; -- input bit example 133 | val_i : in std_logic_vector(3 downto 0); -- input vector example 134 | 135 | --Insert output ports below 136 | max_o : out std_logic; -- output bit example 137 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 138 | ); 139 | end TCL_Generic; 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 | addr/data: 8 1 243 | 0 1 0 1 1 0 1 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 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | -------------------------------------------------------------------------------- /lab05/testing/circ_files/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 | -- HEIG-VD, institute REDS, 1400 Yverdon-les-Bains 85 | -- Project : 86 | -- File : 87 | -- Autor : 88 | -- Date : 89 | -- 90 | -------------------------------------------------------------------------------- 91 | -- Description : 92 | -- 93 | -------------------------------------------------------------------------------- 94 | 95 | library ieee; 96 | use ieee.std_logic_1164.all; 97 | --use ieee.numeric_std.all; 98 | 99 | entity VHDL_Component is 100 | port( 101 | ------------------------------------------------------------------------------ 102 | --Insert input ports below 103 | horloge_i : in std_logic; -- input bit example 104 | val_i : in std_logic_vector(3 downto 0); -- input vector example 105 | ------------------------------------------------------------------------------ 106 | --Insert output ports below 107 | max_o : out std_logic; -- output bit example 108 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 109 | ); 110 | end VHDL_Component; 111 | 112 | -------------------------------------------------------------------------------- 113 | --Complete your VHDL description below 114 | architecture type_architecture of VHDL_Component is 115 | 116 | 117 | begin 118 | 119 | 120 | end type_architecture; 121 | 122 | 123 | 124 | 125 | 126 | library ieee; 127 | use ieee.std_logic_1164.all; 128 | 129 | entity TCL_Generic is 130 | port( 131 | --Insert input ports below 132 | horloge_i : in std_logic; -- input bit example 133 | val_i : in std_logic_vector(3 downto 0); -- input vector example 134 | 135 | --Insert output ports below 136 | max_o : out std_logic; -- output bit example 137 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 138 | ); 139 | end TCL_Generic; 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: 8 8 253 | 1 80 81 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 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | -------------------------------------------------------------------------------- /lab05/testing/logisim-evolution.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/61c-teach/fa20-lab-starter/e4545d88812dcc2c618f0b194f5acc2b6681b9e2/lab05/testing/logisim-evolution.jar -------------------------------------------------------------------------------- /lab05/testing/reference_output/ex1_test.out: -------------------------------------------------------------------------------- 1 | 0000 0000 1 1 0 0 0 0 0 1 0 0 0 2 | 0000 0001 1 0 1 0 0 0 1 0 1 0 1 3 | 0000 0010 1 0 1 0 0 1 0 1 1 1 0 4 | 0000 0011 0 0 0 1 0 1 1 1 0 1 1 5 | 0000 0100 1 1 0 0 0 0 0 0 0 0 0 6 | 0000 0101 1 1 0 0 0 0 0 0 0 0 0 7 | 0000 0110 1 1 0 0 0 0 0 0 0 0 0 8 | 0000 0111 1 1 0 0 0 0 0 0 0 0 0 9 | -------------------------------------------------------------------------------- /lab05/testing/reference_output/ex2_test.out: -------------------------------------------------------------------------------- 1 | 0000 0001 0000 0000 2 | 0000 0010 0000 0001 3 | 0000 0011 0000 0010 4 | 0000 0100 0000 0011 5 | 0000 0101 0000 0100 6 | 0000 0110 0000 0101 7 | 0000 0111 0000 0110 8 | 0000 1000 0000 0111 9 | 0000 1001 0000 1000 10 | 0000 1010 0000 1001 11 | 0000 1011 0000 1010 12 | 0000 1100 0000 1011 13 | 0000 1101 0000 1100 14 | 0000 1110 0000 1101 15 | 0000 1111 0000 1110 16 | 0001 0000 0000 1111 17 | 0001 0001 0001 0000 18 | 0001 0010 0001 0001 19 | 0001 0011 0001 0010 20 | 0001 0100 0001 0011 21 | 0001 0101 0001 0100 22 | 0001 0110 0001 0101 23 | 0001 0111 0001 0110 24 | 0001 1000 0001 0111 25 | 0001 1001 0001 1000 26 | 0001 1010 0001 1001 27 | 0001 1011 0001 1010 28 | 0001 1100 0001 1011 29 | 0001 1101 0001 1100 30 | 0001 1110 0001 1101 31 | 0001 1111 0001 1110 32 | 0010 0000 0001 1111 33 | 0010 0001 0010 0000 34 | 0010 0010 0010 0001 35 | 0010 0011 0010 0010 36 | 0010 0100 0010 0011 37 | 0010 0101 0010 0100 38 | 0010 0110 0010 0101 39 | 0010 0111 0010 0110 40 | 0010 1000 0010 0111 41 | 0010 1001 0010 1000 42 | 0010 1010 0010 1001 43 | 0010 1011 0010 1010 44 | 0010 1100 0010 1011 45 | 0010 1101 0010 1100 46 | 0010 1110 0010 1101 47 | 0010 1111 0010 1110 48 | 0011 0000 0010 1111 49 | 0011 0001 0011 0000 50 | 0011 0010 0011 0001 51 | 0011 0011 0011 0010 52 | 0011 0100 0011 0011 53 | 0011 0101 0011 0100 54 | 0011 0110 0011 0101 55 | 0011 0111 0011 0110 56 | 0011 1000 0011 0111 57 | 0011 1001 0011 1000 58 | 0011 1010 0011 1001 59 | 0011 1011 0011 1010 60 | 0011 1100 0011 1011 61 | 0011 1101 0011 1100 62 | 0011 1110 0011 1101 63 | 0011 1111 0011 1110 64 | 0100 0000 0011 1111 65 | 0100 0001 0100 0000 66 | 0100 0010 0100 0001 67 | 0100 0011 0100 0010 68 | 0100 0100 0100 0011 69 | 0100 0101 0100 0100 70 | 0100 0110 0100 0101 71 | 0100 0111 0100 0110 72 | 0100 1000 0100 0111 73 | 0100 1001 0100 1000 74 | 0100 1010 0100 1001 75 | 0100 1011 0100 1010 76 | 0100 1100 0100 1011 77 | 0100 1101 0100 1100 78 | 0100 1110 0100 1101 79 | 0100 1111 0100 1110 80 | 0101 0000 0100 1111 81 | 0101 0001 0101 0000 82 | 0101 0010 0101 0001 83 | 0101 0011 0101 0010 84 | 0101 0100 0101 0011 85 | 0101 0101 0101 0100 86 | 0101 0110 0101 0101 87 | 0101 0111 0101 0110 88 | 0101 1000 0101 0111 89 | 0101 1001 0101 1000 90 | 0101 1010 0101 1001 91 | 0101 1011 0101 1010 92 | 0101 1100 0101 1011 93 | 0101 1101 0101 1100 94 | 0101 1110 0101 1101 95 | 0101 1111 0101 1110 96 | 0110 0000 0101 1111 97 | 0110 0001 0110 0000 98 | 0110 0010 0110 0001 99 | 0110 0011 0110 0010 100 | 0110 0100 0110 0011 101 | 0110 0101 0110 0100 102 | 0110 0110 0110 0101 103 | 0110 0111 0110 0110 104 | 0110 1000 0110 0111 105 | 0110 1001 0110 1000 106 | 0110 1010 0110 1001 107 | 0110 1011 0110 1010 108 | 0110 1100 0110 1011 109 | 0110 1101 0110 1100 110 | 0110 1110 0110 1101 111 | 0110 1111 0110 1110 112 | 0111 0000 0110 1111 113 | 0111 0001 0111 0000 114 | 0111 0010 0111 0001 115 | 0111 0011 0111 0010 116 | 0111 0100 0111 0011 117 | 0111 0101 0111 0100 118 | 0111 0110 0111 0101 119 | 0111 0111 0111 0110 120 | 0111 1000 0111 0111 121 | 0111 1001 0111 1000 122 | 0111 1010 0111 1001 123 | 0111 1011 0111 1010 124 | 0111 1100 0111 1011 125 | 0111 1101 0111 1100 126 | 0111 1110 0111 1101 127 | 0111 1111 0111 1110 128 | 1000 0000 0111 1111 129 | 1000 0001 1000 0000 130 | 1000 0010 1000 0001 131 | 1000 0011 1000 0010 132 | 1000 0100 1000 0011 133 | 1000 0101 1000 0100 134 | 1000 0110 1000 0101 135 | 1000 0111 1000 0110 136 | 1000 1000 1000 0111 137 | 1000 1001 1000 1000 138 | 1000 1010 1000 1001 139 | 1000 1011 1000 1010 140 | 1000 1100 1000 1011 141 | 1000 1101 1000 1100 142 | 1000 1110 1000 1101 143 | 1000 1111 1000 1110 144 | 1001 0000 1000 1111 145 | 1001 0001 1001 0000 146 | 1001 0010 1001 0001 147 | 1001 0011 1001 0010 148 | 1001 0100 1001 0011 149 | 1001 0101 1001 0100 150 | 1001 0110 1001 0101 151 | 1001 0111 1001 0110 152 | 1001 1000 1001 0111 153 | 1001 1001 1001 1000 154 | 1001 1010 1001 1001 155 | 1001 1011 1001 1010 156 | 1001 1100 1001 1011 157 | 1001 1101 1001 1100 158 | 1001 1110 1001 1101 159 | 1001 1111 1001 1110 160 | 1010 0000 1001 1111 161 | 1010 0001 1010 0000 162 | 1010 0010 1010 0001 163 | 1010 0011 1010 0010 164 | 1010 0100 1010 0011 165 | 1010 0101 1010 0100 166 | 1010 0110 1010 0101 167 | 1010 0111 1010 0110 168 | 1010 1000 1010 0111 169 | 1010 1001 1010 1000 170 | 1010 1010 1010 1001 171 | 1010 1011 1010 1010 172 | 1010 1100 1010 1011 173 | 1010 1101 1010 1100 174 | 1010 1110 1010 1101 175 | 1010 1111 1010 1110 176 | 1011 0000 1010 1111 177 | 1011 0001 1011 0000 178 | 1011 0010 1011 0001 179 | 1011 0011 1011 0010 180 | 1011 0100 1011 0011 181 | 1011 0101 1011 0100 182 | 1011 0110 1011 0101 183 | 1011 0111 1011 0110 184 | 1011 1000 1011 0111 185 | 1011 1001 1011 1000 186 | 1011 1010 1011 1001 187 | 1011 1011 1011 1010 188 | 1011 1100 1011 1011 189 | 1011 1101 1011 1100 190 | 1011 1110 1011 1101 191 | 1011 1111 1011 1110 192 | 1100 0000 1011 1111 193 | 1100 0001 1100 0000 194 | 1100 0010 1100 0001 195 | 1100 0011 1100 0010 196 | 1100 0100 1100 0011 197 | 1100 0101 1100 0100 198 | 1100 0110 1100 0101 199 | 1100 0111 1100 0110 200 | 1100 1000 1100 0111 201 | 1100 1001 1100 1000 202 | 1100 1010 1100 1001 203 | 1100 1011 1100 1010 204 | 1100 1100 1100 1011 205 | 1100 1101 1100 1100 206 | 1100 1110 1100 1101 207 | 1100 1111 1100 1110 208 | 1101 0000 1100 1111 209 | 1101 0001 1101 0000 210 | 1101 0010 1101 0001 211 | 1101 0011 1101 0010 212 | 1101 0100 1101 0011 213 | 1101 0101 1101 0100 214 | 1101 0110 1101 0101 215 | 1101 0111 1101 0110 216 | 1101 1000 1101 0111 217 | 1101 1001 1101 1000 218 | 1101 1010 1101 1001 219 | 1101 1011 1101 1010 220 | 1101 1100 1101 1011 221 | 1101 1101 1101 1100 222 | 1101 1110 1101 1101 223 | 1101 1111 1101 1110 224 | 1110 0000 1101 1111 225 | 1110 0001 1110 0000 226 | 1110 0010 1110 0001 227 | 1110 0011 1110 0010 228 | 1110 0100 1110 0011 229 | 1110 0101 1110 0100 230 | 1110 0110 1110 0101 231 | 1110 0111 1110 0110 232 | 1110 1000 1110 0111 233 | 1110 1001 1110 1000 234 | 1110 1010 1110 1001 235 | 1110 1011 1110 1010 236 | 1110 1100 1110 1011 237 | 1110 1101 1110 1100 238 | 1110 1110 1110 1101 239 | 1110 1111 1110 1110 240 | 1111 0000 1110 1111 241 | 1111 0001 1111 0000 242 | 1111 0010 1111 0001 243 | 1111 0011 1111 0010 244 | 1111 0100 1111 0011 245 | 1111 0101 1111 0100 246 | 1111 0110 1111 0101 247 | 1111 0111 1111 0110 248 | 1111 1000 1111 0111 249 | 1111 1001 1111 1000 250 | 1111 1010 1111 1001 251 | 1111 1011 1111 1010 252 | 1111 1100 1111 1011 253 | 1111 1101 1111 1100 254 | 1111 1110 1111 1101 255 | 1111 1111 1111 1110 256 | 0000 0000 1111 1111 257 | -------------------------------------------------------------------------------- /lab05/testing/reference_output/ex3_test.out: -------------------------------------------------------------------------------- 1 | 0000 0000 1 0 2 | 0000 0001 1 1 3 | 0000 0010 1 0 4 | 0000 0011 1 1 5 | 0000 0100 0 1 6 | 0000 0101 0 0 7 | 0000 0110 0 1 8 | 0000 0111 0 0 9 | -------------------------------------------------------------------------------- /lab05/testing/reference_output/ex4_test.out: -------------------------------------------------------------------------------- 1 | 0000 0000 0 1000 0001 0000 0001 2 | 0000 0001 0 0000 0000 1000 0000 3 | 0000 0010 1 0000 0001 1000 0001 4 | -------------------------------------------------------------------------------- /lab05/testing/reference_output/ex5_test.out: -------------------------------------------------------------------------------- 1 | 0000 0000 1000 0000 0000 0000 0000 0000 0000 0001 0001 2 | 0000 0001 0100 0000 0000 0000 0000 0000 0000 0001 0010 3 | 0000 0010 0001 0000 0000 0000 0000 0000 0000 0001 0100 4 | 0000 0011 0000 0001 0000 0000 0000 0000 0000 0001 1000 5 | 0000 0100 0010 0000 0000 0000 0000 0000 0000 0001 0011 6 | 0000 0101 0000 1000 0000 0000 0000 0000 0000 0001 0101 7 | 0000 0110 0000 0000 1000 0000 0000 0000 0000 0001 1001 8 | 0000 0111 0000 0000 0000 0010 0000 0000 0000 0001 1111 9 | -------------------------------------------------------------------------------- /lab05/testing/test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import os.path 5 | import tempfile 6 | import subprocess 7 | import time 8 | import signal 9 | import re 10 | import sys 11 | import shutil 12 | 13 | file_locations = os.getcwd() 14 | logisim_location = os.path.join(os.getcwd(),"logisim-evolution.jar") 15 | 16 | class TestCase(): 17 | """ 18 | Runs specified circuit file and compares output against the provided reference trace file. 19 | """ 20 | 21 | def __init__(self, circfile, tracefile, register_doc): 22 | self.circfile = circfile 23 | self.tracefile = tracefile 24 | self.register_doc = register_doc 25 | 26 | def __call__(self, filename): 27 | output = tempfile.TemporaryFile(mode='r+') 28 | try: 29 | stdinf = open('/dev/null') 30 | except Exception as e: 31 | try: 32 | stdinf = open('nul') 33 | except Exception as e: 34 | print("Could not open nul or /dev/null. Program will most likely error now.") 35 | proc = subprocess.Popen(["java","-jar",logisim_location,"-tty","table",self.circfile], stdin=stdinf, stdout=subprocess.PIPE) 36 | try: 37 | reference = open(self.tracefile) 38 | passed = compare_unbounded(proc.stdout,reference, filename) 39 | finally: 40 | try: 41 | os.kill(proc.pid,signal.SIGTERM) 42 | except Exception as e: 43 | pass 44 | if passed: 45 | return (True, "Matched expected output") 46 | else: 47 | return (False, "Did not match expected output") 48 | 49 | def compare_unbounded(student_out, reference_out, filename): 50 | passed = True 51 | student_output_array = [] 52 | while True: 53 | line1 = student_out.readline().rstrip().decode("utf-8", "namereplace") 54 | line2 = reference_out.readline().rstrip() 55 | if line2 == '': 56 | break 57 | student_output_array.append(line1) 58 | m = re.match(line2, line1) 59 | if m == None or m.start() != 0 or m.end() != len(line2): 60 | passed = False 61 | with open(filename, "w") as student_output: 62 | for line in student_output_array: 63 | student_output.write(line + '\n') 64 | return passed 65 | 66 | 67 | def run_tests(tests): 68 | print("Testing files...") 69 | tests_passed = 0 70 | tests_failed = 0 71 | 72 | for description,filename,test in tests: 73 | test_passed, reason = test(filename) 74 | if test_passed: 75 | print("\tPASSED test: %s" % description) 76 | tests_passed += 1 77 | else: 78 | print("\tFAILED test: %s (%s)" % (description, reason)) 79 | tests_failed += 1 80 | 81 | print("Passed %d/%d tests" % (tests_passed, (tests_passed + tests_failed))) 82 | 83 | tests = [ 84 | ("Exercise 1 (Sub-Circuits) test", "student_output/ex1_test.out",TestCase(os.path.join(file_locations,'circ_files/ex1_test.circ'), os.path.join 85 | (file_locations,'reference_output/ex1_test.out'), "")), 86 | ("Exercise 2 (Add Machine) test", "student_output/ex2_test.out",TestCase(os.path.join(file_locations,'circ_files/ex2_test.circ'), os.path.join 87 | (file_locations,'reference_output/ex2_test.out'), "")), 88 | ("Exercise 3 (FSM) test", "student_output/ex3_test.out",TestCase(os.path.join(file_locations,'circ_files/ex3_test.circ'), os.path.join 89 | (file_locations,'reference_output/ex3_test.out'), "")), 90 | ("Exercise 4 (Split) test", "student_output/ex4_test.out",TestCase(os.path.join(file_locations,'circ_files/ex4_test.circ'), os.path.join 91 | (file_locations,'reference_output/ex4_test.out'), "")), 92 | ("Exercise 5 (Rotate Right) test", "student_output/ex5_test.out",TestCase(os.path.join(file_locations,'circ_files/ex5_test.circ'), os.path.join 93 | (file_locations,'reference_output/ex5_test.out'), "")), 94 | ] 95 | 96 | if __name__ == '__main__': 97 | run_tests(tests) 98 | -------------------------------------------------------------------------------- /lab06/ROMdata: -------------------------------------------------------------------------------- 1 | v2.0 raw 2 | 3 2 fc 1 2 fb 1 3 | -------------------------------------------------------------------------------- /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 | addr/data: 8 8 44 | 0 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- 52 | -- HEIG-VD, institute REDS, 1400 Yverdon-les-Bains 53 | -- Project : 54 | -- File : 55 | -- Autor : 56 | -- Date : 57 | -- 58 | -------------------------------------------------------------------------------- 59 | -- Description : 60 | -- 61 | -------------------------------------------------------------------------------- 62 | 63 | library ieee; 64 | use ieee.std_logic_1164.all; 65 | --use ieee.numeric_std.all; 66 | 67 | entity VHDL_Component is 68 | port( 69 | ------------------------------------------------------------------------------ 70 | --Insert input ports below 71 | horloge_i : in std_logic; -- input bit example 72 | val_i : in std_logic_vector(3 downto 0); -- input vector example 73 | ------------------------------------------------------------------------------ 74 | --Insert output ports below 75 | max_o : out std_logic; -- output bit example 76 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 77 | ); 78 | end VHDL_Component; 79 | 80 | -------------------------------------------------------------------------------- 81 | --Complete your VHDL description below 82 | architecture type_architecture of VHDL_Component is 83 | 84 | 85 | begin 86 | 87 | 88 | end type_architecture; 89 | 90 | 91 | 92 | 93 | 94 | library ieee; 95 | use ieee.std_logic_1164.all; 96 | 97 | entity TCL_Generic is 98 | port( 99 | --Insert input ports below 100 | horloge_i : in std_logic; -- input bit example 101 | val_i : in std_logic_vector(3 downto 0); -- input vector example 102 | 103 | --Insert output ports below 104 | max_o : out std_logic; -- output bit example 105 | cpt_o : out std_logic_Vector(3 downto 0) -- output vector example 106 | ); 107 | end TCL_Generic; 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 | addr/data: 8 8 191 | 3 2 fc 1 2 fb 1 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 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | -------------------------------------------------------------------------------- /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 | # Rewriten by Stephan Kaminsky in RISC-V on 7/30/2018 2 | # This program accesses an array in ways that provide data about the cache parameters. 3 | # Coupled with the Data Cache Simulator and Memory Reference Visualization to help students 4 | # understand how the cache parameters affect cache performance. 5 | # 6 | # PSEUDOCODE: 7 | # int array[]; //Assume sizeof(int) == 4 8 | # for (k = 0; k < repcount; k++) { // repeat repcount times 9 | # /* Step through the selected array segment with the given step size. */ 10 | # for (index = 0; index < arraysize; index += stepsize) { 11 | # if(option==0) 12 | # array[index] = 0; // Option 0: One cache access - write 13 | # else 14 | # array[index] = array[index] + 1; // Option 1: Two cache accesses - read AND write 15 | # } 16 | # } 17 | 18 | .data 19 | array: .word 2048 # max array size specified in BYTES (DO NOT CHANGE) 20 | 21 | .text 22 | ################################################################################################## 23 | # You MAY change the code below this section 24 | main: li a0, 256 # array size in BYTES (power of 2 < array size) 25 | li a1, 2 # step size (power of 2 > 0) 26 | li a2, 1 # rep count (int > 0) 27 | li a3, 1 # 0 - option 0, 1 - option 1 28 | # You MAY change the code above this section 29 | ################################################################################################## 30 | 31 | jal accessWords # lw/sw 32 | #jal accessBytes # lb/sb 33 | 34 | li a0,10 # exit 35 | ecall 36 | 37 | # SUMMARY OF REGISTER USE: 38 | # a0 = array size in bytes 39 | # a1 = step size 40 | # a2 = number of times to repeat 41 | # a3 = 0 (W) / 1 (RW) 42 | # s0 = moving array ptr 43 | # s1 = array limit (ptr) 44 | 45 | accessWords: 46 | la s0, array # ptr to array 47 | add s1, s0, a0 # hardcode array limit (ptr) 48 | slli t1, a1, 2 # multiply stepsize by 4 because WORDS 49 | wordLoop: 50 | beq a3, zero, wordZero 51 | 52 | lw t0, 0(s0) # array[index/4]++ 53 | addi t0, t0, 1 54 | sw t0, 0(s0) 55 | j wordCheck 56 | 57 | wordZero: 58 | sw zero, 0(s0) # array[index/4] = 0 59 | 60 | wordCheck: 61 | add s0, s0, t1 # increment ptr 62 | blt s0, s1, wordLoop # inner loop done? 63 | 64 | addi a2, a2, -1 65 | bgtz a2, accessWords # outer loop done? 66 | jr ra 67 | 68 | 69 | accessBytes: 70 | la s0, array # ptr to array 71 | add s1, s0, a0 # hardcode array limit (ptr) 72 | byteLoop: 73 | beq a3, zero, byteZero 74 | 75 | lbu t0, 0(s0) # array[index]++ 76 | addi t0, t0, 1 77 | sb t0, 0(s0) 78 | j byteCheck 79 | 80 | byteZero: 81 | sb zero, 0(s0) # array[index] = 0 82 | 83 | byteCheck: 84 | add s0, s0, a1 # increment ptr 85 | blt s0, s1, byteLoop # inner loop done? 86 | 87 | addi a2, a2, -1 88 | bgtz a2, accessBytes # outer loop done? 89 | jr ra 90 | -------------------------------------------------------------------------------- /lab07/exercise1.txt: -------------------------------------------------------------------------------- 1 | Scenario 1 2 | 1. 3 | 2. 4 | 3. 5 | 6 | Scenario 2 7 | 1. 8 | 2. 9 | 3. 10 | 11 | Scenario 3 12 | 1. 13 | 2. 14 | 3. 15 | 4. 16 | 5. 17 | 18 | --- lines below are ignored by the AG --- 19 | 20 | Checkoff Question 1: 21 | Checkoff Question 2: 22 | Checkoff Question 3: 23 | Checkoff Question 4: 24 | Checkoff Question 5: 25 | -------------------------------------------------------------------------------- /lab07/exercise2.txt: -------------------------------------------------------------------------------- 1 | 1. 2 | 2. 3 | 4 | --- lines below are ignored by the AG --- 5 | 6 | Checkoff Question 1: 7 | Checkoff Question 2: 8 | Checkoff Question 3: 9 | -------------------------------------------------------------------------------- /lab07/exercise3.txt: -------------------------------------------------------------------------------- 1 | --- not autograded --- 2 | 3 | Part 1 4 | blocksize = 20, n = 100: 5 | blocksize = 20, n = 1000: 6 | blocksize = 20, n = 2000: 7 | blocksize = 20, n = 5000: 8 | blocksize = 20, n = 10000: 9 | 10 | Checkoff Question 1: 11 | Checkoff Question 2: 12 | 13 | Part 2 14 | blocksize = 50, n = 10000: 15 | blocksize = 100, n = 10000: 16 | blocksize = 500, n = 10000: 17 | blocksize = 1000, n = 10000: 18 | blocksize = 5000, n = 10000: 19 | 20 | Checkoff Question 3: 21 | -------------------------------------------------------------------------------- /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 | void benchmark(int *A, int *B, int n, int blocksize, 8 | void (*transpose)(int, int, int*, int*), char *description) { 9 | 10 | int i, j; 11 | printf("Testing %s: ", description); 12 | 13 | /* initialize A,B to random integers */ 14 | srand48( time( NULL ) ); 15 | for( i = 0; i < n*n; i++ ) A[i] = lrand48( ); 16 | for( i = 0; i < n*n; i++ ) B[i] = lrand48( ); 17 | 18 | /* measure performance */ 19 | struct timeval start, end; 20 | 21 | gettimeofday( &start, NULL ); 22 | transpose( n, blocksize, B, A ); 23 | gettimeofday( &end, NULL ); 24 | 25 | double seconds = (end.tv_sec - start.tv_sec) + 26 | 1.0e-6 * (end.tv_usec - start.tv_usec); 27 | printf( "%g milliseconds\n", seconds*1e3 ); 28 | 29 | /* check correctness */ 30 | for( i = 0; i < n; i++ ) { 31 | for( j = 0; j < n; j++ ) { 32 | if( B[j+i*n] != A[i+j*n] ) { 33 | printf("Error!!!! Transpose does not result in correct answer!!\n"); 34 | exit( -1 ); 35 | } 36 | } 37 | } 38 | } 39 | 40 | int main( int argc, char **argv ) { 41 | if (argc != 3) { 42 | printf("Usage: transpose \nExiting.\n"); 43 | exit(1); 44 | } 45 | 46 | int n = atoi(argv[1]); 47 | int blocksize = atoi(argv[2]); 48 | 49 | /* allocate an n*n block of integers for the matrices */ 50 | int *A = (int*)malloc( n*n*sizeof(int) ); 51 | int *B = (int*)malloc( n*n*sizeof(int) ); 52 | 53 | /* run tests */ 54 | benchmark(A, B, n, blocksize, transpose_naive, "naive transpose"); 55 | benchmark(A, B, n, blocksize, transpose_blocking, "transpose with blocking"); 56 | 57 | /* release resources */ 58 | free( A ); 59 | free( B ); 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /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/answers.txt: -------------------------------------------------------------------------------- 1 | Exercise 1: 2 | 1. 3 | 2. 4 | 3. 5 | 6 | Exercise 2: 7 | 1. 8 | 9 | Exercise 3: 10 | 1. 11 | 12 | --- lines below are ignored by the AG --- 13 | 14 | Exercise 1 Checkoff Questions: 15 | 1. 16 | 2. 17 | 18 | Exercise 4 Checkoff Question: 19 | 1. 20 | -------------------------------------------------------------------------------- /lab09/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=--std=c99 -Wall 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 | -------------------------------------------------------------------------------- /lab09/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 | //This is what we call the TAIL CASE 35 | //For when NUM_ELEMS isn't a multiple of 4 36 | //NONTRIVIAL FACT: NUM_ELEMS / 4 * 4 is the largest multiple of 4 less than NUM_ELEMS 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 DO NOT DO NOT DO NOT WRITE ANYTHING ABOVE THIS LINE. */ 53 | 54 | for(unsigned int w = 0; w < OUTER_ITERATIONS; w++) { 55 | /* YOUR CODE GOES HERE */ 56 | 57 | /* You'll need a tail case. */ 58 | 59 | } 60 | clock_t end = clock(); 61 | printf("Time taken: %Lf s\n", (long double)(end - start) / CLOCKS_PER_SEC); 62 | return result; 63 | } 64 | 65 | long long int sum_simd_unrolled(int vals[NUM_ELEMS]) { 66 | clock_t start = clock(); 67 | __m128i _127 = _mm_set1_epi32(127); 68 | long long int result = 0; 69 | for(unsigned int w = 0; w < OUTER_ITERATIONS; w++) { 70 | /* COPY AND PASTE YOUR sum_simd() HERE */ 71 | /* MODIFY IT BY UNROLLING IT */ 72 | 73 | /* You'll need 1 or maybe 2 tail cases here. */ 74 | 75 | } 76 | clock_t end = clock(); 77 | printf("Time taken: %Lf s\n", (long double)(end - start) / CLOCKS_PER_SEC); 78 | return result; 79 | } -------------------------------------------------------------------------------- /lab09/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 | -------------------------------------------------------------------------------- /lab09/test_simd.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "simd.h" 5 | 6 | /* ***DON'T MODIFY THIS FILE! ONLY 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", reference); 22 | clock_t reft = end - start; 23 | 24 | printf("Starting randomized unrolled sum.\n"); 25 | printf("Sum: %lld\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", 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", simd, reference); 36 | success = 1; 37 | } 38 | 39 | if (reft <= simdt * 2) { 40 | printf("Test Failed! SIMD sum provided less than 2X speedup.\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", 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", simdu, reference); 53 | success = 1; 54 | } 55 | 56 | if (simdt <= simdut) { 57 | printf("Test Failed! SIMD unrolled function provided no speedup.\n"); 58 | success = 1; 59 | } 60 | 61 | if (!success) { 62 | printf("All tests Passed! Correct values were produced, and speedups were achieved!\n"); 63 | return 0; 64 | } else { 65 | return 1; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /lab10/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/c 3 | 4 | # executables 5 | server_basic 6 | server_process 7 | v_add 8 | hello 9 | dotp 10 | **/report.txt 11 | **/*_sobel.bmp 12 | 13 | ### C ### 14 | # Prerequisites 15 | *.d 16 | 17 | # Object files 18 | *.o 19 | *.ko 20 | *.obj 21 | *.elf 22 | 23 | # Precompiled Headers 24 | *.gch 25 | *.pch 26 | 27 | # Libraries 28 | *.lib 29 | *.a 30 | *.la 31 | *.lo 32 | 33 | # Shared objects (inc. Windows DLLs) 34 | *.dll 35 | *.so 36 | *.so.* 37 | *.dylib 38 | 39 | # Executables 40 | *.exe 41 | *.out 42 | *.app 43 | *.i*86 44 | *.x86_64 45 | *.hex 46 | 47 | # Test images 48 | #*.jpeg 49 | #*.bmp 50 | 51 | 52 | # Debug files 53 | *.dSYM/ 54 | *.su 55 | 56 | **/.idea* 57 | -------------------------------------------------------------------------------- /lab10/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS= -std=gnu99 -c -fopenmp 3 | LDFLAGS=-fopenmp 4 | OBJECTS=$(SOURCES:.c=.o) 5 | EXECUTABLES=v_add dotp hello server_basic server_process 6 | 7 | .PHONY: all clean 8 | 9 | all: $(EXECUTABLES) 10 | 11 | v_add: v_add.o omp_app.o libbmp.o 12 | hello: hello.o 13 | dotp: dotp.o omp_app.o libbmp.o 14 | server_basic: server_basic.o libhttp.o omp_apps.o server_utils_serial.o libbmp.o 15 | server_process: server_process.o libhttp.o omp_apps.o server_utils_process.o libbmp.o 16 | 17 | $(EXECUTABLES): 18 | $(CC) $(LDFLAGS) $^ -o $@ 19 | 20 | server_basic.o: server.c libhttp/libhttp.c omp_apps.c server_utils.c libbmp/libbmp.c 21 | server_process.o: server.c libhttp/libhttp.c omp_apps.c server_utils.c libbmp/libbmp.c 22 | omp_app.o: omp_apps.c libbmp/libbmp.c 23 | 24 | server_utils_serial.o: server_utils.c 25 | $(CC) $(CFLAGS) $< -o $@ 26 | server_utils_process.o: server_utils.c 27 | $(CC) -DPROC $(CFLAGS) $< -o $@ 28 | server_process.o: 29 | $(CC) $(CFLAGS) $< -o $@ 30 | server_basic.o: 31 | $(CC) $(CFLAGS) $< -o $@ 32 | 33 | libbmp.o: 34 | $(CC) $(CFLAGS) libbmp/libbmp.c -o $@ 35 | libhttp.o: 36 | $(CC) $(CFLAGS) libhttp/libhttp.c -o $@ 37 | 38 | omp_app.o: omp_apps.c libbmp.o 39 | $(CC) $(CFLAGS) omp_apps.c -o $@ 40 | 41 | %.o: %.c 42 | $(CC) $(CFLAGS) $< -o $@ 43 | 44 | clean: 45 | rm -f $(EXECUTABLES) *.o 46 | rm -f ./files/*_sobel.bmp 47 | -------------------------------------------------------------------------------- /lab10/assets/process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/61c-teach/fa20-lab-starter/e4545d88812dcc2c618f0b194f5acc2b6681b9e2/lab10/assets/process.png -------------------------------------------------------------------------------- /lab10/assets/sample_output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/61c-teach/fa20-lab-starter/e4545d88812dcc2c618f0b194f5acc2b6681b9e2/lab10/assets/sample_output.jpg -------------------------------------------------------------------------------- /lab10/assets/threads.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/61c-teach/fa20-lab-starter/e4545d88812dcc2c618f0b194f5acc2b6681b9e2/lab10/assets/threads.png -------------------------------------------------------------------------------- /lab10/dotp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "omp_apps.h" 7 | 8 | int main() { 9 | double *x = gen_array(ARRAY_SIZE); 10 | double *y = gen_array(ARRAY_SIZE); 11 | double serial_result = 0.0; 12 | double result; 13 | 14 | double start_time, run_time; 15 | 16 | // calculate result serially 17 | for(int i=0; i 0.001) { 33 | printf("Manual optimized does not match reference.\n"); 34 | return -1; 35 | } 36 | 37 | printf("Manual Optimized: %d thread(s) took %f seconds\n",i,run_time); 38 | } 39 | 40 | for (int i=1; i<=num_threads; i++) { 41 | omp_set_num_threads(i); 42 | start_time = omp_get_wtime(); 43 | for(int j=0; j 0.001) { 50 | printf("Reduction optimized does not match reference.\n"); 51 | return -1; 52 | } 53 | 54 | printf("Reduction Optimized: %d thread(s) took %f seconds\n",i,run_time); 55 | } 56 | 57 | // Only run this once because it's too slow.. 58 | omp_set_num_threads(1); 59 | start_time = omp_get_wtime(); 60 | for(int j=0; j 2 | 3 | 4 | 5 | CS 61C is the best 6 | 104 | 105 | 106 | 107 | CS 61C IS THE BEST 108 | 109 |

WELCOME TO CS61C

110 |
114 |
115 |

CS61C

116 |
117 |
118 |

Created with WEB 4.0 HTML6 CLOUD.

119 |
120 | 121 | 122 | -------------------------------------------------------------------------------- /lab10/files/lena.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/61c-teach/fa20-lab-starter/e4545d88812dcc2c618f0b194f5acc2b6681b9e2/lab10/files/lena.bmp -------------------------------------------------------------------------------- /lab10/files/monarch.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/61c-teach/fa20-lab-starter/e4545d88812dcc2c618f0b194f5acc2b6681b9e2/lab10/files/monarch.bmp -------------------------------------------------------------------------------- /lab10/files/my_documents/click_here.txt: -------------------------------------------------------------------------------- 1 | Recommended materials to kill some quarantine time: 2 | 3 | https://missing.csail.mit.edu/ 4 | https://www.youtube.com/watch?v=c0bsKc4tiuY 5 | https://blog.nelhage.com/post/computers-can-be-understood/ 6 | https://github.com/olofk/servk 7 | https://www.thirtythreeforty.net/posts/2019/12/my-business-card-runs-linux/ 8 | 9 | 10 | -------------------------------------------------------------------------------- /lab10/files/my_documents/credit.txt: -------------------------------------------------------------------------------- 1 | Site designed by cs162 staff. 2 | http server modified from [cs162 hw4](https://cs162.eecs.berkeley.edu/static/hw/hw4.pdf) 3 | [libbmp](https://github.com/marc-q/libbmp) 4 | 5 | Content in this folder introduced by alice. 6 | -------------------------------------------------------------------------------- /lab10/files/my_documents/git-poem.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/61c-teach/fa20-lab-starter/e4545d88812dcc2c618f0b194f5acc2b6681b9e2/lab10/files/my_documents/git-poem.jpg -------------------------------------------------------------------------------- /lab10/files/my_documents/multi-processing.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/61c-teach/fa20-lab-starter/e4545d88812dcc2c618f0b194f5acc2b6681b9e2/lab10/files/my_documents/multi-processing.jpeg -------------------------------------------------------------------------------- /lab10/files/my_documents/multithread-everything.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/61c-teach/fa20-lab-starter/e4545d88812dcc2c618f0b194f5acc2b6681b9e2/lab10/files/my_documents/multithread-everything.jpeg -------------------------------------------------------------------------------- /lab10/files/my_documents/style.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Merriweather+Sans); 2 | 3 | ol { 4 | counter-reset: li; 5 | list-style: none; 6 | *list-style: decimal; /* Keep using default numbering for IE6/7 */ 7 | font: 15px 'Merriweather Sans', 'lucida sans', sans-serif; 8 | padding: 0; 9 | text-shadow: 0 1px 0 rgba(255,255,255,.5); 10 | width: 300px; 11 | margin: 0 auto; 12 | } 13 | ol ol { 14 | margin-left: 2em; 15 | } 16 | .rounded-list a { 17 | position: relative; 18 | display: block; 19 | padding: .4em .4em .4em 2em; 20 | *padding: .4em; 21 | margin: .5em 0; 22 | background: #ddd; 23 | color: #444; 24 | text-decoration: none; 25 | border-radius: .3em; 26 | transition: all .5s ease-out; 27 | } 28 | .rounded-list a:hover{ 29 | background: #eee; 30 | } 31 | .rounded-list a:before{ 32 | content: counter(li); 33 | counter-increment: li; 34 | position: absolute; 35 | left: -1.3em; 36 | top: 50%; 37 | margin-top: -1.3em; 38 | background: #87ceeb; 39 | height: 2em; 40 | width: 2em; 41 | line-height: 2em; 42 | border: .3em solid #fff; 43 | text-align: center; 44 | font-weight: bold; 45 | border-radius: 2em; 46 | transition: all .3s ease-out; 47 | } 48 | -------------------------------------------------------------------------------- /lab10/files/my_documents/theslowwinter.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/61c-teach/fa20-lab-starter/e4545d88812dcc2c618f0b194f5acc2b6681b9e2/lab10/files/my_documents/theslowwinter.pdf -------------------------------------------------------------------------------- /lab10/files/my_documents/wholesome_facts.txt: -------------------------------------------------------------------------------- 1 | Sunflowers face the sun. When they cannot find the sun, they face each other. 2 | An otter will find a rock as a juvenile and keep that rock for life. 3 | Sea otters hold hands when they sleep so they don't drift apart. 4 | Bees get sleepy after drinking nectar and occasionally take naps on flowers. 5 | Cows have best friends. 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lab10/files/template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Sobel Edge Detector Result 6 | 7 | 8 |

Image Filter

9 |

Original

10 | 11 |

Sobel-Edge-Detectored

12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /lab10/files/test.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/61c-teach/fa20-lab-starter/e4545d88812dcc2c618f0b194f5acc2b6681b9e2/lab10/files/test.bmp -------------------------------------------------------------------------------- /lab10/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 | -------------------------------------------------------------------------------- /lab10/libbmp/libbmp.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2016 - 2017 Marc Volker Dickmann 2 | * Project: LibBMP 3 | */ 4 | #include 5 | #include 6 | #include "libbmp.h" 7 | 8 | // BMP_HEADER 9 | 10 | void 11 | bmp_header_init_df (bmp_header *header, 12 | const int width, 13 | const int height) 14 | { 15 | header->bfSize = (sizeof (bmp_pixel) * width + BMP_GET_PADDING (width)) 16 | * abs (height); 17 | header->bfReserved = 0; 18 | header->bfOffBits = 54; 19 | header->biSize = 40; 20 | header->biWidth = width; 21 | header->biHeight = height; 22 | header->biPlanes = 1; 23 | header->biBitCount = 24; 24 | header->biCompression = 0; 25 | header->biSizeImage = 0; 26 | header->biXPelsPerMeter = 0; 27 | header->biYPelsPerMeter = 0; 28 | header->biClrUsed = 0; 29 | header->biClrImportant = 0; 30 | } 31 | 32 | enum bmp_error 33 | bmp_header_write (const bmp_header *header, 34 | FILE *img_file) 35 | { 36 | if (header == NULL) 37 | { 38 | return BMP_HEADER_NOT_INITIALIZED; 39 | } 40 | else if (img_file == NULL) 41 | { 42 | return BMP_FILE_NOT_OPENED; 43 | } 44 | 45 | // Since an adress must be passed to fwrite, create a variable! 46 | const unsigned short magic = BMP_MAGIC; 47 | fwrite (&magic, sizeof (magic), 1, img_file); 48 | 49 | // Use the type instead of the variable because its a pointer! 50 | fwrite (header, sizeof (bmp_header), 1, img_file); 51 | return BMP_OK; 52 | } 53 | 54 | enum bmp_error 55 | bmp_header_read (bmp_header *header, 56 | FILE *img_file) 57 | { 58 | if (img_file == NULL) 59 | { 60 | return BMP_FILE_NOT_OPENED; 61 | } 62 | 63 | // Since an adress must be passed to fread, create a variable! 64 | unsigned short magic; 65 | 66 | // Check if its an bmp file by comparing the magic nbr: 67 | if (fread (&magic, sizeof (magic), 1, img_file) != 1 || 68 | magic != BMP_MAGIC) 69 | { 70 | return BMP_INVALID_FILE; 71 | } 72 | 73 | if (fread (header, sizeof (bmp_header), 1, img_file) != 1) 74 | { 75 | return BMP_ERROR; 76 | } 77 | 78 | return BMP_OK; 79 | } 80 | 81 | // BMP_PIXEL 82 | 83 | void 84 | bmp_pixel_init (bmp_pixel *pxl, 85 | const unsigned char red, 86 | const unsigned char green, 87 | const unsigned char blue) 88 | { 89 | pxl->red = red; 90 | pxl->green = green; 91 | pxl->blue = blue; 92 | } 93 | 94 | // BMP_IMG 95 | 96 | void 97 | bmp_img_alloc (bmp_img *img) 98 | { 99 | const size_t h = abs (img->img_header.biHeight); 100 | 101 | // Allocate the required memory for the pixels: 102 | img->img_pixels = malloc (sizeof (bmp_pixel*) * h); 103 | 104 | for (size_t y = 0; y < h; y++) 105 | { 106 | img->img_pixels[y] = malloc (sizeof (bmp_pixel) * img->img_header.biWidth); 107 | } 108 | } 109 | 110 | void 111 | bmp_img_init_df (bmp_img *img, 112 | const int width, 113 | const int height) 114 | { 115 | // INIT the header with default values: 116 | bmp_header_init_df (&img->img_header, width, height); 117 | bmp_img_alloc (img); 118 | } 119 | 120 | void 121 | bmp_img_free (bmp_img *img) 122 | { 123 | const size_t h = abs (img->img_header.biHeight); 124 | 125 | for (size_t y = 0; y < h; y++) 126 | { 127 | free (img->img_pixels[y]); 128 | } 129 | free (img->img_pixels); 130 | } 131 | 132 | enum bmp_error 133 | bmp_img_write (const bmp_img *img, 134 | const char *filename) 135 | { 136 | FILE *img_file = fopen (filename, "wb"); 137 | 138 | if (img_file == NULL) 139 | { 140 | return BMP_FILE_NOT_OPENED; 141 | } 142 | 143 | // NOTE: This way the correct error code could be returned. 144 | const enum bmp_error err = bmp_header_write (&img->img_header, img_file); 145 | 146 | if (err != BMP_OK) 147 | { 148 | // ERROR: Could'nt write the header! 149 | fclose (img_file); 150 | return err; 151 | } 152 | 153 | // Select the mode (bottom-up or top-down): 154 | const size_t h = abs (img->img_header.biHeight); 155 | const size_t offset = (img->img_header.biHeight > 0 ? h - 1 : 0); 156 | 157 | // Create the padding: 158 | const unsigned char padding[3] = {'\0', '\0', '\0'}; 159 | 160 | // Write the content: 161 | for (size_t y = 0; y < h; y++) 162 | { 163 | // Write a whole row of pixels to the file: 164 | fwrite (img->img_pixels[abs (offset - y)], sizeof (bmp_pixel), img->img_header.biWidth, img_file); 165 | 166 | // Write the padding for the row! 167 | fwrite (padding, sizeof (unsigned char), BMP_GET_PADDING (img->img_header.biWidth), img_file); 168 | } 169 | 170 | // NOTE: All good! 171 | fclose (img_file); 172 | return BMP_OK; 173 | } 174 | 175 | enum bmp_error 176 | bmp_img_read (bmp_img *img, 177 | const char *filename) 178 | { 179 | FILE *img_file = fopen (filename, "rb"); 180 | 181 | if (img_file == NULL) 182 | { 183 | return BMP_FILE_NOT_OPENED; 184 | } 185 | 186 | // NOTE: This way the correct error code can be returned. 187 | const enum bmp_error err = bmp_header_read (&img->img_header, img_file); 188 | 189 | if (err != BMP_OK) 190 | { 191 | // ERROR: Could'nt read the image header! 192 | fclose (img_file); 193 | return err; 194 | } 195 | 196 | bmp_img_alloc (img); 197 | 198 | // Select the mode (bottom-up or top-down): 199 | const size_t h = abs (img->img_header.biHeight); 200 | const size_t offset = (img->img_header.biHeight > 0 ? h - 1 : 0); 201 | const size_t padding = BMP_GET_PADDING (img->img_header.biWidth); 202 | 203 | // Needed to compare the return value of fread 204 | const size_t items = img->img_header.biWidth; 205 | 206 | // Read the content: 207 | for (size_t y = 0; y < h; y++) 208 | { 209 | // Read a whole row of pixels from the file: 210 | if (fread (img->img_pixels[abs (offset - y)], sizeof (bmp_pixel), items, img_file) != items) 211 | { 212 | fclose (img_file); 213 | return BMP_ERROR; 214 | } 215 | 216 | // Skip the padding: 217 | fseek (img_file, padding, SEEK_CUR); 218 | } 219 | 220 | // NOTE: All good! 221 | fclose (img_file); 222 | return BMP_OK; 223 | } 224 | -------------------------------------------------------------------------------- /lab10/libbmp/libbmp.h: -------------------------------------------------------------------------------- 1 | #ifndef __LIBBMP_H__ 2 | #define __LIBBMP_H__ 3 | 4 | #define BMP_MAGIC 19778 5 | 6 | #define BMP_GET_PADDING(a) ((a) % 4) 7 | 8 | enum bmp_error 9 | { 10 | BMP_FILE_NOT_OPENED = -4, 11 | BMP_HEADER_NOT_INITIALIZED, 12 | BMP_INVALID_FILE, 13 | BMP_ERROR, 14 | BMP_OK = 0 15 | }; 16 | 17 | typedef struct _bmp_header 18 | { 19 | unsigned int bfSize; 20 | unsigned int bfReserved; 21 | unsigned int bfOffBits; 22 | 23 | unsigned int biSize; 24 | int biWidth; 25 | int biHeight; 26 | unsigned short biPlanes; 27 | unsigned short biBitCount; 28 | unsigned int biCompression; 29 | unsigned int biSizeImage; 30 | int biXPelsPerMeter; 31 | int biYPelsPerMeter; 32 | unsigned int biClrUsed; 33 | unsigned int biClrImportant; 34 | } bmp_header; 35 | 36 | typedef struct _bmp_pixel 37 | { 38 | unsigned char blue; 39 | unsigned char green; 40 | unsigned char red; 41 | } bmp_pixel; 42 | 43 | // This is faster than a function call 44 | #define BMP_PIXEL(r,g,b) ((bmp_pixel){(b),(g),(r)}) 45 | 46 | typedef struct _bmp_img 47 | { 48 | bmp_header img_header; 49 | bmp_pixel **img_pixels; 50 | } bmp_img; 51 | 52 | // BMP_HEADER 53 | void bmp_header_init_df (bmp_header*, 54 | const int, 55 | const int); 56 | 57 | enum bmp_error bmp_header_write (const bmp_header*, 58 | FILE*); 59 | 60 | enum bmp_error bmp_header_read (bmp_header*, 61 | FILE*); 62 | 63 | // BMP_PIXEL 64 | void bmp_pixel_init (bmp_pixel*, 65 | const unsigned char, 66 | const unsigned char, 67 | const unsigned char); 68 | 69 | // BMP_IMG 70 | void bmp_img_alloc (bmp_img*); 71 | void bmp_img_init_df (bmp_img*, 72 | const int, 73 | const int); 74 | void bmp_img_free (bmp_img*); 75 | 76 | enum bmp_error bmp_img_write (const bmp_img*, 77 | const char*); 78 | 79 | enum bmp_error bmp_img_read (bmp_img*, 80 | const char*); 81 | 82 | #endif /* __LIBBMP_H__ */ 83 | -------------------------------------------------------------------------------- /lab10/libhttp/libhttp.c: -------------------------------------------------------------------------------- 1 | #include "libhttp.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define LIBHTTP_REQUEST_MAX_SIZE 8192 10 | 11 | void http_fatal_error(char *message) { 12 | fprintf(stderr, "%s\n", message); 13 | exit(ENOBUFS); 14 | } 15 | 16 | struct http_request *http_request_parse(int fd) { 17 | struct http_request *request = malloc(sizeof(struct http_request)); 18 | if (!request) http_fatal_error("Malloc failed"); 19 | 20 | char *read_buffer = malloc(LIBHTTP_REQUEST_MAX_SIZE + 1); 21 | if (!read_buffer) http_fatal_error("Malloc failed"); 22 | 23 | int bytes_read = read(fd, read_buffer, LIBHTTP_REQUEST_MAX_SIZE); 24 | read_buffer[bytes_read] = '\0'; /* Always null-terminate. */ 25 | 26 | char *read_start, *read_end; 27 | size_t read_size; 28 | 29 | do { 30 | /* Read in the HTTP method: "[A-Z]*" */ 31 | read_start = read_end = read_buffer; 32 | while (*read_end >= 'A' && *read_end <= 'Z') read_end++; 33 | read_size = read_end - read_start; 34 | if (read_size == 0) break; 35 | request->method = malloc(read_size + 1); 36 | memcpy(request->method, read_start, read_size); 37 | request->method[read_size] = '\0'; 38 | 39 | /* Read in a space character. */ 40 | read_start = read_end; 41 | if (*read_end != ' ') break; 42 | read_end++; 43 | 44 | /* Read in the path: "[^ \n]*" */ 45 | read_start = read_end; 46 | while (*read_end != '\0' && *read_end != ' ' && *read_end != '\n') 47 | read_end++; 48 | read_size = read_end - read_start; 49 | if (read_size == 0) break; 50 | request->path = malloc(read_size + 1); 51 | memcpy(request->path, read_start, read_size); 52 | request->path[read_size] = '\0'; 53 | 54 | /* Read in HTTP version and rest of request line: ".*" */ 55 | read_start = read_end; 56 | while (*read_end != '\0' && *read_end != '\n') read_end++; 57 | if (*read_end != '\n') break; 58 | read_end++; 59 | 60 | free(read_buffer); 61 | return request; 62 | } while (0); 63 | 64 | /* An error occurred. */ 65 | free(request); 66 | free(read_buffer); 67 | return NULL; 68 | } 69 | 70 | char *http_get_response_message(int status_code) { 71 | switch (status_code) { 72 | case 100: 73 | return "100 Continue"; 74 | case 200: 75 | return "200 OK"; 76 | case 301: 77 | return "Redirection 301: Moved Permanently"; 78 | case 400: 79 | return "Error 400: Bad Request"; 80 | case 401: 81 | return "Error 401: Unauthorized"; 82 | case 403: 83 | return "Error 403: Forbidden"; 84 | case 404: 85 | return "Error 404: Not Found"; 86 | default: 87 | return "Error 500: Internal Server Error"; 88 | } 89 | } 90 | 91 | void http_start_response(int fd, int status_code) { 92 | dprintf(fd, "HTTP/1.0 %d %s\r\n", status_code, 93 | http_get_response_message(status_code)); 94 | } 95 | 96 | void http_send_header(int fd, char *key, char *value) { 97 | dprintf(fd, "%s: %s\r\n", key, value); 98 | } 99 | 100 | void http_end_headers(int fd) { dprintf(fd, "\r\n"); } 101 | 102 | void http_send_string(int fd, char *data) { 103 | http_send_data(fd, data, strlen(data)); 104 | } 105 | 106 | void http_send_data(int fd, char *data, size_t size) { 107 | ssize_t bytes_sent; 108 | while (size > 0) { 109 | bytes_sent = write(fd, data, size); 110 | if (bytes_sent < 0) return; 111 | size -= bytes_sent; 112 | data += bytes_sent; 113 | } 114 | } 115 | 116 | char *http_get_mime_type(char *file_name) { 117 | char *file_extension = strrchr(file_name, '.'); 118 | if (file_extension == NULL) 119 | return "text/plain"; 120 | 121 | if (strcmp(file_extension, ".html") == 0 || 122 | strcmp(file_extension, ".htm") == 0) { 123 | return "text/html"; 124 | } else if (strcmp(file_extension, ".jpg") == 0 || 125 | strcmp(file_extension, ".jpeg") == 0) { 126 | return "image/jpeg"; 127 | } else if (strcmp(file_extension, ".bmp") == 0) { 128 | return "image/bmp"; 129 | } else if (strcmp(file_extension, ".png") == 0) { 130 | return "image/png"; 131 | } else if (strcmp(file_extension, ".css") == 0) { 132 | return "text/css"; 133 | } else if (strcmp(file_extension, ".js") == 0) { 134 | return "application/javascript"; 135 | } else if (strcmp(file_extension, ".pdf") == 0) { 136 | return "application/pdf"; 137 | } else { 138 | return "text/plain"; 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /lab10/libhttp/libhttp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * A simple HTTP library. 3 | * Usage example: 4 | * 5 | * // Returns NULL if an error was encountered. 6 | * struct http_request *request = http_request_parse(fd); 7 | * 8 | * ... 9 | * 10 | * http_start_response(fd, 200); 11 | * http_send_header(fd, "Content-type", http_get_mime_type("index_backup.html")); 12 | * http_send_header(fd, "Server", "httpserver/1.0"); 13 | * http_end_headers(fd); 14 | * http_send_string(fd, "Home"); 15 | * 16 | * close(fd); 17 | */ 18 | 19 | #ifndef LIBHTTP_H 20 | #define LIBHTTP_H 21 | 22 | #include 23 | 24 | /** Functions for parsing an HTTP request. */ 25 | struct http_request { 26 | char *method; 27 | char *path; 28 | }; 29 | 30 | struct http_request *http_request_parse(int fd); 31 | char *http_get_response_message(int status_code); 32 | 33 | /** Functions for sending an HTTP response. */ 34 | void http_start_response(int fd, int status_code); 35 | void http_send_header(int fd, char *key, char *value); 36 | void http_end_headers(int fd); 37 | void http_send_string(int fd, char *data); 38 | void http_send_data(int fd, char *data, size_t size); 39 | 40 | /** Helper function: gets the Content-Type based on a file name. */ 41 | char *http_get_mime_type(char *file_name); 42 | 43 | void route(); 44 | 45 | // some interesting macro for `route()` 46 | #define ROUTE_START() if (0) { 47 | #define ROUTE(METHOD, URI) \ 48 | } \ 49 | else if (strcmp(URI, uri) == 0 && strcmp(METHOD, method) == 0) { 50 | #define ROUTE_GET(URI) ROUTE("GET", URI) 51 | #define ROUTE_POST(URI) ROUTE("POST", URI) 52 | #define ROUTE_END() \ 53 | } \ 54 | else printf( \ 55 | "HTTP/1.1 500 Internal Server Error\n\n" \ 56 | "The server has no handler to the request.\n"); 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /lab10/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) { 125 | pos += sprintf(pos, "Incorrect result!\n"); 126 | *pos = '\0'; 127 | return report_buf; 128 | } 129 | } 130 | 131 | for (int i = 1; i <= num_threads; i++) { 132 | omp_set_num_threads(i); 133 | start_time = omp_get_wtime(); 134 | 135 | for (int j = 0; j < REPEAT; j++) { 136 | result = dotp_reduction_optimized(x, y, arr_size); 137 | } 138 | 139 | run_time = omp_get_wtime() - start_time; 140 | pos += sprintf(pos, "Reduction Optimized: %d thread(s) took %f seconds\n", 141 | i, run_time); 142 | 143 | // verify result is correct (within some threshold) 144 | if (fabs(serial_result - result) > 0.001) { 145 | pos += sprintf(pos, "Incorrect result!\n"); 146 | *pos = '\0'; 147 | return report_buf; 148 | } 149 | } 150 | 151 | // Only run this once because it's too slow.. 152 | omp_set_num_threads(1); 153 | start_time = omp_get_wtime(); 154 | for (int j = 0; j < REPEAT; j++) result = dotp_naive(x, y, arr_size); 155 | run_time = omp_get_wtime() - start_time; 156 | 157 | pos += sprintf(pos, "Naive: %d thread(s) took %f seconds\n", 1, run_time); 158 | *pos = '\0'; 159 | return report_buf; 160 | } 161 | 162 | 163 | /* ---------------------Image Processing: Sobel Edge Detector----------------------*/ 164 | int sobel[3][3] = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}}; 165 | void sobel_filter(bmp_pixel **src, bmp_pixel **dst, int row, int col) { 166 | int res = 0; 167 | for (int i = 0; i < 3; i++) { 168 | for (int j = 0; j < 3; j++) { 169 | bmp_pixel pxl = src[row - 1 + i][col - 1 + j]; 170 | res += ((int)pxl.blue + (int)pxl.green + (int)pxl.red) * sobel[i][j]; 171 | } 172 | } 173 | res *= 2; // scale a little bit so the result image is brighter. 174 | res = res < 0? 0 : (res > 255? 255 : res); 175 | bmp_pixel_init(&dst[row][col], res, res, res); 176 | } 177 | 178 | char *image_proc(const char* filename) { 179 | bmp_img img, img_copy; 180 | if (bmp_img_read(&img, filename) != 0) 181 | return 0; 182 | 183 | char *res= (char*)calloc(32, sizeof(char)); 184 | strncat(res, filename, strlen(filename) - 4); 185 | strcat(res, "_sobel.bmp"); 186 | 187 | bmp_img_read(&img_copy, filename); 188 | 189 | unsigned int wid = img.img_header.biWidth; 190 | unsigned int hgt = img.img_header.biHeight; 191 | bmp_img_init_df(&img_copy, wid, hgt); 192 | 193 | // To parallelize these for loops, check out scheduling policy: http://jakascorner.com/blog/2016/06/omp-for-scheduling.html 194 | // and omp collapse directive https://software.intel.com/en-us/articles/openmp-loop-collapse-directive 195 | for (int i = 1; i < hgt-1; i++) { 196 | for (int j = 1; j < wid-1; j++) { 197 | sobel_filter(img.img_pixels, img_copy.img_pixels, i, j); 198 | } 199 | } 200 | bmp_img_write(&img_copy, res); 201 | bmp_img_free(&img_copy); 202 | bmp_img_free(&img); 203 | return res; 204 | } -------------------------------------------------------------------------------- /lab10/omp_apps.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef COMPUTE_DOTP_H 3 | #define COMPUTE_DOTP_H 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "libbmp/libbmp.h" 12 | 13 | #define REPEAT 60 14 | #define BUF_SIZE 8192 15 | 16 | #define ARRAY_SIZE 5000000 17 | 18 | // for web server 19 | char *compute_dotp(int); 20 | char *image_proc(const char*); 21 | 22 | void v_add_naive(double* x, double* y, double* z); 23 | void v_add_optimized_adjacent(double* x, double* y, double* z); 24 | void v_add_optimized_chunks(double* x, double* y, double* z); 25 | double dotp_naive(double* x, double* y, int arr_size); 26 | double dotp_manual_optimized(double* x, double* y, int arr_size); 27 | double dotp_reduction_optimized(double* x, double* y, int arr_size); 28 | 29 | double* gen_array(int n); 30 | int verify(double* x, double* y, void(*funct)(double *x, double *y, double *z)); 31 | 32 | #endif -------------------------------------------------------------------------------- /lab10/server.c: -------------------------------------------------------------------------------- 1 | #include "server_utils.h" 2 | 3 | char *USAGE = "--files directory/ [--port 8000 --concurrency 5]\n"; 4 | char *report = "report.txt"; 5 | 6 | int main(int argc, char **argv) { 7 | signal(SIGINT, signal_callback_handler); 8 | 9 | // default configs 10 | server_port = 8000; 11 | server_files_directory = "./files/"; 12 | 13 | int i; 14 | for (i = 1; i < argc; i++) { 15 | if (strcmp("--files", argv[i]) == 0) { 16 | server_files_directory = argv[++i]; 17 | if (!server_files_directory) { 18 | fprintf(stderr, "Expected argument after --files\n"); 19 | exit_with_usage(argv[0]); 20 | } 21 | } else if (strcmp("--dotp-size", argv[i]) == 0) { 22 | char *size_str = argv[++i]; 23 | if (!size_str) { 24 | fprintf(stderr, "Expected argument after --dotp-size\n"); 25 | exit_with_usage(argv[0]); 26 | } 27 | dotp_size = atoi(size_str); 28 | } else if (strcmp("--port", argv[i]) == 0) { 29 | char *server_port_string = argv[++i]; 30 | if (!server_port_string) { 31 | fprintf(stderr, "Expected argument after --port\n"); 32 | exit_with_usage(argv[0]); 33 | } 34 | server_port = atoi(server_port_string); 35 | } else if (strcmp("--help", argv[i]) == 0) { 36 | exit_with_usage(argv[0]); 37 | } else { 38 | fprintf(stderr, "Unrecognized option: %s\n", argv[i]); 39 | exit_with_usage(argv[0]); 40 | } 41 | } 42 | 43 | chdir(server_files_directory); 44 | serve_forever(&server_fd); 45 | exit(EXIT_SUCCESS); 46 | } 47 | -------------------------------------------------------------------------------- /lab10/server_utils.c: -------------------------------------------------------------------------------- 1 | #include "server_utils.h" 2 | #include 3 | 4 | char *header_tag_left = "

"; 5 | char *header_tag_right = "


"; 6 | char *content_type = "Content-Type"; 7 | char *content_len = "Content-Length"; 8 | int dotp_size = 100000; // default to 5 0s, can be changed from command line arg 9 | const char *template_str = " \ 10 | \ 11 | \ 12 | \ 13 | Sobel Edge Detector Result \ 14 | \ 15 | \ 16 |

Image Filter

\ 17 |

Original

\ 18 | \ 19 |

Sobel-Edge-Detectored

\ 20 | \ 21 | \ 22 | \ 23 | "; 24 | 25 | /** Serves the file at path to the the socket fd. */ 26 | void handle_report_request(int socket_fd, int arr_size) { 27 | char *result = compute_dotp(arr_size); 28 | int size = strlen(result); 29 | http_make_header(socket_fd, "text/html", 200, size); 30 | http_send_data(socket_fd, result, size); 31 | free(result); 32 | } 33 | 34 | void http_make_header(int sfd, char *ftype, int status_code, __off_t size) { 35 | http_start_response(sfd, 200); 36 | http_send_header(sfd, content_type, ftype); 37 | 38 | if (size != -1) { 39 | char size_char[64]; 40 | sprintf(size_char, "%ld", size); 41 | http_send_header(sfd, content_len, size_char); 42 | } 43 | http_end_headers(sfd); 44 | } 45 | 46 | void handle_bmp_request(int socket_fd, char *path) { 47 | char *res = image_proc(path); 48 | char buf[2048]; 49 | 50 | // error occurred in calling image_proc 51 | if (!res) { 52 | printf("Error occurred reading bmp image. \n"); 53 | return; 54 | } 55 | 56 | // Serve the origin and modified image in a html file 57 | http_make_header(socket_fd, "text/html", 200, -1); 58 | sprintf(buf, template_str, path, res); 59 | http_send_string(socket_fd, buf); 60 | } 61 | 62 | /** Serves the file at path to the the socket fd. */ 63 | void http_serve_file(int socket_fd, char *path, int size) { 64 | char *type = http_get_mime_type(basename(path)); 65 | int filed, len_count = 0, cnt = 0; 66 | char buf[BUFSIZ]; 67 | 68 | http_make_header(socket_fd, type, 200, size); 69 | filed = open(path, O_RDONLY); 70 | len_count = 0; 71 | while ((cnt = read(filed, buf, BUFSIZ - 1)) > 0) { 72 | len_count += cnt; 73 | http_send_data(socket_fd, buf, (size_t)cnt); 74 | lseek(filed, len_count, SEEK_SET); 75 | } 76 | close(filed); 77 | } 78 | 79 | /** Serves the directory at path to the the socket fd. */ 80 | void http_serve_directory(int socket_fd, char *path) { 81 | DIR *dir = opendir(path); 82 | struct dirent *ent; 83 | char* fname; 84 | char buf[256]; 85 | 86 | http_make_header(socket_fd, "text/html", 200, -1); 87 | char* start = "
    "; 88 | http_send_string(socket_fd, start); 89 | 90 | while ((ent = readdir(dir)) != NULL) { 91 | fname = ent->d_name; 92 | sprintf(buf, "
  • %s
  • \n", path, fname, fname); 93 | http_send_string(socket_fd, buf); 94 | } 95 | char *end = "
"; 96 | http_send_string(socket_fd, end); 97 | } 98 | 99 | void http_make_error(int socket_fd, int status) { 100 | char msg[64] = {0}; 101 | strcat(msg, header_tag_left); 102 | strcat(msg, http_get_response_message(status)); 103 | strcat(msg, header_tag_right); 104 | 105 | http_make_header(socket_fd, "text/html", status, strlen(msg)); 106 | http_send_string(socket_fd, msg); 107 | } 108 | 109 | void signal_callback_handler(int signum) { 110 | printf("Caught signal %d: %s\n", signum, strsignal(signum)); 111 | printf("Closing socket %d\n", server_fd); 112 | if (shutdown(server_fd, SHUT_RDWR) < 0) 113 | perror("Failed to shutdown socket at server_fd (ignoring)\n"); 114 | if (close(server_fd) < 0) perror("Failed to close server_fd (ignoring)\n"); 115 | exit(EXIT_SUCCESS); 116 | } 117 | 118 | void exit_with_usage(char *executable_name) { 119 | fprintf(stderr, "Usage:"); 120 | fprintf(stderr, " %s ", executable_name); 121 | fprintf(stderr, "%s", USAGE); 122 | exit(EXIT_SUCCESS); 123 | } 124 | 125 | inline int start_with(char *src, char *target) { 126 | return strncmp(src, target, strlen(target)) == 0; 127 | } 128 | 129 | /** Reads an HTTP request from socket_fd, and deliver an HTTP response 130 | * 1) If requested an existing file, respond with the file 131 | * 2) If requested a directory: 132 | * if there exists an index.html present in the directory, 133 | * send index.html. otherwise list files in the directory with links. 134 | * 4) Send a 404 Not Found if no result found. */ 135 | void handle_files_request(int socket_fd, struct http_request *request) { 136 | char path[128] = {0}; 137 | path[0] = '.'; 138 | 139 | // If requested file is a bmp image, apply sobel edge detector 140 | // and deliver the result images 141 | if (start_with(request->path, "/filter") && strcmp(http_get_mime_type(request->path), "image/bmp") == 0 ) { 142 | strcpy(path + 1, request->path + strlen("/filter")); 143 | handle_bmp_request(socket_fd, path); 144 | return; 145 | } 146 | strcpy(path + 1, request->path); 147 | 148 | struct stat file_stat; 149 | stat(path, &file_stat); 150 | 151 | if ((file_stat.st_mode & __S_IFMT) == __S_IFREG) { 152 | http_serve_file(socket_fd, path, file_stat.st_size); 153 | return; 154 | } else if ((file_stat.st_mode & __S_IFMT) == __S_IFDIR) { 155 | char path_origin[128] = {0}; 156 | strncpy(path_origin, path, strlen(path)); 157 | strcat(path, "//index.html"); 158 | if (stat(path, &file_stat) == -1) { 159 | http_serve_directory(socket_fd, path_origin); 160 | } else { 161 | http_serve_file(socket_fd, path, file_stat.st_size); 162 | } 163 | return; 164 | } 165 | 166 | http_make_error(socket_fd, 404); 167 | return; 168 | } 169 | 170 | void dispatch(int client_socket_number) { 171 | struct http_request *request = http_request_parse(client_socket_number); 172 | 173 | if (request == NULL || request->path[0] != '/') { 174 | http_make_error(client_socket_number, 400); return; 175 | } 176 | 177 | if (strstr(request->path, "..") != NULL) { 178 | http_make_error(client_socket_number, 403); return; 179 | } 180 | 181 | printf("%s\n", request->path); 182 | if (strcmp(request->path, "/report") == 0) { 183 | handle_report_request(client_socket_number, dotp_size); 184 | return; 185 | } 186 | 187 | if (strcmp(request->method, "GET") != 0) { 188 | printf("Sorry we only support GET method so far... %s\n", request->method); 189 | return; 190 | } 191 | 192 | // only support GET request 193 | void (*request_handler)(int, struct http_request*) = &handle_files_request; 194 | 195 | request_handler(client_socket_number, request); 196 | close(client_socket_number); 197 | 198 | sleep(5); // Pretending we are doing some heavy computation... 199 | } 200 | 201 | /** Open a TCP socket on all interfaces. *socket_number stores 202 | * the fd number of the server socket in call request_handler 203 | * with the accepted socket fd number on an accepted connection.*/ 204 | void serve_forever(int *socket_number) { 205 | struct sockaddr_in server_address, client_address; 206 | size_t client_address_length = sizeof(client_address); 207 | int client_socket_number; 208 | 209 | *socket_number = socket(PF_INET, SOCK_STREAM, 0); 210 | if (*socket_number == -1) { 211 | perror("Failed to create new socket"); 212 | exit(errno); 213 | } 214 | 215 | int socket_option = 1; 216 | if (setsockopt(*socket_number, SOL_SOCKET, SO_REUSEADDR, &socket_option, 217 | sizeof(socket_option)) == -1) { 218 | perror("Failed to set socket options"); 219 | exit(errno); 220 | } 221 | 222 | memset(&server_address, 0, sizeof(server_address)); 223 | server_address.sin_family = AF_INET; 224 | server_address.sin_addr.s_addr = INADDR_ANY; 225 | server_address.sin_port = htons(server_port); 226 | 227 | if (bind(*socket_number, (struct sockaddr *)&server_address, 228 | sizeof(server_address)) == -1) { 229 | perror("Failed to bind on socket"); 230 | exit(errno); 231 | } 232 | 233 | if (listen(*socket_number, 1024) == -1) { 234 | perror("Failed to listen on socket"); 235 | exit(errno); 236 | } 237 | 238 | printf("Listening on port %d...\n", server_port); 239 | 240 | while (1) { 241 | client_socket_number = accept(*socket_number, 242 | (struct sockaddr *) &client_address, 243 | (socklen_t * ) & client_address_length); 244 | if (client_socket_number < 0) { 245 | perror("Error accepting socket"); 246 | continue; 247 | } 248 | 249 | printf("Accepted connection from %s on port %d\n", 250 | inet_ntoa(client_address.sin_addr), client_address.sin_port); 251 | 252 | pid_t parent_pid = getpid(); 253 | #ifdef PROC 254 | // PART 2 TASK: Implement forking 255 | /* YOUR CODE HERE */ 256 | 257 | if (/* YOUR CODE HERE */) { 258 | // This line kills the child process if parent dies 259 | int r = prctl(PR_SET_PDEATHSIG, SIGTERM); 260 | 261 | /* YOUR CODE HERE */ 262 | 263 | // These lines exit the current process with code 1 264 | // 1) when there was an error in prctl, 2) when the parent has been killed 265 | if (r == -1 || getppid() != parent_pid) { 266 | perror(0); 267 | exit(1); 268 | } 269 | 270 | /* YOUR CODE HERE */ 271 | } 272 | #else 273 | dispatch(client_socket_number); 274 | #endif 275 | } 276 | } -------------------------------------------------------------------------------- /lab10/server_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef THREAD_LAB_SERVER_UTILS_H 2 | #define THREAD_LAB_SERVER_UTILS_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "omp_apps.h" 24 | #include "libhttp/libhttp.h" 25 | 26 | /** Global configuration variables. */ 27 | int server_fd; 28 | int server_port; 29 | char *server_files_directory; 30 | 31 | extern char *USAGE; 32 | extern char *report; 33 | extern char *header_tag_left; 34 | extern char *header_tag_right; 35 | extern char *content_type; 36 | extern char *content_len; 37 | extern int dotp_size; 38 | 39 | int start_with(char*, char*); 40 | 41 | void http_make_header(int, char *, int, __off_t); 42 | 43 | void http_make_error(int , int ); 44 | 45 | void signal_callback_handler(int ); 46 | 47 | void exit_with_usage(char*); 48 | 49 | void handle_report_request(int, int); 50 | 51 | /** Serves the file at path to the the socket fd. */ 52 | void http_serve_file(int, char*, int); 53 | 54 | /** Serves the directory at path to the the socket fd. */ 55 | void http_serve_directory(int socket_fd, char *path); 56 | 57 | /** Request handler**/ 58 | void handle_files_request(int socket_fd, struct http_request*); 59 | 60 | void serve_forever(int *socket_number); 61 | 62 | void dispatch(int); 63 | 64 | #endif //THREAD_LAB_SERVER_UTILS_H 65 | -------------------------------------------------------------------------------- /lab10/timer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | host='localhost' 5 | port='8000' 6 | num_reqs=3 7 | timeout=6 8 | 9 | print_usage() { 10 | printf "Usage: $0 [-h host] [-p port] [-n number of reqs] [-t timeout (seconds)]" 11 | } 12 | 13 | while getopts 'h:p:n:t:' flag; do 14 | case "${flag}" in 15 | h) host="${OPTARG}" ;; 16 | p) port="${OPTARG}" ;; 17 | n) num_reqs="${OPTARG}" ;; 18 | t) timeout="${OPTARG}" ;; 19 | *) print_usage 20 | exit 1 ;; 21 | esac 22 | done 23 | 24 | echo "Making $num_reqs consecutive requests..." 25 | elapsed=0 26 | for ((i=1;i<=$num_reqs;i++)); do 27 | echo -ne "Request $i/$num_reqs...\r" 28 | start_time="$(date +%s%3N)" 29 | curl -sS -m "$timeout" -o/dev/null "http://$host:$port/" 30 | end_time="$(date +%s%3N)" 31 | elapsed=$(($elapsed + $end_time - $start_time)) 32 | done 33 | echo "Time elapsed: ${elapsed}ms" 34 | -------------------------------------------------------------------------------- /lab10/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 | 17 | for (int i=1; i<=num_threads; i++) { 18 | omp_set_num_threads(i); 19 | start_time = omp_get_wtime(); 20 | for(int j=0; j outputs/createIndices 11 | 12 | spark-submit mostPopular.py seqFiles/billOfRights.txt.seq 13 | mv spark-wc-out-mostPopular/part-00000 outputs/mostPopular -------------------------------------------------------------------------------- /lab11/textFiles/billOfRights.txt: -------------------------------------------------------------------------------- 1 | Amendment I 2 | 3 | Congress shall make no law respecting an establishment of religion, or prohibiting the free exercise thereof; or abridging the freedom of speech, or of the press; or the right of the people peaceably to assemble, and to petition the Government for a redress of grievances. 4 | 5 | ---END.OF.DOCUMENT--- 6 | 7 | Amendment II 8 | 9 | A well regulated Militia, being necessary to the security of a free State, the right of the people to keep and bear Arms, shall not be infringed. 10 | 11 | ---END.OF.DOCUMENT--- 12 | 13 | Amendment III 14 | 15 | No Soldier shall, in time of peace be quartered in any house, without the consent of the Owner, nor in time of war, but in a manner to be prescribed by law. 16 | 17 | ---END.OF.DOCUMENT--- 18 | 19 | Amendment IV 20 | 21 | The right of the people to be secure in their persons, houses, papers, and effects, against unreasonable searches and seizures, shall not be violated, and no Warrants shall issue, but upon probable cause, supported by Oath or affirmation, and particularly describing the place to be searched, and the persons or things to be seized. 22 | 23 | ---END.OF.DOCUMENT--- 24 | 25 | Amendment V 26 | 27 | No person shall be held to answer for a capital, or otherwise infamous crime, unless on a presentment or indictment of a Grand Jury, except in cases arising in the land or naval forces, or in the Militia, when in actual service in time of War or public danger; nor shall any person be subject for the same offence to be twice put in jeopardy of life or limb; nor shall be compelled in any criminal case to be a witness against himself, nor be deprived of life, liberty, or property, without due process of law; nor shall private property be taken for public use, without just compensation. 28 | 29 | ---END.OF.DOCUMENT--- 30 | 31 | Amendment VI 32 | 33 | In all criminal prosecutions, the accused shall enjoy the right to a speedy and public trial, by an impartial jury of the State and district wherein the crime shall have been committed, which district shall have been previously ascertained by law, and to be informed of the nature and cause of the accusation; to be confronted with the witnesses against him; to have compulsory process for obtaining witnesses in his favor, and to have the Assistance of Counsel for his defence. 34 | 35 | ---END.OF.DOCUMENT--- 36 | 37 | Amendment VII 38 | 39 | In Suits at common law, where the value in controversy shall exceed twenty dollars, the right of trial by jury shall be preserved, and no fact tried by a jury, shall be otherwise re-examined in any Court of the United States, than according to the rules of the common law. 40 | 41 | ---END.OF.DOCUMENT--- 42 | 43 | Amendment VIII 44 | 45 | Excessive bail shall not be required, nor excessive fines imposed, nor cruel and unusual punishments inflicted. 46 | 47 | ---END.OF.DOCUMENT--- 48 | 49 | Amendment IX 50 | 51 | The enumeration in the Constitution, of certain rights, shall not be construed to deny or disparage others retained by the people. 52 | 53 | ---END.OF.DOCUMENT--- 54 | 55 | Amendment X 56 | 57 | The powers not delegated to the United States by the Constitution, nor prohibited by it to the States, are reserved to the States respectively, or to the people. 58 | -------------------------------------------------------------------------------- /lab11/textImporter/Importer.java: -------------------------------------------------------------------------------- 1 | /* Written by Ariel Rabkin , 2011. 2 | * Copyright 2011, the Regents of the University of California. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 21 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | */ 26 | 27 | import java.io.*; 28 | import java.security.MessageDigest; 29 | import org.apache.hadoop.conf.Configuration; 30 | import org.apache.hadoop.fs.FSDataOutputStream; 31 | import org.apache.hadoop.fs.FileSystem; 32 | import org.apache.hadoop.fs.Path; 33 | import org.apache.hadoop.io.SequenceFile; 34 | import org.apache.hadoop.io.Text; 35 | import org.apache.hadoop.io.compress.*; 36 | import org.apache.hadoop.io.compress.bzip2.CBZip2InputStream; 37 | 38 | /** 39 | * Converts text files to sequence files, suitably for cs61c project 1, Spring 201 40 | * 41 | * Usage: Importer [output] 42 | * If invoked on a text file, converts that file to compressed sequence file, writing the output 43 | * in output dir. 44 | * If invoked on a directory, recursively scans that directory and subdirs for .txt 45 | * files, storing output to output dir. 46 | * 47 | * Each input file is split at boundaries, where a boundary is a line containing 48 | * exactly the text: "---END.OF.DOCUMENT---" 49 | * 50 | * Will also process .bz2 files, first decompressing them. 51 | * 52 | * Default output dir is "convertedOut" 53 | * 54 | * Written by Ariel Rabkin, asrabkin@gmail.com 55 | * Licensed under the terms of the New BSD License. 56 | * 57 | */ 58 | public class Importer { 59 | 60 | static SequenceFile.Writer seqFileWriter; 61 | static long totalBytes = 0; 62 | static long totalRecords = 0; 63 | static long files = 0; 64 | static File outDir = new File("convertedOut"); 65 | public static void main(String[] args) { 66 | try { 67 | if(args.length < 1) { 68 | System.err.println("can't run. Not enough args. Need to specify input file or dir"); 69 | System.exit(-1); 70 | } else 71 | System.out.println("starting scan of " + args[0]); 72 | 73 | if(args.length > 1) 74 | outDir = new File(args[1]); 75 | System.out.println("dumping output to " + outDir.getAbsolutePath()); 76 | 77 | lookForFiles(new File(args[0])); 78 | long avgRecLength = totalBytes / totalRecords; 79 | System.out.println("total data, uncompressed was " + totalBytes/ (1024 * 1024) + " MB"); 80 | System.out.println("total of " + totalRecords + " records. (Avg uncompressed size " + avgRecLength + " bytes)"); 81 | } catch(Exception e) { 82 | e.printStackTrace(); 83 | } 84 | } 85 | 86 | public static Text hash(Text content) throws Exception { 87 | StringBuilder sb = new StringBuilder(); 88 | sb.append("doc_"); 89 | 90 | MessageDigest md = MessageDigest.getInstance("MD5"); 91 | 92 | md.update(content.getBytes(), 0, content.getLength()); 93 | byte[] bytes = md.digest(); 94 | for(int i=0; i < bytes.length; ++i) { 95 | if( (bytes[i] & 0xF0) == 0) 96 | sb.append('0'); 97 | sb.append( Integer.toHexString(0xFF & bytes[i]) ); 98 | } 99 | return new Text(sb.toString()); 100 | } 101 | 102 | static void lookForFiles(File file) throws Exception { 103 | if(file.isDirectory()) { 104 | File[] contents = file.listFiles(); 105 | if(contents == null) { 106 | System.out.println("WARN: null list of contents for " + file.getAbsolutePath()); 107 | return; 108 | } 109 | for(File sub: contents) 110 | lookForFiles(sub); 111 | } else { 112 | if(file.getName().endsWith(".bz2") || file.getName().contains(".txt")) 113 | copyFile(file); 114 | } 115 | } 116 | 117 | public static void copyFile(File file) throws Exception { 118 | // String TEST_PREFIX = ""; 119 | File destFile = new File(outDir,file.getName()+".seq"); 120 | Path dest = new Path(destFile.getAbsolutePath()); 121 | 122 | Configuration conf = new Configuration(); 123 | FileSystem fileSys = org.apache.hadoop.fs.FileSystem.get(new java.net.URI(conf.get("fs.default.name")),conf); 124 | CompressionCodec codec = new DefaultCodec(); 125 | fileSys.mkdirs(dest.getParent()); 126 | FSDataOutputStream outputStr = fileSys.create(dest); 127 | seqFileWriter = SequenceFile.createWriter(conf, outputStr, 128 | Text.class, Text.class, 129 | SequenceFile.CompressionType.BLOCK, codec); 130 | String filename = file.getName(); 131 | InputStream in = new BufferedInputStream(new FileInputStream(file)); 132 | if(filename.endsWith(".bz2")) { 133 | in.read(); 134 | in.read(); //snarf header 135 | in = new CBZip2InputStream(in); 136 | } 137 | BufferedReader br = new BufferedReader(new InputStreamReader(in, "US-ASCII")); 138 | 139 | System.out.println("working on file " + file); 140 | int records = 0; 141 | long bytes = 0, bytes_since_status = 0; 142 | long startTime= System.currentTimeMillis(); 143 | String s = null; 144 | Text content = new Text(); 145 | while( (s = br.readLine()) != null) { 146 | if(s.startsWith("---END.OF.DOCUMENT---")) { 147 | Text name = new Text(hash(content)); 148 | seqFileWriter.append(name, content); 149 | records ++; 150 | content = new Text(); 151 | } else { 152 | byte[] line_as_bytes = (s+ " ").getBytes(); 153 | for(byte b: line_as_bytes) { 154 | assert b < 128: "found an unexpected high-bit set"; 155 | } 156 | 157 | content.append(line_as_bytes, 0, line_as_bytes.length); 158 | bytes += line_as_bytes.length; 159 | /* 160 | bytes_since_status += line_as_bytes.length; 161 | if(bytes_since_status > 10 * 1024 * 1024) { //every 10 MB 162 | System.err.print('.'); 163 | bytes_since_status = 0; 164 | }*/ 165 | } 166 | } //end while 167 | if(content.getLength() > 5) { 168 | Text name = new Text(hash(content)); 169 | seqFileWriter.append(name, content); 170 | records ++; 171 | } 172 | totalBytes += bytes; 173 | totalRecords += records; 174 | long time = (System.currentTimeMillis() - startTime)/ 1000 + 1; 175 | long kbSec = bytes / 1024 / time; 176 | System.out.println(new java.util.Date()); 177 | System.out.println("File " + file.getName() + " " + records+ " records, " + 178 | bytes + " bytes in " + time+ " seconds (" +kbSec + " KB/sec)."); 179 | in.close(); 180 | seqFileWriter.close(); 181 | outputStr.close(); 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /lab11/textImporter/wc.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/61c-teach/fa20-lab-starter/e4545d88812dcc2c618f0b194f5acc2b6681b9e2/lab11/textImporter/wc.jar -------------------------------------------------------------------------------- /lab11/wordCount.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import re 3 | 4 | from pyspark import SparkContext,SparkConf 5 | 6 | def splitDocument(document): 7 | """Returns a list of all words in the document""" 8 | return re.findall(r"\w+", document[1]) 9 | 10 | def toPairs(word): 11 | """ Creates `(key, value)` pairs where the word is the key and 1 is the value """ 12 | return (word, 1) 13 | 14 | def sumCounts(a, b): 15 | """ Add up the values for each word, resulting in a count of occurences """ 16 | return a + b 17 | 18 | def wordCount(file_name, output="spark-wc-out-wordCount"): 19 | sc = SparkContext("local[8]", "WordCount", conf=SparkConf().set("spark.hadoop.validateOutputSpecs", "false")) 20 | """ Reads in a sequence file FILE_NAME to be manipulated """ 21 | file = sc.sequenceFile(file_name) 22 | 23 | """ 24 | - Explanation: 25 | - 26 | - `flatMap` takes in a function that will take one input and outputs 0 or 27 | - more items. All returned results are combined into a single list of 28 | - items that future functions are run on. We use this function to 29 | - transform our document into a list of words. 30 | - 31 | - `map` takes in a function take in one item, perform an action on it, and 32 | - return the result. When called on a list, it applies the function to 33 | - each item in the list. We use this function transform our words into 34 | - `(key, value)` pairs, with the key being the word and the value being 35 | - the number of times it occurs. 36 | - 37 | - `reduceByKey` groups a list of `(key, value)` pairs by keys and runs a 38 | - function on each key which takes two values and returns a single value 39 | - (i.e. "reducing" them two inputs into one). It will be called 40 | - iteratively on each key until only a single value remains for that key. 41 | - We use this function to sum the number of times a word occurs. 42 | """ 43 | counts = file.flatMap(splitDocument) \ 44 | .map(toPairs) \ 45 | .reduceByKey(sumCounts) 46 | 47 | """ Takes the dataset stored in counts and writes everything out to OUTPUT """ 48 | counts.coalesce(1).saveAsTextFile(output) 49 | 50 | """ Do not worry about this """ 51 | if __name__ == "__main__": 52 | argv = sys.argv 53 | if len(argv) == 2: 54 | wordCount(argv[1]) 55 | else: 56 | wordCount(argv[1], argv[2]) 57 | -------------------------------------------------------------------------------- /tools/venus.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/61c-teach/fa20-lab-starter/e4545d88812dcc2c618f0b194f5acc2b6681b9e2/tools/venus.jar --------------------------------------------------------------------------------