├── .gitmodules ├── 1 - Maze ├── assets │ ├── maps │ │ ├── maps with solution │ │ │ ├── code_result_0.txt │ │ │ ├── code_result_1.txt │ │ │ ├── code_result_2.txt │ │ │ ├── code_result_3.txt │ │ │ ├── map_0.txt │ │ │ ├── map_1.txt │ │ │ ├── map_2.txt │ │ │ ├── map_3.txt │ │ │ ├── maze_0.dat │ │ │ ├── maze_1.dat │ │ │ ├── maze_2.dat │ │ │ ├── maze_3.dat │ │ │ ├── result_0.txt │ │ │ ├── result_1.txt │ │ │ ├── result_2.txt │ │ │ └── result_3.txt │ │ └── maps without solution │ │ │ ├── map_0.txt │ │ │ ├── map_1.txt │ │ │ ├── map_2.txt │ │ │ ├── maze_0.dat │ │ │ ├── maze_1.dat │ │ │ └── maze_2.dat │ ├── photos │ │ ├── Controller diagram.png │ │ ├── DataPath.png │ │ ├── abstract_level_design.png │ │ ├── datapath1.png │ │ ├── datapath2.png │ │ ├── datapath3.png │ │ ├── datapath4.png │ │ └── datapath5.png │ ├── problem description │ │ └── CA#01.pdf │ └── utils │ │ ├── generate │ │ ├── generate.py │ │ └── generate_valid.py │ │ └── judge │ │ ├── check_path.py │ │ ├── convert.py │ │ └── intelligent_rat.py └── code │ ├── controller.v │ ├── counter2bit.v │ ├── datapth.v │ ├── incrementer_decrementer.v │ ├── intelligent_rat.v │ ├── list.v │ ├── maze_memory.v │ ├── mux2in.v │ ├── register.v │ ├── stack.v │ └── tb.v ├── 2 - RISC-V Single-Cycle ├── assets │ ├── assembly │ │ ├── maxarray.s │ │ └── maxarraySemiAsm.s │ ├── controller │ │ └── Single-Cycle Controller.jpg │ ├── datapath │ │ └── Single-Cycle Datapath.png │ ├── memory │ │ ├── ArrayData.txt │ │ ├── data.mem │ │ └── instructions.mem │ ├── problem description │ │ └── CA#02.pdf │ └── utils │ │ ├── assembler │ │ ├── customized assembler │ │ │ ├── assembler.bat │ │ │ ├── assembler.py │ │ │ ├── convertToBase2.py │ │ │ ├── main.py │ │ │ ├── toRealAssmebly.py │ │ │ └── type.py │ │ └── online │ │ │ ├── assembler_link.txt │ │ │ └── convert.py │ │ └── data generator │ │ ├── data_generator.bat │ │ ├── data_generator.py │ │ └── io_.py └── code │ ├── ALU.v │ ├── ALU_Controller.v │ ├── Adder.v │ ├── BranchController.v │ ├── DataMemory.v │ ├── ImmediateExtend.v │ ├── InstructionMemory.v │ ├── MainController.v │ ├── Mux2to1.v │ ├── Mux4to1.v │ ├── RISC_V.v │ ├── RISC_V_Controller.v │ ├── RISC_V_Datapath.v │ ├── Register.v │ ├── RregisterFile.v │ └── TestBench.v ├── 3 - RISC-V Multi-Cycle ├── assets │ ├── assembly │ │ ├── maxarray.s │ │ └── maxarraySemiAsm.s │ ├── controller │ │ └── Multi-Cycle Controller.jpg │ ├── datapath │ │ └── Multi-Cycle Datapath.png │ ├── memory │ │ └── instrdata.mem │ ├── problem description │ │ └── CA#03.pdf │ └── utils │ │ ├── assembler │ │ ├── customized_assembler │ │ │ ├── assembler.bat │ │ │ ├── assembler.py │ │ │ ├── convertToBase2.py │ │ │ ├── main.py │ │ │ ├── toRealAssmebly.py │ │ │ └── type.py │ │ └── online │ │ │ ├── assembler_link.txt │ │ │ └── convert.py │ │ ├── combine_data_instr.bat │ │ └── data_generator │ │ ├── data_generator.bat │ │ ├── data_generator.py │ │ └── io_.py └── code │ ├── ALU.v │ ├── ALU_Controller.v │ ├── BranchController.v │ ├── ImmediateExtend.v │ ├── InstrDataMemory.v │ ├── MainController.v │ ├── Mux2to1.v │ ├── Mux4to1.v │ ├── RISC_V.v │ ├── RISC_V_Controller.v │ ├── RISC_V_Datapath.v │ ├── Register.v │ ├── Registerfile.v │ └── TestBench.v ├── 4 - RISC-V Pipeline ├── assets │ ├── assembly │ │ ├── maxarray.s │ │ └── maxarraySemiAsm.s │ ├── controller │ │ └── Pipeline controller.jpg │ ├── datapath │ │ └── Pipeline Datapath.png │ ├── memory │ │ ├── data.mem │ │ └── instructions.mem │ ├── problem description │ │ └── CA#04.pdf │ └── utils │ │ ├── assembler │ │ ├── customized assembler │ │ │ ├── assembler.bat │ │ │ ├── assembler.py │ │ │ ├── convertToBase2.py │ │ │ ├── main.py │ │ │ ├── toRealAssmebly.py │ │ │ └── type.py │ │ └── online │ │ │ ├── assembler_link.txt │ │ │ └── convert.py │ │ └── data generator │ │ ├── data_generator.bat │ │ ├── data_generator.py │ │ └── io_.py └── code │ ├── ALU.v │ ├── ALU_Controller.v │ ├── Adder.v │ ├── BranchController.v │ ├── DataMemory.v │ ├── HazardUnit.v │ ├── ImmediateExtend.v │ ├── InstructionMemory.v │ ├── MainController.v │ ├── Mux2to1.v │ ├── Mux4to1.v │ ├── RISC_V.v │ ├── RISC_V_Controller.v │ ├── RISC_V_Datapath.v │ ├── RegEX_Mem.v │ ├── RegID_EX.v │ ├── RegIF_ID.v │ ├── RegMEM_WB.v │ ├── Register.v │ ├── RegisterFile.v │ └── TestBench.v ├── LICENSE └── README.md /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Archive-Last-Semester"] 2 | path = Archive-Last-Semester 3 | url = https://github.com/MisaghM/Computer-Architecture-Course-Projects 4 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps with solution/code_result_0.txt: -------------------------------------------------------------------------------- 1 | xx 2 | 01 3 | 01 4 | 01 5 | 11 6 | 01 7 | 01 8 | 01 9 | 11 10 | 11 11 | 01 12 | 01 13 | 11 14 | 01 15 | 01 16 | 01 17 | 11 18 | 01 19 | 11 20 | 10 21 | 11 22 | 01 23 | 11 24 | 01 25 | 01 26 | 11 27 | 01 28 | 11 29 | 11 30 | 10 31 | 11 32 | 11 33 | 11 34 | 01 35 | 11 36 | xx 37 | xx 38 | xx 39 | xx 40 | xx 41 | xx 42 | xx 43 | xx 44 | xx 45 | xx 46 | xx 47 | xx 48 | xx 49 | xx 50 | xx 51 | xx 52 | xx 53 | xx 54 | xx 55 | xx 56 | xx 57 | xx 58 | xx 59 | xx 60 | xx 61 | xx 62 | xx 63 | xx 64 | xx 65 | xx 66 | xx 67 | xx 68 | xx 69 | xx 70 | xx 71 | xx 72 | xx 73 | xx 74 | xx 75 | xx 76 | xx 77 | xx 78 | xx 79 | xx 80 | xx 81 | xx 82 | xx 83 | xx 84 | xx 85 | xx 86 | xx 87 | xx 88 | xx 89 | xx 90 | xx 91 | xx 92 | xx 93 | xx 94 | xx 95 | xx 96 | xx 97 | xx 98 | xx 99 | xx 100 | xx 101 | xx 102 | xx 103 | xx 104 | xx 105 | xx 106 | xx 107 | xx 108 | xx 109 | xx 110 | xx 111 | xx 112 | xx 113 | xx 114 | xx 115 | xx 116 | xx 117 | xx 118 | xx 119 | xx 120 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps with solution/code_result_1.txt: -------------------------------------------------------------------------------- 1 | xx 2 | 11 3 | 01 4 | 01 5 | 01 6 | 01 7 | 01 8 | 00 9 | 01 10 | 11 11 | 11 12 | 11 13 | 11 14 | 11 15 | 01 16 | 11 17 | 01 18 | 01 19 | 01 20 | 11 21 | 11 22 | 11 23 | 11 24 | 01 25 | 11 26 | 01 27 | 11 28 | 01 29 | 01 30 | 11 31 | 10 32 | 10 33 | 11 34 | 01 35 | 01 36 | 01 37 | 11 38 | xx 39 | xx 40 | xx 41 | xx 42 | xx 43 | xx 44 | xx 45 | xx 46 | xx 47 | xx 48 | xx 49 | xx 50 | xx 51 | xx 52 | xx 53 | xx 54 | xx 55 | xx 56 | xx 57 | xx 58 | xx 59 | xx 60 | xx 61 | xx 62 | xx 63 | xx 64 | xx 65 | xx 66 | xx 67 | xx 68 | xx 69 | xx 70 | xx 71 | xx 72 | xx 73 | xx 74 | xx 75 | xx 76 | xx 77 | xx 78 | xx 79 | xx 80 | xx 81 | xx 82 | xx 83 | xx 84 | xx 85 | xx 86 | xx 87 | xx 88 | xx 89 | xx 90 | xx 91 | xx 92 | xx 93 | xx 94 | xx 95 | xx 96 | xx 97 | xx 98 | xx 99 | xx 100 | xx 101 | xx 102 | xx 103 | xx 104 | xx 105 | xx 106 | xx 107 | xx 108 | xx 109 | xx 110 | xx 111 | xx 112 | xx 113 | xx 114 | xx 115 | xx 116 | xx 117 | xx 118 | xx 119 | xx 120 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps with solution/code_result_2.txt: -------------------------------------------------------------------------------- 1 | xx 2 | 01 3 | 11 4 | 01 5 | 01 6 | 01 7 | 00 8 | 01 9 | 01 10 | 11 11 | 01 12 | 01 13 | 00 14 | 01 15 | 01 16 | 11 17 | 10 18 | 11 19 | 10 20 | 11 21 | 11 22 | 10 23 | 11 24 | 01 25 | 01 26 | 11 27 | 11 28 | 10 29 | 11 30 | 01 31 | 11 32 | 11 33 | 11 34 | 01 35 | 01 36 | 01 37 | 01 38 | 00 39 | 01 40 | 11 41 | 11 42 | 11 43 | 11 44 | 11 45 | 01 46 | xx 47 | xx 48 | xx 49 | xx 50 | xx 51 | xx 52 | xx 53 | xx 54 | xx 55 | xx 56 | xx 57 | xx 58 | xx 59 | xx 60 | xx 61 | xx 62 | xx 63 | xx 64 | xx 65 | xx 66 | xx 67 | xx 68 | xx 69 | xx 70 | xx 71 | xx 72 | xx 73 | xx 74 | xx 75 | xx 76 | xx 77 | xx 78 | xx 79 | xx 80 | xx 81 | xx 82 | xx 83 | xx 84 | xx 85 | xx 86 | xx 87 | xx 88 | xx 89 | xx 90 | xx 91 | xx 92 | xx 93 | xx 94 | xx 95 | xx 96 | xx 97 | xx 98 | xx 99 | xx 100 | xx 101 | xx 102 | xx 103 | xx 104 | xx 105 | xx 106 | xx 107 | xx 108 | xx 109 | xx 110 | xx 111 | xx 112 | xx 113 | xx 114 | xx 115 | xx 116 | xx 117 | xx 118 | xx 119 | xx 120 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps with solution/code_result_3.txt: -------------------------------------------------------------------------------- 1 | xx 2 | 01 3 | 01 4 | 11 5 | 10 6 | 10 7 | 11 8 | 01 9 | 01 10 | 01 11 | 01 12 | 00 13 | 00 14 | 01 15 | 01 16 | 01 17 | 01 18 | 11 19 | 10 20 | 11 21 | 11 22 | 10 23 | 11 24 | 11 25 | 10 26 | 11 27 | 01 28 | 01 29 | 01 30 | 11 31 | 10 32 | 10 33 | 11 34 | 01 35 | 11 36 | 01 37 | 01 38 | 01 39 | 01 40 | 11 41 | 01 42 | 11 43 | 01 44 | 01 45 | 00 46 | 00 47 | 01 48 | 11 49 | 11 50 | 11 51 | 11 52 | 10 53 | 11 54 | 01 55 | 11 56 | xx 57 | xx 58 | xx 59 | xx 60 | xx 61 | xx 62 | xx 63 | xx 64 | xx 65 | xx 66 | xx 67 | xx 68 | xx 69 | xx 70 | xx 71 | xx 72 | xx 73 | xx 74 | xx 75 | xx 76 | xx 77 | xx 78 | xx 79 | xx 80 | xx 81 | xx 82 | xx 83 | xx 84 | xx 85 | xx 86 | xx 87 | xx 88 | xx 89 | xx 90 | xx 91 | xx 92 | xx 93 | xx 94 | xx 95 | xx 96 | xx 97 | xx 98 | xx 99 | xx 100 | xx 101 | xx 102 | xx 103 | xx 104 | xx 105 | xx 106 | xx 107 | xx 108 | xx 109 | xx 110 | xx 111 | xx 112 | xx 113 | xx 114 | xx 115 | xx 116 | xx 117 | xx 118 | xx 119 | xx 120 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps with solution/map_0.txt: -------------------------------------------------------------------------------- 1 | 0000110011101011 2 | 0110000111001011 3 | 1010010100011001 4 | 1011000001111001 5 | 1100011100001111 6 | 0101010101100010 7 | 1101100100100101 8 | 0111001110100101 9 | 0001001000100001 10 | 0011011011011000 11 | 0111001010011110 12 | 1000100001000000 13 | 0101011001010101 14 | 0100010011101101 15 | 1110011111010000 16 | 0001101011011100 -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps with solution/map_1.txt: -------------------------------------------------------------------------------- 1 | 0111100010101010 2 | 0000000101100101 3 | 1111000110111010 4 | 0001010100011110 5 | 1100110110011000 6 | 1111010011000001 7 | 1001100000010101 8 | 1100001111010011 9 | 1011010110011100 10 | 1010010111011110 11 | 0101000111001001 12 | 1100110000100110 13 | 0001011100100001 14 | 1010100100010001 15 | 0111110110100000 16 | 0110100110000010 17 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps with solution/map_2.txt: -------------------------------------------------------------------------------- 1 | 0011000100000100 2 | 0000000000011011 3 | 0011101100011111 4 | 1111010100101010 5 | 1000111001101101 6 | 0110101000010001 7 | 1101010010100000 8 | 0000010100100101 9 | 0010001000011110 10 | 1110011110101011 11 | 1011010010111001 12 | 0010001000000000 13 | 0000010101111101 14 | 1101110101011001 15 | 1111101101010101 16 | 0010111101011000 17 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps with solution/map_3.txt: -------------------------------------------------------------------------------- 1 | 0001000001001011 2 | 0001010000101111 3 | 0000001011111110 4 | 0010110011101111 5 | 1010010100111100 6 | 0100100101101011 7 | 1001000000001111 8 | 1010100001111111 9 | 1110010011111001 10 | 1111011000001000 11 | 1100001110000100 12 | 1000000100010000 13 | 0001001010111110 14 | 1011000110011000 15 | 1111001100000100 16 | 0100100011000010 17 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps with solution/maze_0.dat: -------------------------------------------------------------------------------- 1 | 0ceb 2 | 61cb 3 | a519 4 | b079 5 | c70f 6 | 5562 7 | d925 8 | 73a5 9 | 1221 10 | 36d8 11 | 729e 12 | 8840 13 | 5655 14 | 44ed 15 | e7d0 16 | 1adc 17 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps with solution/maze_1.dat: -------------------------------------------------------------------------------- 1 | 78aa 2 | 0165 3 | f1ba 4 | 151e 5 | cd98 6 | f4c1 7 | 9815 8 | c3d3 9 | b59c 10 | a5de 11 | 51c9 12 | cc26 13 | 1721 14 | a911 15 | 7da0 16 | 6982 17 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps with solution/maze_2.dat: -------------------------------------------------------------------------------- 1 | 3104 2 | 001b 3 | 3b1f 4 | f52a 5 | 8e6d 6 | 6a11 7 | d4a0 8 | 0525 9 | 221e 10 | e7ab 11 | b4b9 12 | 2200 13 | 057d 14 | dd59 15 | fb55 16 | 2f58 17 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps with solution/maze_3.dat: -------------------------------------------------------------------------------- 1 | 104b 2 | 142f 3 | 02fe 4 | 2cef 5 | a53c 6 | 496b 7 | 900f 8 | a87f 9 | e4f9 10 | f608 11 | c384 12 | 8110 13 | 12be 14 | b198 15 | f304 16 | 48c2 17 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps with solution/result_0.txt: -------------------------------------------------------------------------------- 1 | right 2 | right 3 | right 4 | down 5 | right 6 | right 7 | right 8 | down 9 | down 10 | right 11 | right 12 | down 13 | right 14 | right 15 | right 16 | down 17 | right 18 | down 19 | left 20 | down 21 | right 22 | down 23 | right 24 | right 25 | down 26 | right 27 | down 28 | down 29 | left 30 | down 31 | down 32 | down 33 | right 34 | down 35 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps with solution/result_1.txt: -------------------------------------------------------------------------------- 1 | down 2 | right 3 | right 4 | right 5 | right 6 | right 7 | up 8 | right 9 | down 10 | down 11 | down 12 | down 13 | down 14 | right 15 | down 16 | right 17 | right 18 | right 19 | down 20 | down 21 | down 22 | down 23 | right 24 | down 25 | right 26 | down 27 | right 28 | right 29 | down 30 | left 31 | left 32 | down 33 | right 34 | right 35 | right 36 | down 37 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps with solution/result_2.txt: -------------------------------------------------------------------------------- 1 | right 2 | down 3 | right 4 | right 5 | right 6 | up 7 | right 8 | right 9 | down 10 | right 11 | right 12 | up 13 | right 14 | right 15 | down 16 | left 17 | down 18 | left 19 | down 20 | down 21 | left 22 | down 23 | right 24 | right 25 | down 26 | down 27 | left 28 | down 29 | right 30 | down 31 | down 32 | down 33 | right 34 | right 35 | right 36 | right 37 | up 38 | right 39 | down 40 | down 41 | down 42 | down 43 | down 44 | right 45 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps with solution/result_3.txt: -------------------------------------------------------------------------------- 1 | right 2 | right 3 | down 4 | left 5 | left 6 | down 7 | right 8 | right 9 | right 10 | right 11 | up 12 | up 13 | right 14 | right 15 | right 16 | right 17 | down 18 | left 19 | down 20 | down 21 | left 22 | down 23 | down 24 | left 25 | down 26 | right 27 | right 28 | right 29 | down 30 | left 31 | left 32 | down 33 | right 34 | down 35 | right 36 | right 37 | right 38 | right 39 | down 40 | right 41 | down 42 | right 43 | right 44 | up 45 | up 46 | right 47 | down 48 | down 49 | down 50 | down 51 | left 52 | down 53 | right 54 | down 55 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps without solution/map_0.txt: -------------------------------------------------------------------------------- 1 | 0011101000111010 2 | 0110001110101010 3 | 1101001000111111 4 | 0011100110001110 5 | 1101100110110010 6 | 0100001100011001 7 | 1101011001011011 8 | 1101001010110001 9 | 0111000000001001 10 | 1101011010110010 11 | 1000011100100100 12 | 0110110100011110 13 | 1011001001110011 14 | 1000000011001111 15 | 1100011111111111 16 | 1101101110010000 17 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps without solution/map_1.txt: -------------------------------------------------------------------------------- 1 | 0000100011110100 2 | 0101010010000100 3 | 1110010010100001 4 | 0110011010000000 5 | 0010001111010110 6 | 0111100110111011 7 | 0001010000010011 8 | 0010110001101101 9 | 1111101111010011 10 | 1100001001100110 11 | 0000000000010001 12 | 1001100100111011 13 | 0000011101101110 14 | 0010101010010010 15 | 0010100011001000 16 | 0110101111101000 17 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps without solution/map_2.txt: -------------------------------------------------------------------------------- 1 | 0001101000011000 2 | 1000000110110110 3 | 1101110111110101 4 | 1000001001101110 5 | 0101101101100100 6 | 0010101110010101 7 | 0100010000010111 8 | 1100000011001000 9 | 1101100100101011 10 | 1010000100010110 11 | 0110000100001101 12 | 1101010100111011 13 | 1111100011011000 14 | 1101100111001111 15 | 0010010011101111 16 | 1111000011001000 17 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps without solution/maze_0.dat: -------------------------------------------------------------------------------- 1 | 3a3a 2 | 63aa 3 | d23f 4 | 398e 5 | d9b2 6 | 4319 7 | d65b 8 | d2b1 9 | 7009 10 | d6b2 11 | 8724 12 | 6d1e 13 | b273 14 | 80cf 15 | c7ff 16 | db90 17 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps without solution/maze_1.dat: -------------------------------------------------------------------------------- 1 | 08f4 2 | 5484 3 | e4a1 4 | 6680 5 | 23d6 6 | 79bb 7 | 1413 8 | 2c6d 9 | fbd3 10 | c266 11 | 0011 12 | 993b 13 | 076e 14 | 2a92 15 | 28c8 16 | 6be8 17 | -------------------------------------------------------------------------------- /1 - Maze/assets/maps/maps without solution/maze_2.dat: -------------------------------------------------------------------------------- 1 | 1a18 2 | 81b6 3 | ddf5 4 | 826e 5 | 5b64 6 | 2b95 7 | 4417 8 | c0c8 9 | d92b 10 | a116 11 | 610d 12 | d53b 13 | f8d8 14 | d9cf 15 | 24ef 16 | f0c8 17 | -------------------------------------------------------------------------------- /1 - Maze/assets/photos/Controller diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shahriar-0/Computer-Architecture-Course-Projects-S2023/869ef7aa726a823138fb17e00bcaafadb635655b/1 - Maze/assets/photos/Controller diagram.png -------------------------------------------------------------------------------- /1 - Maze/assets/photos/DataPath.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shahriar-0/Computer-Architecture-Course-Projects-S2023/869ef7aa726a823138fb17e00bcaafadb635655b/1 - Maze/assets/photos/DataPath.png -------------------------------------------------------------------------------- /1 - Maze/assets/photos/abstract_level_design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shahriar-0/Computer-Architecture-Course-Projects-S2023/869ef7aa726a823138fb17e00bcaafadb635655b/1 - Maze/assets/photos/abstract_level_design.png -------------------------------------------------------------------------------- /1 - Maze/assets/photos/datapath1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shahriar-0/Computer-Architecture-Course-Projects-S2023/869ef7aa726a823138fb17e00bcaafadb635655b/1 - Maze/assets/photos/datapath1.png -------------------------------------------------------------------------------- /1 - Maze/assets/photos/datapath2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shahriar-0/Computer-Architecture-Course-Projects-S2023/869ef7aa726a823138fb17e00bcaafadb635655b/1 - Maze/assets/photos/datapath2.png -------------------------------------------------------------------------------- /1 - Maze/assets/photos/datapath3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shahriar-0/Computer-Architecture-Course-Projects-S2023/869ef7aa726a823138fb17e00bcaafadb635655b/1 - Maze/assets/photos/datapath3.png -------------------------------------------------------------------------------- /1 - Maze/assets/photos/datapath4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shahriar-0/Computer-Architecture-Course-Projects-S2023/869ef7aa726a823138fb17e00bcaafadb635655b/1 - Maze/assets/photos/datapath4.png -------------------------------------------------------------------------------- /1 - Maze/assets/photos/datapath5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shahriar-0/Computer-Architecture-Course-Projects-S2023/869ef7aa726a823138fb17e00bcaafadb635655b/1 - Maze/assets/photos/datapath5.png -------------------------------------------------------------------------------- /1 - Maze/assets/problem description/CA#01.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shahriar-0/Computer-Architecture-Course-Projects-S2023/869ef7aa726a823138fb17e00bcaafadb635655b/1 - Maze/assets/problem description/CA#01.pdf -------------------------------------------------------------------------------- /1 - Maze/assets/utils/generate/generate.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | lst = ["%04x" % random.randrange(16**4) for _ in range(16)] 4 | 5 | while lst[0][0] in ["8", "9", "a", "b", "c", "d", "e", "f"]: 6 | lst[0] = "%04x" % random.randrange(16**4) 7 | 8 | while lst[-1][-1] in ["1", "3", "5", "7", "9", "b", "d", "f"]: 9 | lst[-1] = "%04x" % random.randrange(16**4) 10 | 11 | with open("../../code/maze.dat", "wb") as result_file: 12 | for line in lst: 13 | result_file.write(f"{line}\n".encode("utf-8")) 14 | 15 | 16 | ls = [["0" for _ in range(16)] for i in range(16)] 17 | with open("../../code/maze.dat") as input_file: 18 | done = 0 19 | for line in input_file: 20 | x = bin(int(line.rstrip(), 16))[2:] 21 | ls[done][-len(x) :] = x 22 | done += 1 23 | 24 | with open("map.txt", "wb") as map: 25 | for line in ls: 26 | map.write(f"{''.join(line)}\n".encode("utf-8")) 27 | -------------------------------------------------------------------------------- /1 - Maze/assets/utils/generate/generate_valid.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | 3 | tries = 0 4 | while True: 5 | subprocess.run(["python", ".\generate.py"]) 6 | subprocess.run(["python", ".\intelligent_rat.py"]) 7 | 8 | with open("result.txt") as file: 9 | line = file.readline() 10 | if line != "No solution": 11 | break 12 | tries += 1 13 | 14 | print(f"tries: {tries}!") 15 | -------------------------------------------------------------------------------- /1 - Maze/assets/utils/judge/check_path.py: -------------------------------------------------------------------------------- 1 | from time import sleep 2 | import os 3 | 4 | 5 | class color: 6 | GREEN = "\033[92m" 7 | RED = "\033[91m" 8 | BASE = "\033[0m" 9 | 10 | 11 | dick = {"up": [0, -1], "right": [1, 0], "left": [-1, 0], "down": [0, 1]} 12 | 13 | sth = [] 14 | num = int(input("number of test: ")) 15 | 16 | maze = [] 17 | with open(f"../maps/maps with solution/map_{num}.txt") as file: 18 | for line in file: 19 | line = line.rstrip() 20 | maze.append(list(line)) 21 | 22 | 23 | def print_maze(maze): 24 | os.system("cls") 25 | for row in maze: 26 | print( 27 | (" ".join(row)) 28 | .replace("x", color.GREEN + "◎" + color.BASE) 29 | .replace("M", color.RED + "●" + color.BASE) 30 | ) 31 | 32 | 33 | x, y = 0, 0 34 | maze[0][0] = "x" 35 | with open(f"../maps/maps with solution/result_{num}.txt") as file: 36 | for line in file: 37 | print_maze(maze) 38 | maze[y][x] = "M" 39 | line = line.rstrip() 40 | x += dick[line][0] 41 | y += dick[line][1] 42 | maze[y][x] = "x" 43 | sleep(1 / 3) 44 | 45 | print_maze(maze) 46 | -------------------------------------------------------------------------------- /1 - Maze/assets/utils/judge/convert.py: -------------------------------------------------------------------------------- 1 | dick = { 2 | "00": "up", 3 | "01": "right", 4 | "10": "left", 5 | "11": "down" 6 | } 7 | 8 | sth = [] 9 | with_solution, num = map( 10 | int, input("1 for with solution otherwise 0, number of test: ").split() 11 | ) 12 | directory_name = "maps with solution" if with_solution else "maps without solution" 13 | 14 | 15 | with open(f"../maps/{directory_name}/code_result_{num}.txt") as file: 16 | for line in file: 17 | line = line.rstrip() 18 | if not line in dick: 19 | continue 20 | x = dick[line] 21 | sth.append(x) 22 | 23 | with open("verilog_result_converted.txt", "wb") as file2: 24 | for x in sth: 25 | file2.write(f"{x}\n".encode("utf-8")) 26 | -------------------------------------------------------------------------------- /1 - Maze/assets/utils/judge/intelligent_rat.py: -------------------------------------------------------------------------------- 1 | # let's dance :) 2 | import sys 3 | 4 | sys.setrecursionlimit(20000) 5 | 6 | moves = [(-1, 0), (0, 1), (0, -1), (1, 0)] 7 | dick = {(-1, 0): "up", (0, 1): "right", (0, -1): "left", (1, 0): "down"} 8 | 9 | ls: list[list[str]] = [] 10 | with open("map.txt") as map: 11 | for line in map: 12 | ls.append(list(line.rstrip())) 13 | 14 | result = [] 15 | 16 | 17 | def backtrack(x=0, y=0) -> bool: 18 | if x < 0 or x > 15 or y < 0 or y > 15 or ls[x][y] == "1": 19 | return False 20 | 21 | if x == 15 and y == 15: 22 | return True 23 | 24 | for move in moves: 25 | ls[x][y] = "1" 26 | x += move[0] 27 | y += move[1] 28 | result.append(dick[move]) 29 | if backtrack(x, y): 30 | return True 31 | 32 | x -= move[0] 33 | y -= move[1] 34 | ls[x][y] = "0" 35 | result.pop() 36 | 37 | return False 38 | 39 | 40 | with open("result.txt", "wb") as result_file: 41 | if not backtrack(): 42 | print("not found!") 43 | result_file.write("No solution".encode("utf-8")) 44 | else: 45 | print("found!") 46 | for i in result: 47 | result_file.write(f"{i}\n".encode("utf-8")) 48 | -------------------------------------------------------------------------------- /1 - Maze/code/controller.v: -------------------------------------------------------------------------------- 1 | `define idle 5'b00000 2 | `define init 5'b00001 3 | `define init_search 5'b00010 4 | `define add_to_stack 5'b00011 5 | `define update_xy 5'b00100 6 | `define make_wall 5'b00101 7 | `define check_goal 5'b00110 8 | `define check_wall 5'b00111 9 | `define check_empty_stack 5'b01000 10 | `define pop_stack 5'b01001 11 | `define reload_counter 5'b01010 12 | `define update_reverse 5'b01011 13 | `define free_loc_check_bt 5'b01100 14 | `define change_dir 5'b01101 15 | `define fail 5'b01110 16 | `define stack_read 5'b01111 17 | `define update_list 5'b10000 18 | `define done 5'b10001 19 | `define show 5'b10010 20 | 21 | 22 | module Controller(clk, rst, start, Run, Co, invalid, 23 | found, empty_stack, Done, en_read, 24 | complete_read, D_out, r_update, 25 | init_x, init_y, init_count, Fail, 26 | en_count, ldc, ldx, ldy, 27 | WR, RD, D_in,init_stack, stack_pop, 28 | stack_push, list_push, init_list); 29 | 30 | input clk, rst, start, Run, Co, found, 31 | empty_stack, complete_read, D_out, invalid; 32 | 33 | output reg init_x, init_y, init_count, en_count, 34 | ldc, ldx, ldy, WR, RD, D_in, Done, 35 | list_push, en_read, init_list, Fail, 36 | init_stack,stack_push, stack_pop, 37 | r_update; 38 | 39 | reg [4:0] pstate = `idle; 40 | reg [4:0] nstate = `idle; 41 | 42 | always @(Run or start or Co or pstate or D_out or complete_read or empty_stack or found or invalid) begin 43 | case (pstate) 44 | `idle : nstate <= ~start? `idle : `init; 45 | `init : nstate <= ~start? `init_search : `init; 46 | `init_search : nstate <= `make_wall; 47 | `make_wall : nstate <= ~invalid? `add_to_stack : `free_loc_check_bt; 48 | `add_to_stack : nstate <= `update_xy; 49 | `update_xy : nstate <= `check_goal; 50 | `check_goal : nstate <= found ? `stack_read : `check_wall; 51 | `check_wall : nstate <= D_out ? `check_empty_stack : `init_search; 52 | `check_empty_stack: nstate <= empty_stack ? `fail : `pop_stack; 53 | `pop_stack : nstate <= `reload_counter; 54 | `reload_counter : nstate <= `update_reverse; 55 | `update_reverse : nstate <= `free_loc_check_bt; 56 | `free_loc_check_bt: nstate <= Co ? `check_empty_stack : `change_dir; 57 | `change_dir : nstate <= `make_wall; 58 | `fail : nstate <= `fail; 59 | `stack_read : nstate <= `update_list; 60 | `update_list : nstate <= ~empty_stack ? `stack_read : `done; 61 | `done : nstate <= Run ? `show : `done; 62 | `show : nstate <= complete_read ? `done : `show; 63 | endcase 64 | end 65 | 66 | always @(pstate) begin 67 | {init_x, init_y, init_count,init_stack, en_count, ldc, ldx, ldy, 68 | WR, RD, D_in, stack_pop, list_push, en_read, init_list, 69 | r_update , stack_push, Done, Fail} = 19'b0; 70 | case (pstate) 71 | `init : begin init_x = 1'b1; init_y = 1'b1; 72 | init_list = 1'b1; init_stack = 1'b1; 73 | init_count= 1'b1; end 74 | `init_search : begin init_count = 1'b1; end 75 | `make_wall : begin WR = 1'b1; D_in = 1'b1; end 76 | `add_to_stack : begin stack_push = 1'b1; end 77 | `update_xy : begin ldx = 1'b1; ldy = 1'b1; end 78 | `check_goal : begin RD = 1'b1 ; end 79 | `pop_stack : begin stack_pop = 1'b1; end 80 | `reload_counter : begin ldc = 1'b1; end 81 | `update_reverse : begin ldx = 1'b1; ldy = 1'b1; r_update = 1'b1; end 82 | `free_loc_check_bt: begin WR = 1'b1; end 83 | `change_dir : begin en_count = 1'b1; end 84 | `fail : begin Fail = 1'b1; end 85 | `stack_read : begin stack_pop = 1'b1; end 86 | `update_list : begin list_push = 1'b1; end 87 | `done : begin Done = 1'b1; end 88 | `show : begin en_read = 1'b1; Done = 1'b1; end 89 | endcase 90 | end 91 | 92 | always @(posedge clk or posedge rst) begin 93 | if (rst) 94 | pstate <= `idle; 95 | else 96 | pstate <= nstate; 97 | end 98 | 99 | endmodule -------------------------------------------------------------------------------- /1 - Maze/code/counter2bit.v: -------------------------------------------------------------------------------- 1 | module Counter2bit(rst, clk, init, ld, en, prl, out, Co); 2 | 3 | input init, ld, en, rst, clk; 4 | input [1:0] prl; 5 | output reg [1:0] out; 6 | output Co; 7 | 8 | always @(posedge clk or posedge rst) begin 9 | if (rst || init) 10 | out <= 2'b0; 11 | else if (ld) 12 | out <= prl; 13 | else if (en) 14 | out <= out + 1; 15 | end 16 | 17 | assign Co = &out; 18 | 19 | endmodule -------------------------------------------------------------------------------- /1 - Maze/code/datapth.v: -------------------------------------------------------------------------------- 1 | 2 | module Datapath(clk, rst, init_x, init_y, ldx, ldy, ld_count, Co, 3 | init_count, en_count, list_push, en_read, init_list, 4 | init_stack, stack_dir_push, stack_dir_pop, r_update, 5 | X, Y, Move, found, empty_stack, complete_read, invalid); 6 | 7 | parameter DIRECTION_SIZE = 2; 8 | parameter N = 4; 9 | 10 | input clk, rst, init_x, init_y, ldx, ldy, ld_count, 11 | init_count, en_count, list_push, en_read, init_list, 12 | init_stack, stack_dir_push, stack_dir_pop, r_update; 13 | 14 | output [N - 1:0] X, Y, add_res; 15 | output [DIRECTION_SIZE - 1:0] Move, stackp; 16 | output found, empty_stack, complete_read, Co, invalid; 17 | 18 | wire [N - 1:0] mux1, mux2, mux3; 19 | wire [DIRECTION_SIZE-1:0] counter; 20 | wire slc_mux, dec_en, fa_co; 21 | 22 | assign dec_en = r_update ^ (~counter[0]); 23 | assign slc_mux = ^counter; 24 | 25 | Mux2in mux_1(.a(X), .b(add_res), .slc(slc_mux), .w(mux1)); 26 | Mux2in mux_2(.a(add_res), .b(Y), .slc(slc_mux), .w(mux2)); 27 | Mux2in mux_3(.a(Y), .b(X), .slc(slc_mux), .w(mux3)); 28 | 29 | IncrementerDecrementer inc_dec_instance(.a(mux3), .dec_en(dec_en), .w(add_res), .invalid(invalid)); 30 | 31 | Register regx(.prl(mux1), .clk(clk), .rst(rst), .ld(ldx), .init(init_x), .W(X)); 32 | Register regy(.prl(mux2), .clk(clk), .rst(rst), .ld(ldy), .init(init_y), .W(Y)); 33 | 34 | Counter2bit counter2b( 35 | .init(init_count), .ld(ld_count), .en(en_count), .rst(rst), 36 | .clk(clk), .prl(stackp), .out(counter), .Co(Co) 37 | ); 38 | 39 | Stack direction_stack( 40 | .clk(clk), .rst(rst), .pop(stack_dir_pop), .push(stack_dir_push), 41 | .init(init_stack), .empty(empty_stack), .d_in(counter), .d_out(stackp) 42 | ); 43 | 44 | List result_list( 45 | .clk(clk), .rst(rst), .push(list_push), .init(init_list), .en_read(en_read), 46 | .data_in(stackp), .complete_read(complete_read), .data_out(Move) 47 | ); 48 | 49 | assign found = &{X, Y}; 50 | 51 | endmodule -------------------------------------------------------------------------------- /1 - Maze/code/incrementer_decrementer.v: -------------------------------------------------------------------------------- 1 | module IncrementerDecrementer(a, dec_en, w, invalid); 2 | parameter N = 4; 3 | input [N - 1:0] a; 4 | input dec_en; 5 | output reg [N - 1:0] w; 6 | 7 | output reg invalid; 8 | always @(a, dec_en) begin 9 | if(((~|a) && dec_en == 1'b1) || ((&a) && dec_en == 1'b0)) 10 | invalid <= 1'b1; 11 | else 12 | invalid <= 1'b0; 13 | 14 | w <= (dec_en) ? a - 1 : a + 1; 15 | end 16 | 17 | endmodule -------------------------------------------------------------------------------- /1 - Maze/code/intelligent_rat.v: -------------------------------------------------------------------------------- 1 | 2 | module IntelligentRat(clk, rst, Run, Start, 3 | Fail, Done, Move, X, Y, 4 | D_in, D_out, RD, WR); 5 | 6 | parameter DIRECTION_SIZE = 2; 7 | parameter N = 4; 8 | 9 | input clk, rst, Run, Start, D_out; 10 | 11 | output D_in, Fail, Done, RD, WR; 12 | output [DIRECTION_SIZE - 1:0] Move; 13 | output [N - 1:0] X, Y; 14 | 15 | wire init_x, init_y, ldx, ldy, 16 | init_count,ld_count, en_count, list_push, 17 | en_read, init_list, init_stack, 18 | stack_dir_push, stack_dir_pop, 19 | r_update, found, empty_stack, 20 | complete_read, Co, invalid; 21 | 22 | Datapath dp( 23 | .clk(clk), .rst(rst), .init_x(init_x), .init_y(init_y), .ldx(ldx), .ldy(ldy), 24 | .ld_count(ld_count), .init_count(init_count), .en_count(en_count), 25 | .en_read(en_read), .init_list(init_list), .init_stack(init_stack), .X(X), 26 | .stack_dir_push(stack_dir_push), .stack_dir_pop(stack_dir_pop), .Y(Y), 27 | .Move(Move), .found(found), .empty_stack(empty_stack), .r_update(r_update), 28 | .complete_read(complete_read), .list_push(list_push), .Co(Co), .invalid(invalid) 29 | ); 30 | 31 | Controller cu( 32 | .clk(clk), .rst(rst), .start(Start), .Run(Run), .Co(Co), .found(found), .WR(WR), 33 | .complete_read(complete_read), .D_out(D_out), .init_x(init_x), .init_y(init_y), 34 | .D_in(D_in), .init_stack(init_stack), .init_count(init_count), .en_count(en_count), 35 | .stack_pop(stack_dir_pop), .stack_push(stack_dir_push), .r_update(r_update), 36 | .en_read(en_read), .init_list(init_list), .Done(Done), .Fail(Fail), .empty_stack(empty_stack), 37 | .ldc(ld_count), .ldx(ldx), .list_push(list_push), .ldy(ldy), .RD(RD), .invalid(invalid) 38 | ); 39 | 40 | endmodule -------------------------------------------------------------------------------- /1 - Maze/code/list.v: -------------------------------------------------------------------------------- 1 | `define BITS(x) $rtoi($ceil($clog2(x))) 2 | 3 | 4 | module List (clk, rst, push, init, en_read, data_in, complete_read, data_out); 5 | 6 | parameter MAX_LENGTH = 256; 7 | parameter WIDTH = 2; 8 | 9 | input clk, rst, push, init, en_read; 10 | input [WIDTH - 1:0] data_in; 11 | output complete_read; 12 | output reg [WIDTH - 1:0] data_out; 13 | reg complete_read; 14 | 15 | reg [WIDTH - 1:0] list [0: MAX_LENGTH - 1]; 16 | reg [`BITS(MAX_LENGTH) - 1:0] ptr, last_ptr, length; 17 | reg read_ing; 18 | integer result_file; 19 | 20 | always @(posedge clk or posedge rst) begin 21 | if (rst || init) begin 22 | ptr <= 1'b0; 23 | last_ptr <= 1'b0; 24 | length <= 1'b0; 25 | read_ing <= 1'b0; 26 | complete_read <= 1'b0; 27 | end 28 | 29 | else if (push && (length < MAX_LENGTH)) begin 30 | list[length] <= data_in; 31 | length <= length + 1; 32 | end 33 | 34 | else if (en_read && !read_ing && (length > 0)) begin 35 | ptr <= length - 1; 36 | last_ptr <= length - 1; 37 | read_ing <= 1'b1; 38 | complete_read <= 1'b0; 39 | result_file = $fopen("result.txt", "wb"); 40 | end 41 | 42 | else if (read_ing) begin 43 | if (ptr >= 0) begin 44 | data_out <= list[ptr]; 45 | ptr <= ptr - 1; 46 | $fdisplayb(result_file, data_out); 47 | end 48 | else begin 49 | ptr <= last_ptr; 50 | read_ing <= 1'b0; 51 | complete_read <= 1'b1; 52 | $fclose(result_file); 53 | end 54 | end 55 | end 56 | 57 | endmodule 58 | -------------------------------------------------------------------------------- /1 - Maze/code/maze_memory.v: -------------------------------------------------------------------------------- 1 | module MazeMemory(clk, X, Y, D_in, RD, WR, D_out); 2 | parameter N = 4; 3 | parameter FILENAME = "maze.dat"; 4 | localparam WIDTH = 16; 5 | localparam HEIGHT = 16; 6 | 7 | input [N - 1:0] X, Y; 8 | input D_in, RD, WR, clk; 9 | output reg D_out; 10 | 11 | reg [0:WIDTH - 1] maze [0:HEIGHT - 1]; 12 | 13 | initial begin 14 | $readmemh(FILENAME, maze); 15 | end 16 | 17 | always @(posedge clk, posedge RD) begin 18 | if(WR) 19 | maze[Y][X] = D_in; 20 | else if (RD) 21 | D_out = maze[Y][X]; 22 | end 23 | endmodule -------------------------------------------------------------------------------- /1 - Maze/code/mux2in.v: -------------------------------------------------------------------------------- 1 | module Mux2in(a, b, slc, w); 2 | parameter N = 4; 3 | input [N - 1:0] a, b; 4 | input slc; 5 | output [N - 1:0] w; 6 | 7 | assign w = ~slc ? a : b; 8 | endmodule -------------------------------------------------------------------------------- /1 - Maze/code/register.v: -------------------------------------------------------------------------------- 1 | module Register(prl, clk, rst, ld, init, W); 2 | parameter N = 4; 3 | 4 | input [N - 1:0] prl; 5 | input clk, rst, ld, init; 6 | output reg [N - 1:0] W; 7 | 8 | always @(posedge clk or posedge rst) begin 9 | if (rst || init) 10 | W <= {N{1'b0}}; 11 | 12 | else if (ld) 13 | W <= prl; 14 | end 15 | endmodule 16 | -------------------------------------------------------------------------------- /1 - Maze/code/stack.v: -------------------------------------------------------------------------------- 1 | `define BITS(x) $rtoi($ceil($clog2(x))) 2 | 3 | module Stack(clk, rst, init, pop, push, empty, d_in, d_out); 4 | 5 | parameter WIDTH = 2; 6 | parameter DEPTH = 256; 7 | 8 | input clk, rst, pop, push, init; 9 | input [WIDTH - 1:0] d_in; 10 | 11 | output [WIDTH - 1:0] d_out; 12 | output empty; 13 | 14 | reg [WIDTH - 1:0] stack [DEPTH - 1:0]; 15 | reg [`BITS(DEPTH) - 1:0] index, next_index; 16 | reg [WIDTH - 1:0] d_out, next_d_out; 17 | 18 | wire empty; 19 | assign empty = !(|index); 20 | 21 | 22 | always @(posedge clk or posedge rst) begin 23 | 24 | if(rst || init) begin 25 | next_d_out = 8'd0; 26 | next_index = 1'b0; 27 | end 28 | 29 | else if(push) begin 30 | stack[index] = d_in; 31 | next_index = index + 1'b1; 32 | end 33 | 34 | else if(pop) begin 35 | next_d_out = stack[index - 1'b1]; 36 | next_index = index - 1'b1; 37 | end 38 | 39 | else begin 40 | next_d_out = d_out; 41 | next_index = index; 42 | end 43 | 44 | d_out = next_d_out; 45 | index = next_index; 46 | end 47 | 48 | endmodule -------------------------------------------------------------------------------- /1 - Maze/code/tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ns 2 | 3 | module tb(); 4 | reg Start, Run, clk, rst; 5 | wire Fail, Done,D_in, D_out, RD, WR; 6 | wire [3:0] X,Y; 7 | wire [1:0] Move; 8 | 9 | IntelligentRat rat( 10 | .clk(clk), .rst(rst), .Run(Run), .Start(Start), 11 | .Fail(Fail), .Done(Done), .Move(Move), .X(X), .Y(Y), 12 | .D_in(D_in), .D_out(D_out), .RD(RD), .WR(WR) 13 | ); 14 | 15 | MazeMemory maze( 16 | .clk(clk), .X(X), .Y(Y), .D_in(D_in), 17 | .RD(RD), .WR(WR), .D_out(D_out) 18 | ); 19 | 20 | always #5 clk = ~clk; 21 | 22 | initial begin 23 | {Start, Run, clk, rst} = 4'b0; 24 | #30 Start = 1'b1; 25 | #30 Start = 1'b0; 26 | #40000 Run = 1'b1; 27 | #10 Run = 1'b0; 28 | #3000 29 | #200 rst = 1'b1; 30 | #200 rst = 1'b0; 31 | #10 $stop; 32 | end 33 | 34 | endmodule -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/assets/assembly/maxarray.s: -------------------------------------------------------------------------------- 1 | .global _boot 2 | 3 | .text 4 | _boot: 5 | jal x0, FindMax 6 | 7 | FindMax: 8 | lw x8, 1000(x0) # maxElement = mem[1000] 9 | add x9, x0, x0 # i 10 | 11 | Loop: 12 | addi x9, x9, 4 # i += 4 13 | slti x6, x9, 40 # check if 10 elements are traversed (40 = 4 * 10) 14 | beq x6, x0, EndLoop # if 10 elements are traversed, jump to EndLoop 15 | lw x18, 1000(x9) # element = mem[i] 16 | slt x6, x8, x18 # check if element is greater than maxElement 17 | beq x6, x0, Loop # if element is not greater than maxElement, jump to Loop 18 | add x8, x18, x0 # maxElement = element 19 | jal x0,Loop # jump to Loop 20 | 21 | EndLoop: 22 | sw x8, 2000(x0) # mem[2000] = maxElement 23 | jal x0,End # return 24 | 25 | End: 26 | 27 | -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/assets/assembly/maxarraySemiAsm.s: -------------------------------------------------------------------------------- 1 | .global _boot 2 | 3 | .text 4 | _boot: 5 | jal FindMax 6 | 7 | FindMax: 8 | lw s0, 1000(zero) # maxElement = mem[1000] 9 | add s1, zero, zero # i 10 | 11 | Loop: 12 | addi s1, s1, 4 # i += 4 13 | slti t1, s1, 40 # check if 10 elements are traversed (40 = 4 * 10) 14 | beq t1, zero, EndLoop # if 10 elements are traversed, jump to EndLoop 15 | lw s2, 1000(s1) # element = mem[i] 16 | slt t1, s0, s2 # check if element is greater than maxElement 17 | beq t1, zero, Loop # if element is not greater than maxElement, jump to Loop 18 | add s0, s2, zero # maxElement = element 19 | jal Loop # jump to Loop 20 | 21 | EndLoop: 22 | sw s0, 2000(zero) # mem[2000] = maxElement 23 | jal End # return 24 | 25 | End: 26 | 27 | -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/assets/controller/Single-Cycle Controller.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shahriar-0/Computer-Architecture-Course-Projects-S2023/869ef7aa726a823138fb17e00bcaafadb635655b/2 - RISC-V Single-Cycle/assets/controller/Single-Cycle Controller.jpg -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/assets/datapath/Single-Cycle Datapath.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shahriar-0/Computer-Architecture-Course-Projects-S2023/869ef7aa726a823138fb17e00bcaafadb635655b/2 - RISC-V Single-Cycle/assets/datapath/Single-Cycle Datapath.png -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/assets/memory/ArrayData.txt: -------------------------------------------------------------------------------- 1 | -34 2 | -10 3 | 37 4 | 46 5 | 98 6 | 2 7 | 131 8 | -982 9 | 143 10 | 8 11 | 56 12 | 36 13 | -28 14 | 98 15 | 17 16 | -7 17 | 0 18 | 2 19 | 5 20 | 91 -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/assets/memory/data.mem: -------------------------------------------------------------------------------- 1 | @3e8 2 | 11011110 3 | 11111111 4 | 11111111 5 | 11111111 6 | @3ec 7 | 11110110 8 | 11111111 9 | 11111111 10 | 11111111 11 | @3f0 12 | 00100101 13 | 00000000 14 | 00000000 15 | 00000000 16 | @3f4 17 | 00101110 18 | 00000000 19 | 00000000 20 | 00000000 21 | @3f8 22 | 01100010 23 | 00000000 24 | 00000000 25 | 00000000 26 | @3fc 27 | 00000010 28 | 00000000 29 | 00000000 30 | 00000000 31 | @400 32 | 10000011 33 | 00000000 34 | 00000000 35 | 00000000 36 | @404 37 | 00101010 38 | 11111100 39 | 11111111 40 | 11111111 41 | @408 42 | 10001111 43 | 00000000 44 | 00000000 45 | 00000000 46 | @40c 47 | 00001000 48 | 00000000 49 | 00000000 50 | 00000000 51 | @410 52 | 00111000 53 | 00000000 54 | 00000000 55 | 00000000 56 | @414 57 | 00100100 58 | 00000000 59 | 00000000 60 | 00000000 61 | @418 62 | 11100100 63 | 11111111 64 | 11111111 65 | 11111111 66 | @41c 67 | 01100010 68 | 00000000 69 | 00000000 70 | 00000000 71 | @420 72 | 00010001 73 | 00000000 74 | 00000000 75 | 00000000 76 | @424 77 | 11111001 78 | 11111111 79 | 11111111 80 | 11111111 81 | @428 82 | 00000000 83 | 00000000 84 | 00000000 85 | 00000000 86 | @42c 87 | 00000010 88 | 00000000 89 | 00000000 90 | 00000000 91 | @430 92 | 00000101 93 | 00000000 94 | 00000000 95 | 00000000 96 | @434 97 | 01011011 98 | 00000000 99 | 00000000 100 | 00000000 101 | -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/assets/memory/instructions.mem: -------------------------------------------------------------------------------- 1 | 00000000 2 | 01000000 3 | 00000000 4 | 01101111 5 | 00111110 6 | 10000000 7 | 00100100 8 | 00000011 9 | 00000000 10 | 00000000 11 | 00000100 12 | 10110011 13 | 00000000 14 | 01000100 15 | 10000100 16 | 10010011 17 | 00000010 18 | 10000100 19 | 10100011 20 | 00010011 21 | 00000000 22 | 00000011 23 | 00001100 24 | 01100011 25 | 00111110 26 | 10000100 27 | 10101001 28 | 00000011 29 | 00000001 30 | 00100100 31 | 00100011 32 | 00110011 33 | 11111110 34 | 00000011 35 | 00000110 36 | 11100011 37 | 00000000 38 | 00001001 39 | 00000100 40 | 00110011 41 | 11111110 42 | 01011111 43 | 11110000 44 | 01101111 45 | 01111100 46 | 10000000 47 | 00101000 48 | 00100011 49 | 00000000 50 | 01000000 51 | 00000000 52 | 01101111 53 | -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/assets/problem description/CA#02.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shahriar-0/Computer-Architecture-Course-Projects-S2023/869ef7aa726a823138fb17e00bcaafadb635655b/2 - RISC-V Single-Cycle/assets/problem description/CA#02.pdf -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/assets/utils/assembler/customized assembler/assembler.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | del instructions.mem 2>nul 4 | del FindMax.asm 2>nul 5 | del ..\..\..\memory\instructions.mem 2>nul 6 | 7 | py main.py ..\..\..\assembly\maxarray.s 8 | copy instructions.mem ..\..\..\memory 9 | pause 10 | -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/assets/utils/assembler/customized assembler/assembler.py: -------------------------------------------------------------------------------- 1 | import os 2 | import io 3 | import type 4 | from tqdm import tqdm 5 | 6 | class Assembler: 7 | types = { 8 | **{k: type.R_Type() for k in type.R_Type.map.keys()}, 9 | **{k: type.I_Type() for k in type.I_Type.map.keys()}, 10 | **{k: type.S_Type() for k in type.S_Type.map.keys()}, 11 | **{k: type.J_Type() for k in type.J_Type.map.keys()}, 12 | **{k: type.B_Type() for k in type.B_Type.map.keys()}, 13 | **{k: type.U_Type() for k in type.U_Type.map.keys()}, 14 | } 15 | 16 | labeled = ["beq", "bne", "blt", "bge", "jal"] 17 | 18 | def __init__( 19 | self, 20 | filename_destination: str = "instructions.mem", 21 | directory: str = None, 22 | filename_source: str = None, 23 | ) -> None: 24 | self.directory = directory or os.getcwd() 25 | self.filename_destination = filename_destination 26 | if filename_source is None: 27 | self.filename_source = self.__find_first_assembly_file() 28 | else: 29 | self.filename_source = filename_source 30 | 31 | def __find_first_assembly_file(self): 32 | for root, dirs, files in os.walk(self.directory): 33 | for file in files: 34 | if file.endswith(".asm") or file.endswith(".s"): 35 | return os.path.join(root, file) 36 | return None 37 | 38 | def __find_assembly_lines(self) -> list[str]: 39 | if self.filename_source is None: 40 | print(f"No assembly file found in directory '{self.directory}'") 41 | exit(1) 42 | 43 | with open(self.filename_source, "r") as f: # type: io.TextIOWrapper 44 | lines = f.readlines() 45 | 46 | assembly_lines = [] 47 | for i, line in enumerate(lines): 48 | if line.lstrip() == "\n": 49 | continue 50 | try: 51 | command, *args = line.split() 52 | if command in self.types or ":" in line: 53 | assembly_lines.append(line.split("#", 1)[0]) 54 | except Exception as e: 55 | pass 56 | 57 | return assembly_lines 58 | 59 | def __find_line_of_label( 60 | self, lines: list[str], label: str, calling_line: int 61 | ) -> int: 62 | minus = 0 63 | for i, line in enumerate(lines): 64 | if label + ":" in line: 65 | return i - minus - calling_line 66 | if ":" in line: 67 | minus += 1 68 | 69 | return None 70 | 71 | def assemble(self): 72 | assembly_lines = self.__find_assembly_lines() 73 | machine_code_lines = [] 74 | 75 | for assembly_line in tqdm(assembly_lines, desc="Assembling lines"): 76 | try: 77 | command, *args = assembly_line.split() 78 | if command in self.types: 79 | if command in self.labeled: 80 | label = assembly_line.rstrip().rsplit(" ", 1)[1].rstrip() 81 | label_line = self.__find_line_of_label( 82 | assembly_lines, label, len(machine_code_lines) 83 | ) 84 | if label_line is None: 85 | raise Exception("label doesn't exist") 86 | assembly_line = assembly_line.replace( 87 | label, str(label_line << 2) 88 | ) 89 | machine_code_line = self.types[command](assembly_line) 90 | machine_code_lines.append(machine_code_line) 91 | except Exception as e: 92 | pass 93 | 94 | with open(self.filename_destination, "w") as f: # type: io.TextIOWrapper 95 | waiting_chars = ['|', '/', '-', '\\'] 96 | for i, line in enumerate(machine_code_lines): 97 | bytes = [line[i : i + 8] for i in range(0, len(line), 8)] 98 | for byte in bytes: 99 | f.write(byte + "\n") 100 | if i % 10 == 0: 101 | tqdm.write(f"\rWriting to file {waiting_chars[i % len(waiting_chars)]}", end='') 102 | tqdm.write("\nDone writing to file.") 103 | -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/assets/utils/assembler/customized assembler/convertToBase2.py: -------------------------------------------------------------------------------- 1 | def twos_complement(decimal_number: int, n: int) -> str: 2 | if decimal_number >= 0: 3 | binary_number = bin(decimal_number)[2:] 4 | return binary_number.zfill(n) 5 | else: 6 | binary_number = bin(2**n + decimal_number)[2:] 7 | return binary_number 8 | -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/assets/utils/assembler/customized assembler/main.py: -------------------------------------------------------------------------------- 1 | from assembler import Assembler 2 | from sys import argv 3 | 4 | 5 | def main(): 6 | if len(argv) == 3: 7 | assembler = Assembler(filename_destination=argv[2], filename_source=argv[1]) 8 | elif len(argv) == 2: 9 | assembler = Assembler(filename_source=argv[1]) 10 | else: 11 | print(f"Usage: ") 12 | print("or") 13 | print(f"Usage: and it will be stored in 'instructions.mem'") 14 | print( 15 | "now the program will use the first assembly file in this directory that ends with '.asm' or '.s'" 16 | ) 17 | assembler = Assembler() 18 | 19 | assembler.assemble() 20 | 21 | 22 | if __name__ == "__main__": 23 | main() 24 | -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/assets/utils/assembler/customized assembler/toRealAssmebly.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | input_file = sys.argv[1] 4 | output_file = sys.argv[2] 5 | 6 | registers = [ 7 | "zero", 8 | "ra", 9 | "sp", 10 | "gp", 11 | "tp", 12 | "t0", 13 | "t1", 14 | "t2", 15 | "s0", 16 | "s1", 17 | "a0", 18 | "a1", 19 | "a2", 20 | "a3", 21 | "a4", 22 | "a5", 23 | "a6", 24 | "a7", 25 | "s2", 26 | "s3", 27 | "s4", 28 | "s5", 29 | "s6", 30 | "s7", 31 | "s8", 32 | "s9", 33 | "s10", 34 | "s11", 35 | "t3", 36 | "t4", 37 | "t5", 38 | "t6", 39 | ] 40 | 41 | with open(input_file, "r") as f_in, open(output_file, "w") as f_out: 42 | for line in f_in: 43 | parts = line.split("#", 1) 44 | for reg in registers: 45 | parts[0] = parts[0].replace(reg, "x" + str(registers.index(reg))) 46 | f_out.write("#".join(parts)) 47 | -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/assets/utils/assembler/customized assembler/type.py: -------------------------------------------------------------------------------- 1 | from convertToBase2 import twos_complement 2 | from typing import Any 3 | from copy import deepcopy 4 | import re 5 | 6 | class Type: 7 | def __init__(self) -> None: 8 | pass 9 | 10 | def __call__(self, input: str, *args: Any, **kwds: Any) -> Any: 11 | self.__prepare_str(input) 12 | return self._assemble() 13 | 14 | def _assemble(self) -> str: 15 | print("here") 16 | pass 17 | 18 | def __prepare_str(self, input: str) -> str: 19 | no_comma_text = deepcopy(input).replace(",", "") 20 | no_extra_space = ( 21 | re.sub(r"\s+", " ", no_comma_text).split("#")[0].rstrip().lstrip() 22 | ) 23 | self.input = no_extra_space.replace("(", " ").replace(")", "") 24 | self.parsed = self.__parse() 25 | 26 | def __parse(self) -> list[str]: 27 | self.command, *self.args = self.input.split(" ") 28 | 29 | 30 | class R_Type(Type): 31 | map = { 32 | "add": ("0110011", "000", "0000000"), 33 | "sub": ("0110011", "000", "0100000"), 34 | "and": ("0110011", "111", "0000000"), 35 | "or": ("0110011", "110", "0000000"), 36 | "slt": ("0110011", "010", "0000000"), 37 | } 38 | 39 | def __init__(self) -> None: 40 | pass 41 | 42 | def _assemble(self) -> str: 43 | opcode, func3, func7 = self.map[self.command] 44 | rd = str(bin(int(self.args[0][1:]))[2:].zfill(5)) 45 | rs1 = str(bin(int(self.args[1][1:]))[2:].zfill(5)) 46 | rs2 = str(bin(int(self.args[2][1:]))[2:].zfill(5)) 47 | return func7 + rs2 + rs1 + func3 + rd + opcode 48 | 49 | 50 | class I_Type(Type): 51 | map = { 52 | "lw": ("0000011", "010"), 53 | "addi": ("0010011", "000"), 54 | "xori": ("0010011", "100"), 55 | "ori": ("0010011", "110"), 56 | "slti": ("0010011", "010"), 57 | "jalr": ("1100111", "000"), 58 | } 59 | 60 | def __init__(self) -> None: 61 | pass 62 | 63 | def _assemble(self) -> str: 64 | opcode, func3 = self.map[self.command] 65 | rd = str(bin(int(self.args[0][1:]))[2:].zfill(5)) 66 | if self.command == "lw": 67 | rs1 = str(bin(int(self.args[2][1:]))[2:].zfill(5)) 68 | imm = twos_complement(int(self.args[1]), 12) 69 | else: 70 | rs1 = str(bin(int(self.args[1][1:]))[2:].zfill(5)) 71 | imm = twos_complement(int(self.args[2]), 12) 72 | return imm + rs1 + func3 + rd + opcode 73 | 74 | 75 | class S_Type(Type): 76 | map = {"sw": ("0100011", "010")} 77 | 78 | def __init__(self) -> None: 79 | pass 80 | 81 | def _assemble(self) -> str: 82 | opcode, func3 = self.map[self.command] 83 | rs2 = str(bin(int(self.args[0][1:]))[2:].zfill(5)) 84 | rs1 = str(bin(int(self.args[2][1:]))[2:].zfill(5)) 85 | imm = twos_complement(int(self.args[1]), 12)[::-1] 86 | return imm[5:][::-1] + rs2 + rs1 + func3 + imm[:5][::-1] + opcode 87 | 88 | 89 | class J_Type(Type): 90 | map = {"jal": "1101111"} 91 | 92 | def __init__(self) -> None: 93 | pass 94 | 95 | def _assemble(self) -> str: 96 | opcode = self.map[self.command] 97 | rd = str(bin(int(self.args[0][1:]))[2:].zfill(5)) 98 | imm = twos_complement(int(self.args[1]), 21)[::-1] 99 | return imm[20] + imm[1:11][::-1] + imm[11] + imm[12:20][::-1] + rd + opcode 100 | 101 | 102 | class B_Type(Type): 103 | map = { 104 | "beq": ("1100011", "000"), 105 | "bne": ("1100011", "001"), 106 | "blt": ("1100011", "100"), 107 | "bge": ("1100011", "101"), 108 | } 109 | 110 | def __init__(self) -> None: 111 | pass 112 | 113 | def _assemble(self) -> str: 114 | opcode, func3 = self.map[self.command] 115 | rs1 = str(bin(int(self.args[0][1:]))[2:].zfill(5)) 116 | rs2 = str(bin(int(self.args[1][1:]))[2:].zfill(5)) 117 | imm = twos_complement(int(self.args[2]), 13)[::-1] 118 | return ( 119 | imm[12] 120 | + imm[5:11][::-1] 121 | + rs2 122 | + rs1 123 | + func3 124 | + imm[1:5][::-1] 125 | + imm[11] 126 | + opcode 127 | ) 128 | 129 | 130 | class U_Type(Type): 131 | map = {"lui": "0110111"} 132 | 133 | def __init__(self) -> None: 134 | pass 135 | 136 | def _assemble(self) -> str: 137 | opcode = self.map[self.command] 138 | rd = str(bin(int(self.args[0][1:]))[2:].zfill(5)) 139 | imm = twos_complement(int(self.args[1]), 21) 140 | return imm + rd + opcode -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/assets/utils/assembler/online/assembler_link.txt: -------------------------------------------------------------------------------- 1 | https://riscvasm.lucasteske.dev/# 2 | use this site to convert you assembly to hex file then use convert.py to have usable instructions.mem 3 | 4 | https://ascslab.org/research/briscv/simulator/simulator.html 5 | use this site to simulate RISC-V instructions -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/assets/utils/assembler/online/convert.py: -------------------------------------------------------------------------------- 1 | with open("../memory/instructions.hex", "r") as input_file: 2 | with open("../memory/instructions.mem", "w") as output_file: 3 | for line in input_file: 4 | hex_num = line.strip() 5 | num = int(hex_num, 16) 6 | 7 | msb = (num >> 24) & 0xFF 8 | next_8 = (num >> 16) & 0xFF 9 | next_8_2 = (num >> 8) & 0xFF 10 | lsb = num & 0xFF 11 | 12 | msb_bin = format(msb, "08b") 13 | next_8_bin = format(next_8, "08b") 14 | next_8_2_bin = format(next_8_2, "08b") 15 | lsb_bin = format(lsb, "08b") 16 | 17 | result = f"{msb_bin}\n{next_8_bin}\n{next_8_2_bin}\n{lsb_bin}\n" 18 | output_file.write(result) 19 | -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/assets/utils/data generator/data_generator.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | del data.mem 2>nul 4 | del FindMax.asm 2>nul 5 | del ..\..\memory\data.mem 2>nul 6 | 7 | py data_generator.py ..\..\memory\ArrayData.txt 8 | copy data.mem ..\..\memory 9 | pause 10 | -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/assets/utils/data generator/data_generator.py: -------------------------------------------------------------------------------- 1 | from sys import argv 2 | from io_ import read_from_file, write_to_file 3 | 4 | OUTPUT_FILE = "data.mem" 5 | START_ADDRESS = 1000 6 | 7 | 8 | def twos_complement(x: str): 9 | if x[0] != "-": 10 | return x 11 | index = x.rindex("1") 12 | x = list(x) 13 | x[0] = "0" 14 | for i in range(index): 15 | if x[i] == "1": 16 | x[i] = "0" 17 | else: 18 | x[i] = "1" 19 | x = "".join(x) 20 | return x 21 | 22 | 23 | def hex_address_generator(binary_numbers: tuple[str], start_address: int) -> str: 24 | res = "" 25 | for num in binary_numbers: 26 | res += f"@{start_address:03X}\n".lower() 27 | res += num[24:] + "\n" 28 | res += num[16:24] + "\n" 29 | res += num[8:16] + "\n" 30 | res += num[:8] + "\n" 31 | start_address += 4 32 | return res 33 | 34 | 35 | def main() -> None: 36 | if len(argv) == 2: 37 | numbers = read_from_file(argv[1]) 38 | else: 39 | print("Usage: python data_generator.py ") 40 | exit(1) 41 | 42 | nums = tuple((twos_complement(f"{int(num):032b}") for num in numbers)) 43 | res = hex_address_generator(tuple(nums), START_ADDRESS) 44 | write_to_file(res, OUTPUT_FILE) 45 | 46 | 47 | if __name__ == "__main__": 48 | main() 49 | -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/assets/utils/data generator/io_.py: -------------------------------------------------------------------------------- 1 | def read_from_file(filename: str) -> list[str]: 2 | with open(filename, "r", encoding="utf-8") as file: 3 | return file.read().splitlines() 4 | 5 | 6 | def write_to_file(data: str, filename: str) -> None: 7 | with open(filename, "w", encoding="utf-8") as file: 8 | file.write(data) 9 | -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/code/ALU.v: -------------------------------------------------------------------------------- 1 | `define ADD 3'b000 2 | `define SUB 3'b001 3 | `define AND 3'b010 4 | `define OR 3'b011 5 | `define SLT 3'b101 6 | `define XOR 3'b100 7 | 8 | module ALU(ALUControl, a, b, zero, neg, w); 9 | parameter N = 32; 10 | 11 | input [2:0] ALUControl; 12 | input signed [N-1:0] a, b; 13 | 14 | output zero, neg; 15 | output reg signed [N-1:0] w; 16 | 17 | always @(a or b or ALUControl) begin 18 | case (ALUControl) 19 | `ADD : w = a + b; 20 | `SUB : w = a - b; 21 | `AND : w = a & b; 22 | `OR : w = a | b; 23 | `SLT : w = a < b ? 32'd1 : 32'd0; 24 | `XOR : w = a ^ b; 25 | default: w = {N{1'bz}}; 26 | endcase 27 | end 28 | 29 | assign zero = (~|w); 30 | assign neg = w[N-1]; 31 | 32 | endmodule -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/code/ALU_Controller.v: -------------------------------------------------------------------------------- 1 | `define S_T 2'b00 2 | `define B_T 2'b01 3 | `define R_T 2'b10 4 | `define I_T 2'b11 5 | 6 | 7 | `define ADD 3'b000 8 | `define SUB 3'b001 9 | `define AND 3'b010 10 | `define OR 3'b011 11 | `define SLT 3'b101 12 | `define XOR 3'b100 13 | 14 | 15 | module ALU_Controller(func3, func7, ALUOp, ALUControl); 16 | 17 | input [2:0] func3; 18 | input [1:0] ALUOp; 19 | input func7; //bit 30 instr 20 | 21 | output reg [2:0] ALUControl; 22 | 23 | always @(ALUOp or func3 or func7)begin 24 | case (ALUOp) 25 | `S_T : ALUControl <= `ADD; 26 | `B_T : ALUControl <= `SUB; 27 | `R_T : ALUControl <= 28 | (func3 == 3'b000 & ~func7) ? `ADD: 29 | (func3 == 3'b000 & func7) ? `SUB: 30 | (func3 == 3'b111) ? `AND: 31 | (func3 == 3'b110) ? `OR: 32 | (func3 == 3'b010) ? `SLT : 3'bzzz; 33 | `I_T : ALUControl <= 34 | (func3 == 3'b000) ? `ADD: 35 | (func3 == 3'b100) ? `XOR: 36 | (func3 == 3'b110) ? `OR: 37 | (func3 == 3'b010) ? `SLT: 3'bzzz; 38 | default: ALUControl <= `ADD; 39 | endcase 40 | end 41 | endmodule 42 | -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/code/Adder.v: -------------------------------------------------------------------------------- 1 | module Adder(a, b, w); 2 | parameter N = 32; 3 | 4 | input [N-1:0] a; 5 | input [N-1:0] b; 6 | 7 | output [N-1:0] w; 8 | 9 | assign w = a + b; 10 | 11 | endmodule -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/code/BranchController.v: -------------------------------------------------------------------------------- 1 | `define BEQ 3'b000 2 | `define BNE 3'b001 3 | `define BLT 3'b010 4 | `define BGE 3'b011 5 | 6 | module BranchController(func3, branch, neg, zero, w); 7 | 8 | input branch, zero, neg; 9 | inout [2:0] func3; 10 | 11 | output reg w; 12 | 13 | always @(func3, zero, neg, branch) begin 14 | case(func3) 15 | `BEQ : w <= branch & zero; 16 | `BNE : w <= branch & ~zero; 17 | `BLT : w <= branch & neg; 18 | `BGE : w <= branch & (zero | ~neg); 19 | default: w <= 1'b0; 20 | endcase 21 | end 22 | 23 | endmodule -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/code/DataMemory.v: -------------------------------------------------------------------------------- 1 | module DataMemory(memAdr, writeData, memWrite, clk, readData); 2 | parameter N = 32; 3 | input [31:0] memAdr, writeData; 4 | input memWrite, clk; 5 | 6 | output [N-1:0] readData; 7 | 8 | reg [7:0] dataMemory [0:$pow(2, 16)-1]; // 64KB 9 | 10 | wire [31:0] adr; 11 | assign adr = {memAdr[31:2], 2'b00}; 12 | 13 | initial $readmemb("data.mem", dataMemory, 1000); 14 | 15 | always @(posedge clk) begin 16 | if(memWrite) 17 | {dataMemory[adr + 3], dataMemory[adr + 2], 18 | dataMemory[adr + 1], dataMemory[adr]} <= writeData; 19 | end 20 | 21 | assign readData = {dataMemory[adr + 3], dataMemory[adr + 2], 22 | dataMemory[adr + 1], dataMemory[adr]}; 23 | 24 | endmodule 25 | -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/code/ImmediateExtend.v: -------------------------------------------------------------------------------- 1 | `define I_T 3'b000 2 | `define S_T 3'b001 3 | `define B_T 3'b010 4 | `define J_T 3'b011 5 | `define U_T 3'b100 6 | 7 | module ImmExtension(immSrc, data, w); 8 | 9 | input [2:0] immSrc; 10 | input [24:0] data; 11 | 12 | output reg [31:0] w; 13 | 14 | always @(immSrc, data) begin 15 | case(immSrc) 16 | `I_T : w <= {{20{data[24]}}, data[24:13]}; 17 | `S_T : w <= {{20{data[24]}}, data[24:18], data[4:0]}; 18 | `J_T : w <= {{12{data[24]}}, data[12:5], data[13], data[23:14], 1'b0}; 19 | `B_T : w <= {{20{data[24]}}, data[0], data[23:18], data[4:1], 1'b0}; 20 | `U_T : w <= {data[24:5], {12{1'b0}}}; 21 | default: w <= 32'b0; 22 | endcase 23 | end 24 | 25 | endmodule -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/code/InstructionMemory.v: -------------------------------------------------------------------------------- 1 | module InstructionMemory(pc, instruction); 2 | 3 | input [31:0] pc; 4 | 5 | output [31:0] instruction; 6 | 7 | reg [7:0] instructionMemory [0:$pow(2, 16)-1]; 8 | 9 | wire [31:0] adr; 10 | assign adr = {pc[31:2], 2'b00}; 11 | 12 | initial $readmemb("instructions.mem", instructionMemory); 13 | 14 | assign instruction = {instructionMemory[adr], instructionMemory[adr + 1], 15 | instructionMemory[adr + 2], instructionMemory[adr + 3]}; 16 | 17 | endmodule 18 | -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/code/MainController.v: -------------------------------------------------------------------------------- 1 | `define R_T 7'b0110011 2 | `define I_T 7'b0010011 3 | `define S_T 7'b0100011 4 | `define B_T 7'b1100011 5 | `define U_T 7'b0110111 6 | `define J_T 7'b1101111 7 | `define LW_T 7'b0000011 8 | `define JALR_T 7'b1100111 9 | 10 | module MainController(op, zero, resultSrc, memWrite, 11 | ALUOp, ALUSrc, immSrc, regWrite, 12 | jal, jalr, neg, branch); 13 | 14 | input [6:0] op; 15 | input zero, neg; 16 | 17 | output reg [1:0] resultSrc, ALUOp; 18 | output reg [2:0] immSrc; 19 | output reg regWrite, memWrite, ALUSrc, jal, jalr, branch; 20 | 21 | always @(op) begin 22 | {memWrite, regWrite, ALUSrc, jal, 23 | jalr, branch, immSrc, resultSrc, ALUOp} <= 13'b0; 24 | case(op) 25 | `R_T:begin 26 | ALUOp <= 2'b10; 27 | regWrite <= 1'b1; 28 | end 29 | 30 | `I_T:begin 31 | ALUOp <= 2'b11; 32 | regWrite <= 1'b1; 33 | immSrc <= 3'b000; 34 | ALUSrc <= 1'b1; 35 | jalr <= 1'b0; 36 | resultSrc <= 2'b00; 37 | end 38 | 39 | `LW_T:begin 40 | ALUOp <= 2'b00; 41 | regWrite <= 1'b1; 42 | immSrc <= 3'b000; 43 | ALUSrc <= 1'b1; 44 | jalr <= 1'b0; 45 | resultSrc <= 2'b01; 46 | end 47 | 48 | `JALR_T:begin 49 | ALUOp <= 2'b00; 50 | regWrite <= 1'b1; 51 | immSrc <= 3'b000; 52 | ALUSrc <= 1'b1; 53 | jalr <= 1'b1; 54 | resultSrc <= 2'b10; 55 | end 56 | 57 | `S_T:begin 58 | ALUOp <= 2'b00; 59 | memWrite <= 1'b1; 60 | immSrc <= 3'b001; 61 | ALUSrc <= 1'b1; 62 | end 63 | 64 | `J_T:begin 65 | resultSrc <= 2'b10; 66 | immSrc <= 3'b011; 67 | jal <= 1'b1; 68 | regWrite <= 1'b1; 69 | end 70 | 71 | `B_T:begin 72 | ALUOp <= 2'b01; 73 | immSrc <= 3'b010; 74 | branch <= 1'b1; 75 | end 76 | 77 | `U_T:begin 78 | resultSrc <= 2'b11; 79 | immSrc <= 3'b100; 80 | regWrite <= 1'b1; 81 | end 82 | endcase 83 | end 84 | endmodule -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/code/Mux2to1.v: -------------------------------------------------------------------------------- 1 | module Mux2to1(slc, a, b, w); 2 | parameter N = 32; 3 | 4 | input slc; 5 | input [N-1:0] a, b; 6 | 7 | output [N-1:0] w; 8 | 9 | assign w = ~slc ? a : b; 10 | 11 | endmodule -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/code/Mux4to1.v: -------------------------------------------------------------------------------- 1 | module Mux4to1(slc, a, b, c, d, w); 2 | parameter N = 32; 3 | 4 | input [1:0] slc; 5 | input [N-1:0] a, b, c, d; 6 | 7 | output reg [N-1:0] w; 8 | 9 | always @(a or b or c or d or slc) begin 10 | case (slc) 11 | 2'b00 : w <= a; 12 | 2'b01 : w <= b; 13 | 2'b10 : w <= c; 14 | 2'b11 : w <= d; 15 | default: w <= {N{1'bz}}; 16 | endcase 17 | end 18 | 19 | endmodule -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/code/RISC_V.v: -------------------------------------------------------------------------------- 1 | module RISC_V(clk, rst); 2 | 3 | input clk, rst; 4 | 5 | wire [2:0] func3, ALUControl, immSrc; 6 | wire zero, neg, memWrite, regWrite, ALUSrc, func7; 7 | wire [1:0] resultSrc, PCSrc; 8 | wire [6:0] op; 9 | 10 | RISC_V_Controller CU( 11 | .op(op), .func3(func3), .func7(func7), 12 | .zero(zero), .PCSrc(PCSrc), 13 | .resultSrc(resultSrc), .memWrite(memWrite), 14 | .ALUControl(ALUControl), .immSrc(immSrc), 15 | .ALUSrc(ALUSrc), .neg(neg), .regWrite(regWrite) 16 | ); 17 | 18 | RISC_V_Datapath DP( 19 | .clk(clk), .rst(rst), .regWrite(regWrite), 20 | .ALUSrc(ALUSrc), .resultSrc(resultSrc), 21 | .PCSrc(PCSrc), .ALUControl(ALUControl), 22 | .immSrc(immSrc), .zero(zero), .neg(neg), .op(op), 23 | .func7(func7), .memWrite(memWrite), .func3(func3) 24 | ); 25 | 26 | endmodule -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/code/RISC_V_Controller.v: -------------------------------------------------------------------------------- 1 | module RISC_V_Controller(op, func3, func7, zero, PCSrc, 2 | resultSrc, memWrite, ALUControl, 3 | ALUSrc, immSrc, neg, regWrite); 4 | 5 | input [6:0] op; 6 | input [2:0] func3; 7 | input zero, neg, func7; 8 | 9 | output [1:0] PCSrc, resultSrc; 10 | output [2:0] ALUControl, immSrc; 11 | output regWrite, memWrite, ALUSrc; 12 | 13 | wire jal, jalr, branch, branchRes; 14 | wire [1:0] ALUOp; 15 | 16 | MainController mainController( 17 | .op(op), .zero(zero), .neg(neg), .ALUOp(ALUOp), 18 | .resultSrc(resultSrc), .memWrite(memWrite), 19 | .ALUSrc(ALUSrc), .immSrc(immSrc), .regWrite(regWrite), 20 | .jal(jal), .jalr(jalr), .branch(branch) 21 | ); 22 | 23 | BranchController branchController( 24 | .func3(func3), .branch(branch), .neg(neg), 25 | .zero(zero), .w(branchRes) 26 | ); 27 | 28 | ALU_Controller ALUController( 29 | .func3(func3), .func7(func7), .ALUOp(ALUOp), .ALUControl(ALUControl) 30 | ); 31 | 32 | assign PCSrc = (jalr) ? 2'b10 : (jal | branchRes) ? 2'b01: 2'b00; 33 | 34 | endmodule -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/code/RISC_V_Datapath.v: -------------------------------------------------------------------------------- 1 | module RISC_V_Datapath(clk, rst, regWrite, ALUSrc, 2 | resultSrc, PCSrc, 3 | ALUControl, immSrc, 4 | zero, neg, op, 5 | func7, memWrite, func3); 6 | 7 | 8 | input clk, rst, regWrite, ALUSrc, memWrite; 9 | input [1:0] resultSrc, PCSrc; 10 | input [2:0] immSrc, ALUControl; 11 | 12 | output zero, neg, func7; 13 | output [6:0] op; 14 | output [2:0] func3; 15 | 16 | wire [31:0] PC, PCNext, PCPlus4, PCTarget, 17 | immExt, instr, ALUResult, 18 | readData, result, 19 | SrcA, SrcB, RD2, RD1; 20 | 21 | Register PC_Register( 22 | .in(PCNext), .rst(rst), .clk(clk), .out(PC) 23 | ); 24 | 25 | Mux2to1 branchMux( 26 | .slc(ALUSrc), .a(RD2), .b(immExt), .w(SrcB) 27 | ); 28 | 29 | Mux4to1 PC_Mux( 30 | .slc(PCSrc), .a(PCPlus4), .b(PCTarget), 31 | .c(ALUResult), .d(32'b0), .w(PCNext) 32 | ); 33 | 34 | Mux4to1 ResultMux( 35 | .slc(resultSrc), .a(ALUResult), .b(readData), 36 | .c(PCPlus4), .d(immExt), .w(result) 37 | ); 38 | 39 | Adder PCTar( 40 | .a(PC), .b(immExt), .w(PCTarget) 41 | ); 42 | 43 | Adder PCP4( 44 | .a(PC), .b(32'd4), .w(PCPlus4) 45 | ); 46 | 47 | ImmExtension immExtensionInstance( 48 | .immSrc(immSrc), .data(instr[31:7]), .w(immExt) 49 | ); 50 | 51 | ALU ALU_Instance( 52 | .ALUControl(ALUControl), .a(SrcA), .b(SrcB), 53 | .zero(zero), .neg(neg), .w(ALUResult) 54 | ); 55 | 56 | DataMemory DM( 57 | .memAdr(ALUResult), .writeData(RD2), .clk(clk), 58 | .memWrite(memWrite), .readData(readData) 59 | ); 60 | 61 | InstructionMemory IM( 62 | .pc(PC), .instruction(instr) 63 | ); 64 | 65 | RegisterFile RF( 66 | .clk(clk), 67 | .writeData(result), .regWrite(regWrite), 68 | .readData1(RD1), .readData2(RD2), 69 | .readRegister1(instr[19:15]), 70 | .readRegister2(instr[24:20]), 71 | .writeRegister(instr[11:7]) 72 | ); 73 | 74 | assign SrcA = RD1; 75 | assign op = instr[6:0]; 76 | assign func3 = instr[14:12]; 77 | assign func7 = instr[30]; 78 | 79 | endmodule -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/code/Register.v: -------------------------------------------------------------------------------- 1 | module Register(in, clk, rst, out); 2 | parameter N = 32; 3 | 4 | input [N-1:0] in; 5 | input clk, rst; 6 | 7 | output reg [N-1:0] out; 8 | 9 | always @(posedge clk or posedge rst) begin 10 | if(rst) 11 | out <= {N{1'b0}}; 12 | else 13 | out <= in; 14 | end 15 | 16 | endmodule -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/code/RregisterFile.v: -------------------------------------------------------------------------------- 1 | `define BITS(x) $rtoi($ceil($clog2(x))) 2 | 3 | module RegisterFile(clk, regWrite, 4 | readRegister1, readRegister2, 5 | writeRegister, writeData, 6 | readData1, readData2); 7 | 8 | parameter WordLen = 32; 9 | parameter WordCount = 32; 10 | 11 | input regWrite, clk; 12 | input [`BITS(WordCount)-1:0] readRegister1, readRegister2, writeRegister; 13 | input [WordLen-1:0] writeData; 14 | output [WordLen-1:0] readData1, readData2; 15 | 16 | reg [WordLen-1:0] registerFile [0:WordCount-1]; 17 | 18 | initial 19 | registerFile[0] = 32'd0; 20 | 21 | always @(posedge clk) begin 22 | if (regWrite & (|writeRegister)) 23 | registerFile[writeRegister] <= writeData; 24 | end 25 | 26 | assign readData1 = registerFile[readRegister1]; 27 | assign readData2 = registerFile[readRegister2]; 28 | 29 | endmodule 30 | -------------------------------------------------------------------------------- /2 - RISC-V Single-Cycle/code/TestBench.v: -------------------------------------------------------------------------------- 1 | module TB(); 2 | reg clk, rst; 3 | RISC_V risc_v(.clk(clk), .rst(rst)); 4 | always #5 clk = ~clk; 5 | 6 | initial begin 7 | clk = 1'b0; 8 | #2 rst = 1'b1; 9 | #6 rst = 1'b0; 10 | #2000 $stop; 11 | end 12 | 13 | endmodule -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/assets/assembly/maxarray.s: -------------------------------------------------------------------------------- 1 | .global _boot 2 | 3 | .text 4 | _boot: 5 | jal x0,FindMax 6 | 7 | FindMax: 8 | lw x8, 1000(x0) # maxElement = mem[1000] 9 | add x9, x0, x0 # i 10 | 11 | Loop: 12 | addi x9, x9, 4 # i += 4 13 | slti x6, x9, 40 # check if 10 elements are traversed (40 = 4 * 10) 14 | beq x6, x0, EndLoop # if 10 elements are traversed, jump to EndLoop 15 | lw x18, 1000(x9) # element = mem[i] 16 | slt x6, x8, x18 # check if element is greater than maxElement 17 | beq x6, x0, Loop # if element is not greater than maxElement, jump to Loop 18 | add x8, x18, x0 # maxElement = element 19 | jal x0,Loop # jump to Loop 20 | 21 | EndLoop: 22 | sw x8, 2000(x0) # mem[2000] = maxElement 23 | jal x0,End # return 24 | 25 | End: 26 | 27 | -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/assets/assembly/maxarraySemiAsm.s: -------------------------------------------------------------------------------- 1 | .global _boot 2 | 3 | .text 4 | _boot: 5 | jal FindMax 6 | 7 | FindMax: 8 | lw s0, 1000(zero) # maxElement = mem[1000] 9 | add s1, zero, zero # i 10 | 11 | Loop: 12 | addi s1, s1, 4 # i += 4 13 | slti t1, s1, 40 # check if 10 elements are traversed (40 = 4 * 10) 14 | beq t1, zero, EndLoop # if 10 elements are traversed, jump to EndLoop 15 | lw s2, 1000(s1) # element = mem[i] 16 | slt t1, s0, s2 # check if element is greater than maxElement 17 | beq t1, zero, Loop # if element is not greater than maxElement, jump to Loop 18 | add s0, s2, zero # maxElement = element 19 | jal Loop # jump to Loop 20 | 21 | EndLoop: 22 | sw s0, 2000(zero) # mem[2000] = maxElement 23 | jal End # return 24 | 25 | End: 26 | 27 | -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/assets/controller/Multi-Cycle Controller.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shahriar-0/Computer-Architecture-Course-Projects-S2023/869ef7aa726a823138fb17e00bcaafadb635655b/3 - RISC-V Multi-Cycle/assets/controller/Multi-Cycle Controller.jpg -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/assets/datapath/Multi-Cycle Datapath.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shahriar-0/Computer-Architecture-Course-Projects-S2023/869ef7aa726a823138fb17e00bcaafadb635655b/3 - RISC-V Multi-Cycle/assets/datapath/Multi-Cycle Datapath.png -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/assets/memory/instrdata.mem: -------------------------------------------------------------------------------- 1 | @000 2 | 01101111 3 | 00000000 4 | 01000000 5 | 00000000 6 | @004 7 | 00000011 8 | 00100100 9 | 10000000 10 | 00111110 11 | @008 12 | 10110011 13 | 00000100 14 | 00000000 15 | 00000000 16 | @00c 17 | 10010011 18 | 10000100 19 | 01000100 20 | 00000000 21 | @010 22 | 00010011 23 | 10100011 24 | 10000100 25 | 00000010 26 | @014 27 | 01100011 28 | 00001100 29 | 00000011 30 | 00000000 31 | @018 32 | 00000011 33 | 10101001 34 | 10000100 35 | 00111110 36 | @01c 37 | 00110011 38 | 00100011 39 | 00100100 40 | 00000001 41 | @020 42 | 11100011 43 | 00000110 44 | 00000011 45 | 11111110 46 | @024 47 | 00110011 48 | 00000100 49 | 00001001 50 | 00000000 51 | @028 52 | 01101111 53 | 11110000 54 | 01011111 55 | 11111110 56 | @02c 57 | 00100011 58 | 00101000 59 | 10000000 60 | 01111100 61 | @030 62 | 01101111 63 | 00000000 64 | 01000000 65 | 00000000 66 | @3e8 67 | 11011110 68 | 11111111 69 | 11111111 70 | 11111111 71 | @3ec 72 | 11110110 73 | 11111111 74 | 11111111 75 | 11111111 76 | @3f0 77 | 00100101 78 | 00000000 79 | 00000000 80 | 00000000 81 | @3f4 82 | 00101110 83 | 00000000 84 | 00000000 85 | 00000000 86 | @3f8 87 | 01100010 88 | 00000000 89 | 00000000 90 | 00000000 91 | @3fc 92 | 00000010 93 | 00000000 94 | 00000000 95 | 00000000 96 | @400 97 | 10000011 98 | 00000000 99 | 00000000 100 | 00000000 101 | @404 102 | 00101010 103 | 11111100 104 | 11111111 105 | 11111111 106 | @408 107 | 10001111 108 | 00000000 109 | 00000000 110 | 00000000 111 | @40c 112 | 00001000 113 | 00000000 114 | 00000000 115 | 00000000 116 | @410 117 | 00111000 118 | 00000000 119 | 00000000 120 | 00000000 121 | @414 122 | 00100100 123 | 00000000 124 | 00000000 125 | 00000000 126 | @418 127 | 11100100 128 | 11111111 129 | 11111111 130 | 11111111 131 | @41c 132 | 01100010 133 | 00000000 134 | 00000000 135 | 00000000 136 | @420 137 | 00010001 138 | 00000000 139 | 00000000 140 | 00000000 141 | @424 142 | 11111001 143 | 11111111 144 | 11111111 145 | 11111111 146 | @428 147 | 00000000 148 | 00000000 149 | 00000000 150 | 00000000 151 | @42c 152 | 00000010 153 | 00000000 154 | 00000000 155 | 00000000 156 | @430 157 | 00000101 158 | 00000000 159 | 00000000 160 | 00000000 161 | @434 162 | 01011011 163 | 00000000 164 | 00000000 165 | 00000000 -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/assets/problem description/CA#03.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shahriar-0/Computer-Architecture-Course-Projects-S2023/869ef7aa726a823138fb17e00bcaafadb635655b/3 - RISC-V Multi-Cycle/assets/problem description/CA#03.pdf -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/assets/utils/assembler/customized_assembler/assembler.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | del instructions.mem 2>nul 4 | @REM del FindMax.asm 2>nul 5 | del ..\..\..\memory\instructions.mem 2>nul 6 | 7 | py main.py ..\..\..\assembly\maxarray.s 8 | copy instructions.mem ..\..\ 9 | 10 | pause 11 | -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/assets/utils/assembler/customized_assembler/assembler.py: -------------------------------------------------------------------------------- 1 | import os 2 | import io 3 | import type 4 | from tqdm import tqdm 5 | 6 | class Assembler: 7 | types = { 8 | **{k: type.R_Type() for k in type.R_Type.map.keys()}, 9 | **{k: type.I_Type() for k in type.I_Type.map.keys()}, 10 | **{k: type.S_Type() for k in type.S_Type.map.keys()}, 11 | **{k: type.J_Type() for k in type.J_Type.map.keys()}, 12 | **{k: type.B_Type() for k in type.B_Type.map.keys()}, 13 | **{k: type.U_Type() for k in type.U_Type.map.keys()}, 14 | } 15 | 16 | labeled = ["beq", "bne", "blt", "bge", "jal"] 17 | 18 | def __init__( 19 | self, 20 | filename_destination: str = "instructions.mem", 21 | directory: str = None, 22 | filename_source: str = None, 23 | ) -> None: 24 | self.directory = directory or os.getcwd() 25 | self.filename_destination = filename_destination 26 | if filename_source is None: 27 | self.filename_source = self.__find_first_assembly_file() 28 | else: 29 | self.filename_source = filename_source 30 | 31 | def __find_first_assembly_file(self): 32 | for root, dirs, files in os.walk(self.directory): 33 | for file in files: 34 | if file.endswith(".asm") or file.endswith(".s"): 35 | return os.path.join(root, file) 36 | return None 37 | 38 | def __find_assembly_lines(self) -> list[str]: 39 | if self.filename_source is None: 40 | print(f"No assembly file found in directory '{self.directory}'") 41 | exit(1) 42 | 43 | with open(self.filename_source, "r") as f: # type: io.TextIOWrapper 44 | lines = f.readlines() 45 | 46 | assembly_lines = [] 47 | for i, line in enumerate(lines): 48 | if line.lstrip() == "\n": 49 | continue 50 | try: 51 | command, *args = line.split() 52 | if command in self.types or ":" in line: 53 | assembly_lines.append(line.split("#", 1)[0]) 54 | except Exception as e: 55 | pass 56 | 57 | return assembly_lines 58 | 59 | def __find_line_of_label( 60 | self, lines: list[str], label: str, calling_line: int 61 | ) -> int: 62 | minus = 0 63 | for i, line in enumerate(lines): 64 | if label + ":" in line: 65 | return i - minus - calling_line 66 | if ":" in line: 67 | minus += 1 68 | 69 | return None 70 | 71 | def assemble(self): 72 | assembly_lines = self.__find_assembly_lines() 73 | machine_code_lines = [] 74 | 75 | for assembly_line in tqdm(assembly_lines, desc="Assembling lines"): 76 | try: 77 | command, *args = assembly_line.split() 78 | if command in self.types: 79 | if command in self.labeled: 80 | label = assembly_line.rstrip().rsplit(" ", 1)[1].rstrip() 81 | label_line = self.__find_line_of_label( 82 | assembly_lines, label, len(machine_code_lines) 83 | ) 84 | if label_line is None: 85 | raise Exception("label doesn't exist") 86 | assembly_line = assembly_line.replace( 87 | label, str(label_line << 2) 88 | ) 89 | machine_code_line = self.types[command](assembly_line) 90 | machine_code_lines.append(machine_code_line) 91 | except Exception as e: 92 | pass 93 | 94 | with open(self.filename_destination, "w") as f: # type: io.TextIOWrapper 95 | waiting_chars = ['|', '/', '-', '\\'] 96 | for i, line in enumerate(machine_code_lines): 97 | bytes = [line[i : i + 8] for i in range(0, len(line), 8)] 98 | start_address = 0 99 | f.write(f"@{start_address:03X}\n".lower()) 100 | for byte in reversed(bytes): 101 | f.write(byte + "\n") 102 | start_address += 4 103 | if i % 10 == 0: 104 | tqdm.write(f"\rWriting to file {waiting_chars[i % len(waiting_chars)]}", end='') 105 | tqdm.write("\nDone writing to file.") 106 | -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/assets/utils/assembler/customized_assembler/convertToBase2.py: -------------------------------------------------------------------------------- 1 | def twos_complement(decimal_number: int, n: int) -> str: 2 | if decimal_number >= 0: 3 | binary_number = bin(decimal_number)[2:] 4 | return binary_number.zfill(n) 5 | else: 6 | binary_number = bin(2**n + decimal_number)[2:] 7 | return binary_number 8 | -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/assets/utils/assembler/customized_assembler/main.py: -------------------------------------------------------------------------------- 1 | from assembler import Assembler 2 | from sys import argv 3 | 4 | 5 | def main(): 6 | if len(argv) == 3: 7 | assembler = Assembler(filename_destination=argv[2], filename_source=argv[1]) 8 | elif len(argv) == 2: 9 | assembler = Assembler(filename_source=argv[1]) 10 | else: 11 | print(f"Usage: ") 12 | print("or") 13 | print(f"Usage: and it will be stored in 'instructions.mem'") 14 | print( 15 | "now the program will use the first assembly file in this directory that ends with '.asm' or '.s'" 16 | ) 17 | assembler = Assembler() 18 | 19 | assembler.assemble() 20 | 21 | 22 | if __name__ == "__main__": 23 | main() 24 | -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/assets/utils/assembler/customized_assembler/toRealAssmebly.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | input_file = sys.argv[1] 4 | output_file = sys.argv[2] 5 | 6 | registers = [ 7 | "zero", 8 | "ra", 9 | "sp", 10 | "gp", 11 | "tp", 12 | "t0", 13 | "t1", 14 | "t2", 15 | "s0", 16 | "s1", 17 | "a0", 18 | "a1", 19 | "a2", 20 | "a3", 21 | "a4", 22 | "a5", 23 | "a6", 24 | "a7", 25 | "s2", 26 | "s3", 27 | "s4", 28 | "s5", 29 | "s6", 30 | "s7", 31 | "s8", 32 | "s9", 33 | "s10", 34 | "s11", 35 | "t3", 36 | "t4", 37 | "t5", 38 | "t6", 39 | ] 40 | 41 | with open(input_file, "r") as f_in, open(output_file, "w") as f_out: 42 | for line in f_in: 43 | parts = line.split("#", 1) 44 | for reg in registers: 45 | parts[0] = parts[0].replace(reg, "x" + str(registers.index(reg))) 46 | f_out.write("#".join(parts)) 47 | -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/assets/utils/assembler/customized_assembler/type.py: -------------------------------------------------------------------------------- 1 | from convertToBase2 import twos_complement 2 | from typing import Any 3 | from copy import deepcopy 4 | import re 5 | 6 | class Type: 7 | def __init__(self) -> None: 8 | pass 9 | 10 | def __call__(self, input: str, *args: Any, **kwds: Any) -> Any: 11 | self.__prepare_str(input) 12 | return self._assemble() 13 | 14 | def _assemble(self) -> str: 15 | print("here") 16 | pass 17 | 18 | def __prepare_str(self, input: str) -> str: 19 | no_comma_text = deepcopy(input).replace(",", "") 20 | no_extra_space = ( 21 | re.sub(r"\s+", " ", no_comma_text).split("#")[0].rstrip().lstrip() 22 | ) 23 | self.input = no_extra_space.replace("(", " ").replace(")", "") 24 | self.parsed = self.__parse() 25 | 26 | def __parse(self) -> list[str]: 27 | self.command, *self.args = self.input.split(" ") 28 | 29 | 30 | class R_Type(Type): 31 | map = { 32 | "add": ("0110011", "000", "0000000"), 33 | "sub": ("0110011", "000", "0100000"), 34 | "and": ("0110011", "111", "0000000"), 35 | "or": ("0110011", "110", "0000000"), 36 | "slt": ("0110011", "010", "0000000"), 37 | } 38 | 39 | def __init__(self) -> None: 40 | pass 41 | 42 | def _assemble(self) -> str: 43 | opcode, func3, func7 = self.map[self.command] 44 | rd = str(bin(int(self.args[0][1:]))[2:].zfill(5)) 45 | rs1 = str(bin(int(self.args[1][1:]))[2:].zfill(5)) 46 | rs2 = str(bin(int(self.args[2][1:]))[2:].zfill(5)) 47 | return func7 + rs2 + rs1 + func3 + rd + opcode 48 | 49 | 50 | class I_Type(Type): 51 | map = { 52 | "lw": ("0000011", "010"), 53 | "addi": ("0010011", "000"), 54 | "xori": ("0010011", "100"), 55 | "ori": ("0010011", "110"), 56 | "slti": ("0010011", "010"), 57 | "jalr": ("1100111", "000"), 58 | } 59 | 60 | def __init__(self) -> None: 61 | pass 62 | 63 | def _assemble(self) -> str: 64 | opcode, func3 = self.map[self.command] 65 | rd = str(bin(int(self.args[0][1:]))[2:].zfill(5)) 66 | if self.command == "lw": 67 | rs1 = str(bin(int(self.args[2][1:]))[2:].zfill(5)) 68 | imm = twos_complement(int(self.args[1]), 12) 69 | else: 70 | rs1 = str(bin(int(self.args[1][1:]))[2:].zfill(5)) 71 | imm = twos_complement(int(self.args[2]), 12) 72 | return imm + rs1 + func3 + rd + opcode 73 | 74 | 75 | class S_Type(Type): 76 | map = {"sw": ("0100011", "010")} 77 | 78 | def __init__(self) -> None: 79 | pass 80 | 81 | def _assemble(self) -> str: 82 | opcode, func3 = self.map[self.command] 83 | rs2 = str(bin(int(self.args[0][1:]))[2:].zfill(5)) 84 | rs1 = str(bin(int(self.args[2][1:]))[2:].zfill(5)) 85 | imm = twos_complement(int(self.args[1]), 12)[::-1] 86 | return imm[5:][::-1] + rs2 + rs1 + func3 + imm[:5][::-1] + opcode 87 | 88 | 89 | class J_Type(Type): 90 | map = {"jal": "1101111"} 91 | 92 | def __init__(self) -> None: 93 | pass 94 | 95 | def _assemble(self) -> str: 96 | opcode = self.map[self.command] 97 | rd = str(bin(int(self.args[0][1:]))[2:].zfill(5)) 98 | imm = twos_complement(int(self.args[1]), 21)[::-1] 99 | return imm[20] + imm[1:11][::-1] + imm[11] + imm[12:20][::-1] + rd + opcode 100 | 101 | 102 | class B_Type(Type): 103 | map = { 104 | "beq": ("1100011", "000"), 105 | "bne": ("1100011", "001"), 106 | "blt": ("1100011", "100"), 107 | "bge": ("1100011", "101"), 108 | } 109 | 110 | def __init__(self) -> None: 111 | pass 112 | 113 | def _assemble(self) -> str: 114 | opcode, func3 = self.map[self.command] 115 | rs1 = str(bin(int(self.args[0][1:]))[2:].zfill(5)) 116 | rs2 = str(bin(int(self.args[1][1:]))[2:].zfill(5)) 117 | imm = twos_complement(int(self.args[2]), 13)[::-1] 118 | return ( 119 | imm[12] 120 | + imm[5:11][::-1] 121 | + rs2 122 | + rs1 123 | + func3 124 | + imm[1:5][::-1] 125 | + imm[11] 126 | + opcode 127 | ) 128 | 129 | 130 | class U_Type(Type): 131 | map = {"lui": "0110111"} 132 | 133 | def __init__(self) -> None: 134 | pass 135 | 136 | def _assemble(self) -> str: 137 | opcode = self.map[self.command] 138 | rd = str(bin(int(self.args[0][1:]))[2:].zfill(5)) 139 | imm = twos_complement(int(self.args[1]), 21) 140 | return imm + rd + opcode -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/assets/utils/assembler/online/assembler_link.txt: -------------------------------------------------------------------------------- 1 | https://riscvasm.lucasteske.dev/# 2 | use this site to convert you assembly to hex file then use convert.py to have usable instructions.mem 3 | 4 | https://ascslab.org/research/briscv/simulator/simulator.html 5 | use this site to simulate RISC-V instructions -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/assets/utils/assembler/online/convert.py: -------------------------------------------------------------------------------- 1 | with open("../memory/instructions.hex", "r") as input_file: 2 | with open("../memory/instructions.mem", "w") as output_file: 3 | for line in input_file: 4 | hex_num = line.strip() 5 | num = int(hex_num, 16) 6 | 7 | msb = (num >> 24) & 0xFF 8 | next_8 = (num >> 16) & 0xFF 9 | next_8_2 = (num >> 8) & 0xFF 10 | lsb = num & 0xFF 11 | 12 | msb_bin = format(msb, "08b") 13 | next_8_bin = format(next_8, "08b") 14 | next_8_2_bin = format(next_8_2, "08b") 15 | lsb_bin = format(lsb, "08b") 16 | 17 | result = f"{lsb_bin}\n{next_8_2_bin}\n{next_8_bin}\n{msb_bin}\n" 18 | output_file.write(result) 19 | -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/assets/utils/combine_data_instr.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | @REM del ..\..\memory\data.mem 2>nul 4 | @REM del ..\..\memory\instructions.mem 2>nul 5 | 6 | cd assembler\customized_assembler 7 | .\assembler.bat 8 | cd ..\data_generator 9 | .\data_generator.bat 10 | 11 | copy instructions.mem + data.mem instrdata.mem 12 | 13 | pause 14 | -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/assets/utils/data_generator/data_generator.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | del data.mem 2>nul 4 | @REM del FindMax.asm 2>nul 5 | del ..\..\memory\data.mem 2>nul 6 | 7 | py data_generator.py ..\..\memory\ArrayData.txt 8 | copy data.mem ..\ 9 | pause 10 | -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/assets/utils/data_generator/data_generator.py: -------------------------------------------------------------------------------- 1 | from sys import argv 2 | from io_ import read_from_file, write_to_file 3 | 4 | OUTPUT_FILE = "data.mem" 5 | START_ADDRESS = 1000 6 | 7 | 8 | def twos_complement(x: str): 9 | if x[0] != "-": 10 | return x 11 | index = x.rindex("1") 12 | x = list(x) 13 | x[0] = "0" 14 | for i in range(index): 15 | if x[i] == "1": 16 | x[i] = "0" 17 | else: 18 | x[i] = "1" 19 | x = "".join(x) 20 | return x 21 | 22 | 23 | def hex_address_generator(binary_numbers: tuple[str], start_address: int) -> str: 24 | res = "" 25 | for num in binary_numbers: 26 | res += f"@{start_address:03X}\n".lower() 27 | res += num[24:] + "\n" 28 | res += num[16:24] + "\n" 29 | res += num[8:16] + "\n" 30 | res += num[:8] + "\n" 31 | start_address += 4 32 | return res 33 | 34 | 35 | def main() -> None: 36 | if len(argv) == 2: 37 | numbers = read_from_file(argv[1]) 38 | else: 39 | print("Usage: python data_generator.py ") 40 | exit(1) 41 | 42 | nums = tuple((twos_complement(f"{int(num):032b}") for num in numbers)) 43 | res = hex_address_generator(tuple(nums), START_ADDRESS) 44 | write_to_file(res, OUTPUT_FILE) 45 | 46 | 47 | if __name__ == "__main__": 48 | main() 49 | -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/assets/utils/data_generator/io_.py: -------------------------------------------------------------------------------- 1 | def read_from_file(filename: str) -> list[str]: 2 | with open(filename, "r", encoding="utf-8") as file: 3 | return file.read().splitlines() 4 | 5 | 6 | def write_to_file(data: str, filename: str) -> None: 7 | with open(filename, "w", encoding="utf-8") as file: 8 | file.write(data) 9 | -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/code/ALU.v: -------------------------------------------------------------------------------- 1 | `define ADD 3'b000 2 | `define SUB 3'b001 3 | `define AND 3'b010 4 | `define OR 3'b011 5 | `define SLT 3'b101 6 | `define XOR 3'b100 7 | 8 | module ALU(ALUControl, a, b, zero, neg, w); 9 | parameter N = 32; 10 | 11 | input [2:0] ALUControl; 12 | input signed [N-1:0] a, b; 13 | 14 | output zero, neg; 15 | output reg signed [N-1:0] w; 16 | 17 | always @(a or b or ALUControl) begin 18 | case (ALUControl) 19 | `ADD : w = a + b; 20 | `SUB : w = a - b; 21 | `AND : w = a & b; 22 | `OR : w = a | b; 23 | `SLT : w = a < b ? 32'd1 : 32'd0; 24 | `XOR : w = a ^ b; 25 | default: w = {N{1'bz}}; 26 | endcase 27 | end 28 | 29 | assign zero = (~|w); 30 | assign neg = w[N-1]; 31 | 32 | endmodule -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/code/ALU_Controller.v: -------------------------------------------------------------------------------- 1 | `define S_T 2'b00 2 | `define B_T 2'b01 3 | `define R_T 2'b10 4 | `define I_T 2'b11 5 | 6 | 7 | `define ADD 3'b000 8 | `define SUB 3'b001 9 | `define AND 3'b010 10 | `define OR 3'b011 11 | `define SLT 3'b101 12 | `define XOR 3'b100 13 | 14 | 15 | module ALU_Controller(func3, func7, ALUOp, ALUControl); 16 | 17 | input [2:0] func3; 18 | input [1:0] ALUOp; 19 | input func7; //bit 30 instr 20 | 21 | output reg [2:0] ALUControl; 22 | 23 | always @(ALUOp or func3 or func7)begin 24 | case (ALUOp) 25 | `S_T : ALUControl <= `ADD; 26 | `B_T : ALUControl <= `SUB; 27 | `R_T : ALUControl <= 28 | (func3 == 3'b000 & ~func7) ? `ADD: 29 | (func3 == 3'b000 & func7) ? `SUB: 30 | (func3 == 3'b111) ? `AND: 31 | (func3 == 3'b110) ? `OR: 32 | (func3 == 3'b010) ? `SLT : 3'bzzz; 33 | `I_T : ALUControl <= 34 | (func3 == 3'b000) ? `ADD: 35 | (func3 == 3'b100) ? `XOR: 36 | (func3 == 3'b110) ? `OR: 37 | (func3 == 3'b010) ? `SLT: 3'bzzz; 38 | default: ALUControl <= `ADD; 39 | endcase 40 | end 41 | endmodule -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/code/BranchController.v: -------------------------------------------------------------------------------- 1 | `define BEQ 3'b000 2 | `define BNE 3'b001 3 | `define BLT 3'b010 4 | `define BGE 3'b011 5 | 6 | module BranchController(func3, branch, neg, zero, w); 7 | 8 | input branch, zero, neg; 9 | inout [2:0] func3; 10 | 11 | output reg w; 12 | 13 | always @(func3, zero, neg, branch) begin 14 | case (func3) 15 | `BEQ : w <= branch & zero; 16 | `BNE : w <= branch & ~zero; 17 | `BLT : w <= branch & neg; 18 | `BGE : w <= branch & (zero | ~neg); 19 | default: w <= 1'b0; 20 | endcase 21 | end 22 | 23 | endmodule -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/code/ImmediateExtend.v: -------------------------------------------------------------------------------- 1 | `define I_T 3'b000 2 | `define S_T 3'b001 3 | `define B_T 3'b010 4 | `define J_T 3'b011 5 | `define U_T 3'b100 6 | 7 | module ImmExtension(immSrc, data, w); 8 | 9 | input [2:0] immSrc; 10 | input [24:0] data; 11 | 12 | output reg [31:0] w; 13 | 14 | always @(immSrc, data) begin 15 | case (immSrc) 16 | `I_T : w <= {{20{data[24]}}, data[24:13]}; 17 | `S_T : w <= {{20{data[24]}}, data[24:18], data[4:0]}; 18 | `J_T : w <= {{12{data[24]}}, data[12:5], data[13], data[23:14], 1'b0}; 19 | `B_T : w <= {{20{data[24]}}, data[0], data[23:18], data[4:1], 1'b0}; 20 | `U_T : w <= {data[24:5], {12{1'b0}}}; 21 | default: w <= 32'b0; 22 | endcase 23 | end 24 | 25 | endmodule -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/code/InstrDataMemory.v: -------------------------------------------------------------------------------- 1 | module InstrDataMemory (memAdr, writeData, memWrite, clk, readData); 2 | input [31:0] memAdr, writeData; 3 | input memWrite, clk; 4 | output [31:0] readData; 5 | reg [31:0] readData; 6 | 7 | reg [7:0] dataMem [0:$pow(2, 16)-1]; 8 | 9 | wire [31:0] adr; 10 | assign adr = {memAdr[31:2], 2'b00}; 11 | 12 | initial $readmemb("instrdata.mem", dataMem); 13 | 14 | always @(posedge clk) begin 15 | if (memWrite) 16 | {dataMem[adr + 3], dataMem[adr + 2], dataMem[adr + 1], dataMem[adr]} <= writeData; 17 | end 18 | 19 | assign readData = {dataMem[adr + 3], dataMem[adr + 2], dataMem[adr + 1], dataMem[adr]}; 20 | 21 | endmodule -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/code/MainController.v: -------------------------------------------------------------------------------- 1 | `define R_T 7'b0110011 2 | `define I_T 7'b0010011 3 | `define S_T 7'b0100011 4 | `define B_T 7'b1100011 5 | `define U_T 7'b0110111 6 | `define J_T 7'b1101111 7 | `define LW_T 7'b0000011 8 | `define JALR_T 7'b1100111 9 | 10 | `define IF 5'b00000 11 | `define ID 5'b00001 12 | `define EX_I 5'b00010 13 | `define MEM_I 5'b01100 14 | `define EX_R 5'b00011 15 | `define MEM_R 5'b01110 16 | `define EX_B 5'b00100 17 | `define EX_J 5'b00101 18 | `define MEM_J 5'b01000 19 | `define WB_J 5'b10000 20 | `define EX_JALR 5'b01001 21 | `define MEM_JALR 5'b00110 22 | `define EX_S 5'b00111 23 | `define MEM_S 5'b01101 24 | `define EX_LW 5'b01010 25 | `define MEM_LW 5'b01011 26 | `define WB_LW 5'b10001 27 | `define MEM_U 5'b01111 28 | 29 | module MainController(clk, rst, op, zero, 30 | PCUpdate, adrSrc, memWrite, branch, 31 | IRWrite, resultSrc, ALUOp, neg, 32 | ALUSrcA, ALUSrcB, immSrc, regWrite); 33 | 34 | input [6:0] op; 35 | input clk, rst, zero , neg; 36 | 37 | output reg [1:0] resultSrc, ALUSrcA, ALUSrcB, ALUOp; 38 | output reg [2:0] immSrc; 39 | output reg adrSrc, regWrite, memWrite, PCUpdate, branch, IRWrite; 40 | 41 | reg [4:0] pstate; 42 | reg [4:0] nstate = `IF; 43 | 44 | always @(pstate or op) begin 45 | case (pstate) 46 | `IF : nstate <= `ID; 47 | 48 | `ID : nstate <= (op == `I_T) ? `EX_I : 49 | (op == `R_T) ? `EX_R : 50 | (op == `B_T) ? `EX_B : 51 | (op == `J_T) ? `EX_J : 52 | (op == `U_T) ? `MEM_U : 53 | (op == `S_T) ? `EX_S : 54 | (op == `JALR_T) ? `EX_JALR : 55 | (op == `LW_T) ? `EX_LW : `IF; // undefined instruction 56 | 57 | `EX_I : nstate <= `MEM_I; 58 | `MEM_I: nstate <= `IF; 59 | 60 | `EX_R : nstate <= `MEM_R; 61 | `MEM_R: nstate <= `IF; 62 | 63 | `EX_B : nstate <= `IF; 64 | 65 | `EX_J : nstate <= `MEM_J; 66 | `MEM_J: nstate <= `WB_J; 67 | `WB_J : nstate <= `IF; 68 | 69 | `EX_S : nstate <= `MEM_S; 70 | `MEM_S: nstate <= `IF; 71 | 72 | `EX_JALR : nstate <= `MEM_JALR; 73 | `MEM_JALR: nstate <= `MEM_I; 74 | 75 | `EX_LW : nstate <= `MEM_LW; 76 | `MEM_LW: nstate <= `WB_LW; 77 | `WB_LW : nstate <= `IF; 78 | 79 | `MEM_U: nstate <= `IF; 80 | endcase 81 | end 82 | 83 | 84 | always @(pstate) begin 85 | 86 | {resultSrc, memWrite, ALUOp, ALUSrcA, ALUSrcB, immSrc, 87 | regWrite, PCUpdate, branch, IRWrite} <= 14'b0; 88 | 89 | case (pstate) 90 | // instruction fetch 91 | `IF : begin 92 | IRWrite <= 1'b1; 93 | adrSrc <= 1'b0; 94 | ALUSrcA <= 2'b00; 95 | ALUSrcB <= 2'b10; 96 | ALUOp <= 2'b00; 97 | resultSrc <= 2'b10; 98 | PCUpdate <= 1'b1; 99 | end 100 | // instruction decode 101 | `ID: begin 102 | ALUSrcA <= 2'b01; 103 | ALUSrcB <= 2'b01; 104 | ALUOp <= 2'b00; 105 | immSrc <= 3'b010; 106 | end 107 | // I-type 108 | `EX_I: begin 109 | ALUSrcA <= 2'b10; 110 | ALUSrcB <= 2'b01; 111 | immSrc <= 3'b000; 112 | ALUOp <= 2'b11; 113 | end 114 | 115 | `MEM_I: begin 116 | resultSrc <= 2'b00; 117 | regWrite <= 1'b1; 118 | end 119 | // JALR-type (it's different from I-type so in another cycle it's handled) 120 | `EX_JALR: begin 121 | ALUSrcA <= 2'b10; 122 | ALUSrcB <= 2'b01; 123 | immSrc <= 3'b000; 124 | ALUOp <= 2'b00; 125 | end 126 | 127 | `MEM_JALR: begin 128 | ALUSrcA <= 2'b01; 129 | ALUSrcB <= 2'b10; 130 | ALUOp <= 2'b00; 131 | resultSrc <= 2'b00; 132 | PCUpdate <= 1'b1; 133 | end 134 | // LW (like JALR) 135 | `EX_LW: begin 136 | ALUSrcA <= 2'b10; 137 | ALUSrcB <= 2'b01; 138 | immSrc <= 3'b000; 139 | ALUOp <= 2'b00; 140 | end 141 | 142 | `MEM_LW: begin 143 | resultSrc <= 2'b00; 144 | adrSrc <= 1'b1; 145 | end 146 | 147 | `WB_LW: begin 148 | resultSrc <= 2'b01; 149 | regWrite <= 1'b1; 150 | end 151 | // T-type 152 | `EX_R: begin 153 | ALUSrcA <= 2'b10; 154 | ALUSrcB <= 2'b00; 155 | ALUOp <= 2'b10; 156 | end 157 | 158 | `MEM_R: begin 159 | resultSrc <= 2'b00; 160 | regWrite <= 1'b1; 161 | end 162 | // B-type 163 | `EX_B: begin 164 | ALUSrcA <= 2'b10; 165 | ALUSrcB <= 2'b00; 166 | ALUOp <= 2'b01; 167 | resultSrc <= 2'b00; 168 | branch <= 1'b1; 169 | end 170 | // J-type 171 | `EX_J: begin 172 | ALUSrcA <= 2'b01; 173 | ALUSrcB <= 2'b10; 174 | ALUOp <= 2'b00; 175 | end 176 | 177 | `MEM_J: begin 178 | resultSrc <= 2'b00; 179 | regWrite <= 1'b1; 180 | ALUSrcA <= 2'b01; 181 | ALUSrcB <= 2'b01; 182 | immSrc <= 3'b011; 183 | ALUOp <= 2'b00; 184 | end 185 | 186 | `WB_J: begin 187 | resultSrc <= 2'b00; 188 | PCUpdate <= 1'b1; 189 | end 190 | // S-type 191 | `EX_S: begin 192 | ALUSrcA <= 2'b10; 193 | ALUSrcB <= 2'b01; 194 | ALUOp <= 2'b00; 195 | immSrc <= 3'b001; 196 | end 197 | 198 | `MEM_S: begin 199 | resultSrc <= 2'b00; 200 | adrSrc <= 1'b1; 201 | memWrite <= 1'b1; 202 | end 203 | // U-type 204 | `MEM_U: begin 205 | resultSrc <= 2'b11; 206 | immSrc <= 3'b100; 207 | regWrite <= 1'b1; 208 | end 209 | endcase 210 | end 211 | 212 | always @(posedge clk or posedge rst) begin 213 | if (rst) 214 | pstate <= `IF; 215 | else 216 | pstate <= nstate; 217 | end 218 | 219 | endmodule -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/code/Mux2to1.v: -------------------------------------------------------------------------------- 1 | module Mux2to1(slc, a, b, w); 2 | parameter N = 32; 3 | 4 | input slc; 5 | input [N-1:0] a, b; 6 | 7 | output [N-1:0] w; 8 | 9 | assign w = ~slc ? a : b; 10 | 11 | endmodule -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/code/Mux4to1.v: -------------------------------------------------------------------------------- 1 | module Mux4to1(slc, a, b, c, d, w); 2 | parameter N = 32; 3 | 4 | input [1:0] slc; 5 | input [N-1:0] a, b, c, d; 6 | 7 | output reg [N-1:0] w; 8 | 9 | always @(a or b or c or d or slc) begin 10 | case (slc) 11 | 2'b00 : w <= a; 12 | 2'b01 : w <= b; 13 | 2'b10 : w <= c; 14 | 2'b11 : w <= d; 15 | default: w <= {N{1'bz}}; 16 | endcase 17 | end 18 | 19 | endmodule -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/code/RISC_V.v: -------------------------------------------------------------------------------- 1 | module RISC_V(clk, rst); 2 | input clk, rst; 3 | 4 | wire [2:0] func3, ALUControl, immSrc; 5 | 6 | wire zero, neg, PCSrc, memWrite, func7, 7 | regWrite, ALUSrc, PCWrite, adrSrc, IRWrite; 8 | 9 | wire [1:0] resultSrc, ALUSrcA, ALUSrcB; 10 | 11 | wire [6:0] op; 12 | 13 | RISC_V_Controller CU( 14 | .clk(clk), .rst(rst), .op(op), 15 | .func3(func3), .immSrc(immSrc), 16 | .func7(func7), .zero(zero), 17 | .neg(neg), .PCWrite(PCWrite), 18 | .adrSrc(adrSrc), .memWrite(memWrite), 19 | .IRWrite(IRWrite), .resultSrc(resultSrc), 20 | .ALUControl(ALUControl), .ALUSrcA(ALUSrcA), 21 | .ALUSrcB(ALUSrcB), .regWrite(regWrite) 22 | ); 23 | 24 | RISC_V_Datapath DP( 25 | .clk(clk), .rst(rst), .neg(neg), 26 | .PCWrite(PCWrite), .adrSrc(adrSrc), 27 | .memWrite(memWrite), .IRWrite(IRWrite), 28 | .resultSrc(resultSrc), .immSrc(immSrc), 29 | .ALUControl(ALUControl), .op(op), 30 | .ALUSrcA(ALUSrcA), .func3(func3), 31 | .ALUSrcB(ALUSrcB), .zero(zero), 32 | .regWrite(regWrite), .func7(func7) 33 | ); 34 | 35 | endmodule -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/code/RISC_V_Controller.v: -------------------------------------------------------------------------------- 1 | module RISC_V_Controller(clk, rst, op, func3, func7, zero, neg, 2 | PCWrite, adrSrc, memWrite, 3 | IRWrite, resultSrc, ALUControl, 4 | ALUSrcA, ALUSrcB, immSrc, regWrite); 5 | input [6:0] op; 6 | input [2:0] func3; 7 | input clk, rst, zero , neg, func7; 8 | 9 | output PCWrite, adrSrc, memWrite, IRWrite, regWrite; 10 | output [1:0] resultSrc, ALUSrcA, ALUSrcB; 11 | output [2:0] ALUControl, immSrc; 12 | 13 | wire PCUpdate, branch, branchRes; 14 | wire[1:0] ALUOp; 15 | 16 | MainController mainController( 17 | .clk(clk), .rst(rst), .op(op), 18 | .zero(zero), .neg(neg), .PCUpdate(PCUpdate), 19 | .adrSrc(adrSrc), .memWrite(memWrite), 20 | .branch(branch), .resultSrc(resultSrc), 21 | .ALUSrcA(ALUSrcA), .ALUSrcB(ALUSrcB), 22 | .immSrc(immSrc), .regWrite(regWrite), 23 | .IRWrite(IRWrite), .ALUOp(ALUOp) 24 | ); 25 | 26 | ALU_Controller ALUController( 27 | .func3(func3), .func7(func7), .ALUOp(ALUOp), .ALUControl(ALUControl) 28 | ); 29 | 30 | BranchController branchController( 31 | .func3(func3), .branch(branch), 32 | .neg(neg), .zero(zero), .w(branchRes) 33 | ); 34 | 35 | assign PCWrite = (PCUpdate | branchRes); 36 | 37 | endmodule -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/code/RISC_V_Datapath.v: -------------------------------------------------------------------------------- 1 | module RISC_V_Datapath(clk, rst, PCWrite, adrSrc, memWrite, 2 | IRWrite, resultSrc, ALUControl, 3 | ALUSrcA, ALUSrcB, immSrc, regWrite, 4 | op, func3, func7, zero, neg); 5 | 6 | input clk, rst, PCWrite, adrSrc, memWrite, IRWrite, regWrite; 7 | input [1:0] resultSrc, ALUSrcA, ALUSrcB; 8 | input [2:0] ALUControl, immSrc; 9 | output [6:0] op; 10 | output [2:0] func3; 11 | output func7, zero, neg; 12 | 13 | wire [31:0] PC, Adr, ReadData, OldPC; 14 | wire [31:0] ImmExt, instr, Data; 15 | wire [31:0] RD1, RD2, A, B, SrcA, SrcB; 16 | wire [31:0] ALUResult, ALUOut,Result; 17 | 18 | Register PCR (.in(Result), .en(PCWrite), .rst(rst), .clk(clk), .out(PC)); 19 | Register OldPCR(.in(PC), .en(IRWrite), .rst(rst), .clk(clk), .out(OldPC)); 20 | Register IR (.in(ReadData), .en(IRWrite), .rst(rst), .clk(clk), .out(instr)); 21 | Register MDR (.in(ReadData), .en(1'b1), .rst(rst), .clk(clk), .out(Data)); 22 | Register AR (.in(RD1), .en(1'b1), .rst(rst), .clk(clk), .out(A)); 23 | Register BR (.in(RD2), .en(1'b1), .rst(rst), .clk(clk), .out(B)); 24 | Register ALUR (.in(ALUResult), .en(1'b1), .rst(rst), .clk(clk), .out(ALUOut)); 25 | 26 | Mux2to1 AdrMux(.slc(adrSrc), .a(PC), .b(Result), .w(Adr)); 27 | 28 | Mux4to1 AMux (.slc(ALUSrcA), .a(PC), .b(OldPC), .c(A), .d(32'd0), .w(SrcA)); 29 | Mux4to1 BMux (.slc(ALUSrcB), .a(B), .b(ImmExt), .c(32'd4), .d(32'd0), .w(SrcB)); 30 | Mux4to1 ResultMux(.slc(resultSrc), .a(ALUOut), .b(Data), .c(ALUResult), .d(ImmExt), .w(Result)); 31 | 32 | ImmExtension Extend( 33 | .immSrc(immSrc), .data(instr[31:7]), .w(ImmExt) 34 | ); 35 | 36 | ALU ALU_Instance( 37 | .ALUControl(ALUControl), .a(SrcA), .b(SrcB), 38 | .zero(zero), .neg(neg), .w(ALUResult) 39 | ); 40 | 41 | InstrDataMemory DM( 42 | .memAdr(Adr), .writeData(B), .clk(clk), 43 | .memWrite(memWrite), .readData(ReadData) 44 | ); 45 | 46 | RegisterFile RF( 47 | .clk(clk), 48 | .regWrite(regWrite), 49 | .writeData(Result), 50 | .readData1(RD1), .readData2(RD2), 51 | .readRegister1(instr[19:15]), 52 | .readRegister2(instr[24:20]), 53 | .writeRegister(instr[11:7]) 54 | ); 55 | 56 | assign op = instr[6:0]; 57 | assign func3 = instr[14:12]; 58 | assign func7 = instr[30]; 59 | endmodule -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/code/Register.v: -------------------------------------------------------------------------------- 1 | module Register(in, en, rst, clk, out); 2 | parameter N = 32; 3 | 4 | input [N-1:0] in; 5 | input en, clk, rst; 6 | 7 | output reg [N-1:0] out; 8 | 9 | always @(posedge clk or posedge rst) begin 10 | if (rst) 11 | out <= {N{1'b0}}; 12 | else if (en) 13 | out <= in; 14 | end 15 | 16 | endmodule -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/code/Registerfile.v: -------------------------------------------------------------------------------- 1 | `define BITS(x) $rtoi($ceil($clog2(x))) 2 | 3 | module RegisterFile(clk, regWrite, 4 | readRegister1, readRegister2, 5 | writeRegister, writeData, 6 | readData1, readData2); 7 | 8 | parameter WordLen = 32; 9 | parameter WordCount = 32; 10 | 11 | input regWrite, clk; 12 | input [`BITS(WordCount)-1:0] readRegister1, readRegister2, writeRegister; 13 | input [WordLen-1:0] writeData; 14 | output [WordLen-1:0] readData1, readData2; 15 | 16 | reg [WordLen-1:0] registerFile [0:WordCount-1]; 17 | 18 | initial 19 | registerFile[0] = 32'd0; 20 | 21 | always @(posedge clk) begin 22 | if (regWrite & (|writeRegister)) 23 | registerFile[writeRegister] <= writeData; 24 | end 25 | 26 | assign readData1 = registerFile[readRegister1]; 27 | assign readData2 = registerFile[readRegister2]; 28 | 29 | endmodule -------------------------------------------------------------------------------- /3 - RISC-V Multi-Cycle/code/TestBench.v: -------------------------------------------------------------------------------- 1 | module TB(); 2 | reg clk, rst; 3 | RISC_V risc_v(.clk(clk), .rst(rst)); 4 | always #5 clk = ~clk; 5 | 6 | initial begin 7 | clk = 1'b0; 8 | #2 rst = 1'b1; 9 | #6 rst = 1'b0; 10 | #3500 $stop; 11 | end 12 | 13 | endmodule -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/assets/assembly/maxarray.s: -------------------------------------------------------------------------------- 1 | .global _boot 2 | 3 | .text 4 | _boot: 5 | jal x0,FindMax 6 | 7 | FindMax: 8 | lw x8, 1000(x0) # maxElement = mem[1000] 9 | add x9, x0, x0 # i 10 | 11 | Loop: 12 | addi x9, x9, 4 # i += 4 13 | slti x6, x9, 40 # check if 10 elements are traversed (40 = 4 * 10) 14 | beq x6, x0, EndLoop # if 10 elements are traversed, jump to EndLoop 15 | lw x18, 1000(x9) # element = mem[i] 16 | slt x6, x8, x18 # check if element is greater than maxElement 17 | beq x6, x0, Loop # if element is not greater than maxElement, jump to Loop 18 | add x8, x18, x0 # maxElement = element 19 | jal x0,Loop # jump to Loop 20 | 21 | EndLoop: 22 | sw x8, 2000(x0) # mem[2000] = maxElement 23 | jal x0,End # return 24 | 25 | End: 26 | 27 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/assets/assembly/maxarraySemiAsm.s: -------------------------------------------------------------------------------- 1 | .global _boot 2 | 3 | .text 4 | _boot: 5 | jal FindMax 6 | 7 | FindMax: 8 | lw s0, 1000(zero) # maxElement = mem[1000] 9 | add s1, zero, zero # i 10 | 11 | Loop: 12 | addi s1, s1, 4 # i += 4 13 | slti t1, s1, 40 # check if 10 elements are traversed (40 = 4 * 10) 14 | beq t1, zero, EndLoop # if 10 elements are traversed, jump to EndLoop 15 | lw s2, 1000(s1) # element = mem[i] 16 | slt t1, s0, s2 # check if element is greater than maxElement 17 | beq t1, zero, Loop # if element is not greater than maxElement, jump to Loop 18 | add s0, s2, zero # maxElement = element 19 | jal Loop # jump to Loop 20 | 21 | EndLoop: 22 | sw s0, 2000(zero) # mem[2000] = maxElement 23 | jal End # return 24 | 25 | End: 26 | 27 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/assets/controller/Pipeline controller.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shahriar-0/Computer-Architecture-Course-Projects-S2023/869ef7aa726a823138fb17e00bcaafadb635655b/4 - RISC-V Pipeline/assets/controller/Pipeline controller.jpg -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/assets/datapath/Pipeline Datapath.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shahriar-0/Computer-Architecture-Course-Projects-S2023/869ef7aa726a823138fb17e00bcaafadb635655b/4 - RISC-V Pipeline/assets/datapath/Pipeline Datapath.png -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/assets/memory/data.mem: -------------------------------------------------------------------------------- 1 | @3e8 2 | 11011110 3 | 11111111 4 | 11111111 5 | 11111111 6 | @3ec 7 | 11110110 8 | 11111111 9 | 11111111 10 | 11111111 11 | @3f0 12 | 00100101 13 | 00000000 14 | 00000000 15 | 00000000 16 | @3f4 17 | 00101110 18 | 00000000 19 | 00000000 20 | 00000000 21 | @3f8 22 | 01100010 23 | 00000000 24 | 00000000 25 | 00000000 26 | @3fc 27 | 00000010 28 | 00000000 29 | 00000000 30 | 00000000 31 | @400 32 | 10000011 33 | 00000000 34 | 00000000 35 | 00000000 36 | @404 37 | 00101010 38 | 11111100 39 | 11111111 40 | 11111111 41 | @408 42 | 10001111 43 | 00000000 44 | 00000000 45 | 00000000 46 | @40c 47 | 00001000 48 | 00000000 49 | 00000000 50 | 00000000 51 | @410 52 | 00111000 53 | 00000000 54 | 00000000 55 | 00000000 56 | @414 57 | 00100100 58 | 00000000 59 | 00000000 60 | 00000000 61 | @418 62 | 11100100 63 | 11111111 64 | 11111111 65 | 11111111 66 | @41c 67 | 01100010 68 | 00000000 69 | 00000000 70 | 00000000 71 | @420 72 | 00010001 73 | 00000000 74 | 00000000 75 | 00000000 76 | @424 77 | 11111001 78 | 11111111 79 | 11111111 80 | 11111111 81 | @428 82 | 00000000 83 | 00000000 84 | 00000000 85 | 00000000 86 | @42c 87 | 00000010 88 | 00000000 89 | 00000000 90 | 00000000 91 | @430 92 | 00000101 93 | 00000000 94 | 00000000 95 | 00000000 96 | @434 97 | 01011011 98 | 00000000 99 | 00000000 100 | 00000000 101 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/assets/memory/instructions.mem: -------------------------------------------------------------------------------- 1 | 00000000 2 | 01000000 3 | 00000000 4 | 01101111 5 | 00111110 6 | 10000000 7 | 00100100 8 | 00000011 9 | 00000000 10 | 00000000 11 | 00000100 12 | 10110011 13 | 00000000 14 | 01000100 15 | 10000100 16 | 10010011 17 | 00000010 18 | 10000100 19 | 10100011 20 | 00010011 21 | 00000000 22 | 00000011 23 | 00001100 24 | 01100011 25 | 00111110 26 | 10000100 27 | 10101001 28 | 00000011 29 | 00000001 30 | 00100100 31 | 00100011 32 | 00110011 33 | 11111110 34 | 00000011 35 | 00000110 36 | 11100011 37 | 00000000 38 | 00001001 39 | 00000100 40 | 00110011 41 | 11111110 42 | 01011111 43 | 11110000 44 | 01101111 45 | 01111100 46 | 10000000 47 | 00101000 48 | 00100011 49 | 00000000 50 | 01000000 51 | 00000000 52 | 01101111 53 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/assets/problem description/CA#04.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shahriar-0/Computer-Architecture-Course-Projects-S2023/869ef7aa726a823138fb17e00bcaafadb635655b/4 - RISC-V Pipeline/assets/problem description/CA#04.pdf -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/assets/utils/assembler/customized assembler/assembler.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | del instructions.mem 2>nul 4 | del FindMax.asm 2>nul 5 | del ..\..\..\memory\instructions.mem 2>nul 6 | 7 | py main.py ..\..\..\assembly\maxarray.s 8 | copy instructions.mem ..\..\..\memory 9 | pause 10 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/assets/utils/assembler/customized assembler/assembler.py: -------------------------------------------------------------------------------- 1 | import os 2 | import io 3 | import type 4 | from tqdm import tqdm 5 | 6 | class Assembler: 7 | types = { 8 | **{k: type.R_Type() for k in type.R_Type.map.keys()}, 9 | **{k: type.I_Type() for k in type.I_Type.map.keys()}, 10 | **{k: type.S_Type() for k in type.S_Type.map.keys()}, 11 | **{k: type.J_Type() for k in type.J_Type.map.keys()}, 12 | **{k: type.B_Type() for k in type.B_Type.map.keys()}, 13 | **{k: type.U_Type() for k in type.U_Type.map.keys()}, 14 | } 15 | 16 | labeled = ["beq", "bne", "blt", "bge", "jal"] 17 | 18 | def __init__( 19 | self, 20 | filename_destination: str = "instructions.mem", 21 | directory: str = None, 22 | filename_source: str = None, 23 | ) -> None: 24 | self.directory = directory or os.getcwd() 25 | self.filename_destination = filename_destination 26 | if filename_source is None: 27 | self.filename_source = self.__find_first_assembly_file() 28 | else: 29 | self.filename_source = filename_source 30 | 31 | def __find_first_assembly_file(self): 32 | for root, dirs, files in os.walk(self.directory): 33 | for file in files: 34 | if file.endswith(".asm") or file.endswith(".s"): 35 | return os.path.join(root, file) 36 | return None 37 | 38 | def __find_assembly_lines(self) -> list[str]: 39 | if self.filename_source is None: 40 | print(f"No assembly file found in directory '{self.directory}'") 41 | exit(1) 42 | 43 | with open(self.filename_source, "r") as f: # type: io.TextIOWrapper 44 | lines = f.readlines() 45 | 46 | assembly_lines = [] 47 | for i, line in enumerate(lines): 48 | if line.lstrip() == "\n": 49 | continue 50 | try: 51 | command, *args = line.split() 52 | if command in self.types or ":" in line: 53 | assembly_lines.append(line.split("#", 1)[0]) 54 | except Exception as e: 55 | pass 56 | 57 | return assembly_lines 58 | 59 | def __find_line_of_label( 60 | self, lines: list[str], label: str, calling_line: int 61 | ) -> int: 62 | minus = 0 63 | for i, line in enumerate(lines): 64 | if label + ":" in line: 65 | return i - minus - calling_line 66 | if ":" in line: 67 | minus += 1 68 | 69 | return None 70 | 71 | def assemble(self): 72 | assembly_lines = self.__find_assembly_lines() 73 | machine_code_lines = [] 74 | 75 | for assembly_line in tqdm(assembly_lines, desc="Assembling lines"): 76 | try: 77 | command, *args = assembly_line.split() 78 | if command in self.types: 79 | if command in self.labeled: 80 | label = assembly_line.rstrip().rsplit(" ", 1)[1].rstrip() 81 | label_line = self.__find_line_of_label( 82 | assembly_lines, label, len(machine_code_lines) 83 | ) 84 | if label_line is None: 85 | raise Exception("label doesn't exist") 86 | assembly_line = assembly_line.replace( 87 | label, str(label_line << 2) 88 | ) 89 | machine_code_line = self.types[command](assembly_line) 90 | machine_code_lines.append(machine_code_line) 91 | except Exception as e: 92 | pass 93 | 94 | with open(self.filename_destination, "w") as f: # type: io.TextIOWrapper 95 | waiting_chars = ['|', '/', '-', '\\'] 96 | for i, line in enumerate(machine_code_lines): 97 | bytes = [line[i : i + 8] for i in range(0, len(line), 8)] 98 | for byte in bytes: 99 | f.write(byte + "\n") 100 | if i % 10 == 0: 101 | tqdm.write(f"\rWriting to file {waiting_chars[i % len(waiting_chars)]}", end='') 102 | tqdm.write("\nDone writing to file.") 103 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/assets/utils/assembler/customized assembler/convertToBase2.py: -------------------------------------------------------------------------------- 1 | def twos_complement(decimal_number: int, n: int) -> str: 2 | if decimal_number >= 0: 3 | binary_number = bin(decimal_number)[2:] 4 | return binary_number.zfill(n) 5 | else: 6 | binary_number = bin(2**n + decimal_number)[2:] 7 | return binary_number 8 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/assets/utils/assembler/customized assembler/main.py: -------------------------------------------------------------------------------- 1 | from assembler import Assembler 2 | from sys import argv 3 | 4 | 5 | def main(): 6 | if len(argv) == 3: 7 | assembler = Assembler(filename_destination=argv[2], filename_source=argv[1]) 8 | elif len(argv) == 2: 9 | assembler = Assembler(filename_source=argv[1]) 10 | else: 11 | print(f"Usage: ") 12 | print("or") 13 | print(f"Usage: and it will be stored in 'instructions.mem'") 14 | print( 15 | "now the program will use the first assembly file in this directory that ends with '.asm' or '.s'" 16 | ) 17 | assembler = Assembler() 18 | 19 | assembler.assemble() 20 | 21 | 22 | if __name__ == "__main__": 23 | main() 24 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/assets/utils/assembler/customized assembler/toRealAssmebly.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | input_file = sys.argv[1] 4 | output_file = sys.argv[2] 5 | 6 | registers = [ 7 | "zero", 8 | "ra", 9 | "sp", 10 | "gp", 11 | "tp", 12 | "t0", 13 | "t1", 14 | "t2", 15 | "s0", 16 | "s1", 17 | "a0", 18 | "a1", 19 | "a2", 20 | "a3", 21 | "a4", 22 | "a5", 23 | "a6", 24 | "a7", 25 | "s2", 26 | "s3", 27 | "s4", 28 | "s5", 29 | "s6", 30 | "s7", 31 | "s8", 32 | "s9", 33 | "s10", 34 | "s11", 35 | "t3", 36 | "t4", 37 | "t5", 38 | "t6", 39 | ] 40 | 41 | with open(input_file, "r") as f_in, open(output_file, "w") as f_out: 42 | for line in f_in: 43 | parts = line.split("#", 1) 44 | for reg in registers: 45 | parts[0] = parts[0].replace(reg, "x" + str(registers.index(reg))) 46 | f_out.write("#".join(parts)) 47 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/assets/utils/assembler/customized assembler/type.py: -------------------------------------------------------------------------------- 1 | from convertToBase2 import twos_complement 2 | from typing import Any 3 | from copy import deepcopy 4 | import re 5 | 6 | class Type: 7 | def __init__(self) -> None: 8 | pass 9 | 10 | def __call__(self, input: str, *args: Any, **kwds: Any) -> Any: 11 | self.__prepare_str(input) 12 | return self._assemble() 13 | 14 | def _assemble(self) -> str: 15 | print("here") 16 | pass 17 | 18 | def __prepare_str(self, input: str) -> str: 19 | no_comma_text = deepcopy(input).replace(",", "") 20 | no_extra_space = ( 21 | re.sub(r"\s+", " ", no_comma_text).split("#")[0].rstrip().lstrip() 22 | ) 23 | self.input = no_extra_space.replace("(", " ").replace(")", "") 24 | self.parsed = self.__parse() 25 | 26 | def __parse(self) -> list[str]: 27 | self.command, *self.args = self.input.split(" ") 28 | 29 | 30 | class R_Type(Type): 31 | map = { 32 | "add": ("0110011", "000", "0000000"), 33 | "sub": ("0110011", "000", "0100000"), 34 | "and": ("0110011", "111", "0000000"), 35 | "or": ("0110011", "110", "0000000"), 36 | "slt": ("0110011", "010", "0000000"), 37 | } 38 | 39 | def __init__(self) -> None: 40 | pass 41 | 42 | def _assemble(self) -> str: 43 | opcode, func3, func7 = self.map[self.command] 44 | rd = str(bin(int(self.args[0][1:]))[2:].zfill(5)) 45 | rs1 = str(bin(int(self.args[1][1:]))[2:].zfill(5)) 46 | rs2 = str(bin(int(self.args[2][1:]))[2:].zfill(5)) 47 | return func7 + rs2 + rs1 + func3 + rd + opcode 48 | 49 | 50 | class I_Type(Type): 51 | map = { 52 | "lw": ("0000011", "010"), 53 | "addi": ("0010011", "000"), 54 | "xori": ("0010011", "100"), 55 | "ori": ("0010011", "110"), 56 | "slti": ("0010011", "010"), 57 | "jalr": ("1100111", "000"), 58 | } 59 | 60 | def __init__(self) -> None: 61 | pass 62 | 63 | def _assemble(self) -> str: 64 | opcode, func3 = self.map[self.command] 65 | rd = str(bin(int(self.args[0][1:]))[2:].zfill(5)) 66 | if self.command == "lw": 67 | rs1 = str(bin(int(self.args[2][1:]))[2:].zfill(5)) 68 | imm = twos_complement(int(self.args[1]), 12) 69 | else: 70 | rs1 = str(bin(int(self.args[1][1:]))[2:].zfill(5)) 71 | imm = twos_complement(int(self.args[2]), 12) 72 | return imm + rs1 + func3 + rd + opcode 73 | 74 | 75 | class S_Type(Type): 76 | map = {"sw": ("0100011", "010")} 77 | 78 | def __init__(self) -> None: 79 | pass 80 | 81 | def _assemble(self) -> str: 82 | opcode, func3 = self.map[self.command] 83 | rs2 = str(bin(int(self.args[0][1:]))[2:].zfill(5)) 84 | rs1 = str(bin(int(self.args[2][1:]))[2:].zfill(5)) 85 | imm = twos_complement(int(self.args[1]), 12)[::-1] 86 | return imm[5:][::-1] + rs2 + rs1 + func3 + imm[:5][::-1] + opcode 87 | 88 | 89 | class J_Type(Type): 90 | map = {"jal": "1101111"} 91 | 92 | def __init__(self) -> None: 93 | pass 94 | 95 | def _assemble(self) -> str: 96 | opcode = self.map[self.command] 97 | rd = str(bin(int(self.args[0][1:]))[2:].zfill(5)) 98 | imm = twos_complement(int(self.args[1]), 21)[::-1] 99 | return imm[20] + imm[1:11][::-1] + imm[11] + imm[12:20][::-1] + rd + opcode 100 | 101 | 102 | class B_Type(Type): 103 | map = { 104 | "beq": ("1100011", "000"), 105 | "bne": ("1100011", "001"), 106 | "blt": ("1100011", "100"), 107 | "bge": ("1100011", "101"), 108 | } 109 | 110 | def __init__(self) -> None: 111 | pass 112 | 113 | def _assemble(self) -> str: 114 | opcode, func3 = self.map[self.command] 115 | rs1 = str(bin(int(self.args[0][1:]))[2:].zfill(5)) 116 | rs2 = str(bin(int(self.args[1][1:]))[2:].zfill(5)) 117 | imm = twos_complement(int(self.args[2]), 13)[::-1] 118 | return ( 119 | imm[12] 120 | + imm[5:11][::-1] 121 | + rs2 122 | + rs1 123 | + func3 124 | + imm[1:5][::-1] 125 | + imm[11] 126 | + opcode 127 | ) 128 | 129 | 130 | class U_Type(Type): 131 | map = {"lui": "0110111"} 132 | 133 | def __init__(self) -> None: 134 | pass 135 | 136 | def _assemble(self) -> str: 137 | opcode = self.map[self.command] 138 | rd = str(bin(int(self.args[0][1:]))[2:].zfill(5)) 139 | imm = twos_complement(int(self.args[1]), 21) 140 | return imm + rd + opcode -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/assets/utils/assembler/online/assembler_link.txt: -------------------------------------------------------------------------------- 1 | https://riscvasm.lucasteske.dev/# 2 | use this site to convert you assembly to hex file then use convert.py to have usable instructions.mem 3 | 4 | https://ascslab.org/research/briscv/simulator/simulator.html 5 | use this site to simulate RISC-V instructions -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/assets/utils/assembler/online/convert.py: -------------------------------------------------------------------------------- 1 | with open("../memory/instructions.hex", "r") as input_file: 2 | with open("../memory/instructions.mem", "w") as output_file: 3 | for line in input_file: 4 | hex_num = line.strip() 5 | num = int(hex_num, 16) 6 | 7 | msb = (num >> 24) & 0xFF 8 | next_8 = (num >> 16) & 0xFF 9 | next_8_2 = (num >> 8) & 0xFF 10 | lsb = num & 0xFF 11 | 12 | msb_bin = format(msb, "08b") 13 | next_8_bin = format(next_8, "08b") 14 | next_8_2_bin = format(next_8_2, "08b") 15 | lsb_bin = format(lsb, "08b") 16 | 17 | result = f"{msb_bin}\n{next_8_bin}\n{next_8_2_bin}\n{lsb_bin}\n" 18 | output_file.write(result) 19 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/assets/utils/data generator/data_generator.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | del data.mem 2>nul 4 | del FindMax.asm 2>nul 5 | del ..\..\memory\data.mem 2>nul 6 | 7 | py data_generator.py ..\..\memory\ArrayData.txt 8 | copy data.mem ..\..\memory 9 | pause 10 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/assets/utils/data generator/data_generator.py: -------------------------------------------------------------------------------- 1 | from sys import argv 2 | from io_ import read_from_file, write_to_file 3 | 4 | OUTPUT_FILE = "data.mem" 5 | START_ADDRESS = 1000 6 | 7 | 8 | def twos_complement(x: str): 9 | if x[0] != "-": 10 | return x 11 | index = x.rindex("1") 12 | x = list(x) 13 | x[0] = "0" 14 | for i in range(index): 15 | if x[i] == "1": 16 | x[i] = "0" 17 | else: 18 | x[i] = "1" 19 | x = "".join(x) 20 | return x 21 | 22 | 23 | def hex_address_generator(binary_numbers: tuple[str], start_address: int) -> str: 24 | res = "" 25 | for num in binary_numbers: 26 | res += f"@{start_address:03X}\n".lower() 27 | res += num[24:] + "\n" 28 | res += num[16:24] + "\n" 29 | res += num[8:16] + "\n" 30 | res += num[:8] + "\n" 31 | start_address += 4 32 | return res 33 | 34 | 35 | def main() -> None: 36 | if len(argv) == 2: 37 | numbers = read_from_file(argv[1]) 38 | else: 39 | print("Usage: python data_generator.py ") 40 | exit(1) 41 | 42 | nums = tuple((twos_complement(f"{int(num):032b}") for num in numbers)) 43 | res = hex_address_generator(tuple(nums), START_ADDRESS) 44 | write_to_file(res, OUTPUT_FILE) 45 | 46 | 47 | if __name__ == "__main__": 48 | main() 49 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/assets/utils/data generator/io_.py: -------------------------------------------------------------------------------- 1 | def read_from_file(filename: str) -> list[str]: 2 | with open(filename, "r", encoding="utf-8") as file: 3 | return file.read().splitlines() 4 | 5 | 6 | def write_to_file(data: str, filename: str) -> None: 7 | with open(filename, "w", encoding="utf-8") as file: 8 | file.write(data) 9 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/ALU.v: -------------------------------------------------------------------------------- 1 | `define ADD 3'b000 2 | `define SUB 3'b001 3 | `define AND 3'b010 4 | `define OR 3'b011 5 | `define SLT 3'b101 6 | `define XOR 3'b100 7 | 8 | module ALU(ALUControl, a, b, zero, neg, w); 9 | parameter N = 32; 10 | 11 | input [2:0] ALUControl; 12 | input signed [N-1:0] a, b; 13 | 14 | output zero, neg; 15 | output reg signed [N-1:0] w; // check if it shoudl be signed 16 | 17 | always @(a or b or ALUControl) begin 18 | case (ALUControl) 19 | `ADD : w = a + b; 20 | `SUB : w = a - b; 21 | `AND : w = a & b; 22 | `OR : w = a | b; 23 | `SLT : w = a < b ? 32'd1 : 32'd0; 24 | `XOR : w = a ^ b; 25 | default: w = {N{1'bz}}; 26 | endcase 27 | end 28 | 29 | assign zero = (~|w); 30 | assign neg = w[N-1]; 31 | 32 | endmodule -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/ALU_Controller.v: -------------------------------------------------------------------------------- 1 | `define S_T 2'b00 2 | `define B_T 2'b01 3 | `define R_T 2'b10 4 | `define I_T 2'b11 5 | 6 | `define ADD 3'b000 7 | `define SUB 3'b001 8 | `define AND 3'b010 9 | `define OR 3'b011 10 | `define SLT 3'b101 11 | `define XOR 3'b100 12 | 13 | 14 | module ALU_Controller(func3, func7, ALUOp, ALUControl); 15 | 16 | input [2:0] func3; 17 | input [1:0] ALUOp; 18 | input func7; //bit 30 instr 19 | 20 | output reg [2:0] ALUControl; 21 | 22 | always @(ALUOp or func3 or func7)begin 23 | case (ALUOp) 24 | `S_T : ALUControl <= `ADD; 25 | `B_T : ALUControl <= `SUB; 26 | `R_T : ALUControl <= 27 | (func3 == 3'b000 & ~func7) ? `ADD: 28 | (func3 == 3'b000 & func7) ? `SUB: 29 | (func3 == 3'b111) ? `AND: 30 | (func3 == 3'b110) ? `OR: 31 | (func3 == 3'b010) ? `SLT : 3'bzzz; 32 | `I_T : ALUControl <= 33 | (func3 == 3'b000) ? `ADD: 34 | (func3 == 3'b100) ? `XOR: 35 | (func3 == 3'b110) ? `OR: 36 | (func3 == 3'b010) ? `SLT: 3'bzzz; 37 | default: ALUControl <= `ADD; 38 | endcase 39 | end 40 | endmodule 41 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/Adder.v: -------------------------------------------------------------------------------- 1 | module Adder(a, b, w); 2 | parameter N = 32; 3 | 4 | input [N-1:0] a; 5 | input [N-1:0] b; 6 | 7 | output [N-1:0] w; 8 | 9 | assign w = a + b; 10 | 11 | endmodule -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/BranchController.v: -------------------------------------------------------------------------------- 1 | 2 | `define NOB 3'b000 3 | `define BEQ 3'b001 4 | `define BNE 3'b010 5 | `define BLT 3'b011 6 | `define BGE 3'b100 7 | 8 | `define JAL 2'b01 9 | `define JALR 2'b10 10 | 11 | module BranchController(branchE, jumpE, neg, zero, PCSrcE); 12 | 13 | input zero, neg; 14 | inout [2:0] branchE; 15 | input [1:0] jumpE; 16 | 17 | output reg [1:0] PCSrcE; 18 | 19 | always @(jumpE, zero, neg, branchE) begin 20 | case(branchE) 21 | `NOB : PCSrcE <= (jumpE == `JAL) ? 2'b01 : 22 | (jumpE == `JALR) ? 2'b10 : 2'b00; 23 | 24 | `BEQ : PCSrcE <= (zero) ? 2'b01 : 2'b00; 25 | `BNE : PCSrcE <= (~zero) ? 2'b01 : 2'b00; 26 | `BLT : PCSrcE <= (neg) ? 2'b01 : 2'b00; 27 | `BGE : PCSrcE <= (zero | ~neg) ? 2'b01 : 2'b00; 28 | endcase 29 | end 30 | 31 | endmodule -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/DataMemory.v: -------------------------------------------------------------------------------- 1 | module DataMemory(memAdr, writeData, memWrite, clk, readData); 2 | parameter N = 32; 3 | input [31:0] memAdr, writeData; 4 | input memWrite, clk; 5 | 6 | output [N-1:0] readData; 7 | 8 | reg [7:0] dataMemory [0:$pow(2, 16)-1]; // 64KB 9 | 10 | wire [31:0] adr; 11 | assign adr = {memAdr[31:2], 2'b00}; 12 | 13 | initial $readmemb("data.mem", dataMemory, 1000); 14 | 15 | always @(posedge clk) begin 16 | if(memWrite) 17 | {dataMemory[adr + 3], dataMemory[adr + 2], 18 | dataMemory[adr + 1], dataMemory[adr]} <= writeData; 19 | end 20 | 21 | assign readData = {dataMemory[adr + 3], dataMemory[adr + 2], 22 | dataMemory[adr + 1], dataMemory[adr]}; 23 | 24 | endmodule 25 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/HazardUnit.v: -------------------------------------------------------------------------------- 1 | module HazardUnit(Rs1D, Rs2D, RdE, RdM, RdW, Rs2E, Rs1E, 2 | PCSrcE, resultSrc0, regWriteW, 3 | regWriteM, stallF, stallD, flushD, 4 | flushE, forwardAE, forwardBE, luiM); 5 | 6 | input [4:0] Rs1D, Rs2D, RdE, RdM, RdW, Rs1E, Rs2E; 7 | input [1:0] PCSrcE; 8 | input regWriteM, regWriteW, resultSrc0, luiM; 9 | output reg [1:0] forwardAE, forwardBE; 10 | output reg stallF, stallD, flushD, flushE; 11 | 12 | always @(Rs1E or RdM or RdW or regWriteM or regWriteW) begin 13 | if(Rs1E == 5'b0) 14 | forwardAE <= 2'b00; 15 | else if((Rs1E == RdM) && regWriteM) 16 | forwardAE <= (luiM) ? 2'b11 : 2'b10; 17 | else if((Rs1E == RdW) && regWriteW) 18 | forwardAE <= 2'b01; 19 | else 20 | forwardAE <= 2'b00; 21 | end 22 | 23 | always @(Rs2E or RdM or RdW or regWriteM or regWriteW) begin 24 | if(Rs2E == 5'b0) 25 | forwardBE <= 2'b00; 26 | else if((Rs2E == RdM) && regWriteM) 27 | forwardBE <= (luiM) ? 2'b11 : 2'b10; 28 | else if((Rs2E == RdW) && regWriteW) 29 | forwardBE <= 2'b01; 30 | else 31 | forwardBE <= 2'b00; 32 | end 33 | 34 | reg lwStall; 35 | assign lwStall = ((((Rs1D == RdE) || (Rs2D == RdE)) && resultSrc0)); 36 | 37 | assign stallF = lwStall; 38 | assign stallD = lwStall; 39 | 40 | assign flushD = (PCSrcE != 2'b00); 41 | assign flushE = lwStall || (PCSrcE != 2'b00); 42 | 43 | endmodule 44 | 45 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/ImmediateExtend.v: -------------------------------------------------------------------------------- 1 | `define I_T 3'b000 2 | `define S_T 3'b001 3 | `define B_T 3'b010 4 | `define J_T 3'b011 5 | `define U_T 3'b100 6 | 7 | module ImmExtension(immSrc, data, w); 8 | 9 | input [2:0] immSrc; 10 | input [24:0] data; 11 | 12 | output reg [31:0] w; 13 | 14 | always @(immSrc, data) begin 15 | case(immSrc) 16 | `I_T : w <= {{20{data[24]}}, data[24:13]}; 17 | `S_T : w <= {{20{data[24]}}, data[24:18], data[4:0]}; 18 | `J_T : w <= {{12{data[24]}}, data[12:5], data[13], data[23:14], 1'b0}; 19 | `B_T : w <= {{20{data[24]}}, data[0], data[23:18], data[4:1], 1'b0}; 20 | `U_T : w <= {data[24:5], {12{1'b0}}}; 21 | default: w <= 32'b0; 22 | endcase 23 | end 24 | 25 | endmodule -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/InstructionMemory.v: -------------------------------------------------------------------------------- 1 | module InstructionMemory(pc, instruction); 2 | 3 | input [31:0] pc; 4 | 5 | output [31:0] instruction; 6 | 7 | reg [7:0] instructionMemory [0:$pow(2, 16)-1]; 8 | 9 | wire [31:0] adr; 10 | assign adr = {pc[31:2], 2'b00}; 11 | 12 | initial $readmemb("instructions.mem", instructionMemory); 13 | 14 | assign instruction = {instructionMemory[adr], instructionMemory[adr + 1], 15 | instructionMemory[adr + 2], instructionMemory[adr + 3]}; 16 | 17 | endmodule 18 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/MainController.v: -------------------------------------------------------------------------------- 1 | `define R_T 7'b0110011 2 | `define I_T 7'b0010011 3 | `define S_T 7'b0100011 4 | `define B_T 7'b1100011 5 | `define U_T 7'b0110111 6 | `define J_T 7'b1101111 7 | `define LW_T 7'b0000011 8 | `define JALR_T 7'b1100111 9 | 10 | `define BEQ 3'b000 11 | `define BNE 3'b001 12 | `define BLT 3'b010 13 | `define BGE 3'b011 14 | 15 | module MainController(op, func3, regWriteD, ALUOp, 16 | resultSrcD, memWriteD, jumpD, 17 | branchD, ALUSrcD, immSrcD, luiD); 18 | 19 | input [6:0] op; 20 | input [2:0] func3; 21 | output reg memWriteD, regWriteD, ALUSrcD, luiD; 22 | output reg [1:0] resultSrcD, jumpD, ALUOp; 23 | output reg [2:0] branchD, immSrcD; 24 | 25 | always @(op, func3) begin 26 | {ALUOp, regWriteD, immSrcD, ALUSrcD, memWriteD, 27 | resultSrcD, jumpD, ALUOp, branchD, immSrcD, luiD} <= 16'b0; 28 | case (op) 29 | `R_T: begin 30 | ALUOp <= 2'b10; 31 | regWriteD <= 1'b1; 32 | end 33 | 34 | `I_T: begin 35 | ALUOp <= 2'b11; 36 | regWriteD <= 1'b1; 37 | immSrcD <= 3'b000; 38 | ALUSrcD <= 1'b1; 39 | resultSrcD <= 2'b00; 40 | end 41 | 42 | `S_T: begin 43 | ALUOp <= 2'b00; 44 | memWriteD <= 1'b1; 45 | immSrcD <= 3'b001; 46 | ALUSrcD <= 1'b1; 47 | end 48 | 49 | `B_T: begin 50 | ALUOp <= 2'b01; 51 | immSrcD <= 3'b010; 52 | case (func3) 53 | `BEQ : branchD <= 3'b001; 54 | `BNE : branchD <= 3'b010; 55 | `BLT : branchD <= 3'b011; 56 | `BGE : branchD <= 3'b100; 57 | default: branchD <= 3'b000; 58 | endcase 59 | end 60 | 61 | `U_T: begin 62 | resultSrcD <= 2'b11; 63 | immSrcD <= 3'b100; 64 | regWriteD <= 1'b1; 65 | luiD <= 1'b1; 66 | end 67 | 68 | `J_T: begin 69 | resultSrcD <= 2'b10; 70 | immSrcD <= 3'b011; 71 | jumpD <= 2'b01; 72 | regWriteD <= 1'b1; 73 | end 74 | 75 | `LW_T: begin 76 | ALUOp <= 2'b00; 77 | regWriteD <= 1'b1; 78 | immSrcD <= 3'b000; 79 | ALUSrcD <= 1'b1; 80 | resultSrcD <= 2'b01; 81 | end 82 | 83 | `JALR_T: begin 84 | ALUOp <= 2'b00; 85 | regWriteD <= 1'b1; 86 | immSrcD <= 3'b000; 87 | ALUSrcD <= 1'b1; 88 | jumpD <= 2'b10; 89 | resultSrcD <= 2'b10; 90 | end 91 | 92 | default: begin 93 | regWriteD <= 1'b0; 94 | ALUSrcD <= 2'b00; 95 | ALUOp <= 3'b000; 96 | end 97 | 98 | endcase 99 | end 100 | 101 | endmodule 102 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/Mux2to1.v: -------------------------------------------------------------------------------- 1 | module Mux2to1(slc, a, b, w); 2 | parameter N = 32; 3 | 4 | input slc; 5 | input [N-1:0] a, b; 6 | 7 | output [N-1:0] w; 8 | 9 | assign w = ~slc ? a : b; 10 | 11 | endmodule -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/Mux4to1.v: -------------------------------------------------------------------------------- 1 | module Mux4to1(slc, a, b, c, d, w); 2 | parameter N = 32; 3 | 4 | input [1:0] slc; 5 | input [N-1:0] a, b, c, d; 6 | 7 | output reg [N-1:0] w; 8 | 9 | always @(a or b or c or d or slc) begin 10 | case (slc) 11 | 2'b00 : w <= a; 12 | 2'b01 : w <= b; 13 | 2'b10 : w <= c; 14 | 2'b11 : w <= d; 15 | default: w <= {N{1'bz}}; 16 | endcase 17 | end 18 | 19 | endmodule -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/RISC_V.v: -------------------------------------------------------------------------------- 1 | module RISC_V(clk, rst); 2 | input clk, rst; 3 | 4 | wire ALUSrcD, memWriteD, regWriteD, luiD, func7; 5 | wire [1:0] resultSrcD, jumpD; 6 | wire [2:0] immSrcD, branchD; 7 | wire [2:0] func3, ALUControlD; 8 | wire [6:0] op; 9 | 10 | RISC_V_Controller CU( 11 | .clk(clk), .rst(rst), .op(op), .func3(func3), 12 | .regWriteD(regWriteD), .resultSrcD(resultSrcD), 13 | .memWriteD(memWriteD), .ALUControlD(ALUControlD), 14 | .jumpD(jumpD), .branchD(branchD), .func7(func7), 15 | .ALUSrcD(ALUSrcD), .immSrcD(immSrcD), .luiD(luiD) 16 | ); 17 | 18 | RISC_V_Datapath DP( 19 | .clk(clk), .rst(rst), .regWriteD(regWriteD), 20 | .memWriteD(memWriteD), .jumpD(jumpD), .func3(func3), 21 | .branchD(branchD), .immSrcD(immSrcD), .luiD(luiD), 22 | .ALUControlD(ALUControlD), .ALUSrcD(ALUSrcD), 23 | .func7(func7), .resultSrcD(resultSrcD), .op(op) 24 | ); 25 | 26 | endmodule -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/RISC_V_Controller.v: -------------------------------------------------------------------------------- 1 | module RISC_V_Controller(clk, rst, op, func3, func7, 2 | regWriteD, resultSrcD, memWriteD, 3 | jumpD, branchD, ALUControlD, 4 | ALUSrcD, immSrcD, luiD); 5 | input [6:0] op; 6 | input [2:0] func3; 7 | input clk, rst, func7; 8 | 9 | output ALUSrcD, memWriteD, regWriteD, luiD; 10 | output [1:0] resultSrcD, jumpD; 11 | output [2:0] ALUControlD, immSrcD,branchD; 12 | 13 | wire [1:0] ALUOp; 14 | 15 | MainController maindecoder( 16 | .op(op), .func3(func3), .regWriteD(regWriteD), 17 | .resultSrcD(resultSrcD), .memWriteD(memWriteD), 18 | .jumpD(jumpD), .branchD(branchD), .ALUOp(ALUOp), 19 | .ALUSrcD(ALUSrcD), .immSrcD(immSrcD), .luiD(luiD) 20 | ); 21 | 22 | ALU_Controller ALUdecoder( 23 | .func3(func3), .func7(func7), .ALUOp(ALUOp), 24 | .ALUControl(ALUControlD) 25 | ); 26 | 27 | endmodule -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/RISC_V_Datapath.v: -------------------------------------------------------------------------------- 1 | module RISC_V_Datapath(clk, rst, regWriteD, resultSrcD, 2 | memWriteD, jumpD, branchD, 3 | ALUControlD, ALUSrcD, immSrcD, 4 | luiD, op, func3, func7); 5 | 6 | input clk, rst, regWriteD, memWriteD, ALUSrcD, luiD; 7 | input [1:0] resultSrcD, jumpD; 8 | input [2:0] ALUControlD, branchD, immSrcD; 9 | 10 | output [6:0] op; 11 | output [2:0] func3; 12 | output func7; 13 | 14 | wire regWriteW, regWriteM, memWriteM, luiE, 15 | luiM, regWriteE, 16 | ALUSrcE, memWriteE, flushE, zero, neg, 17 | stallF, stallD, flushD; 18 | 19 | wire [1:0] resultSrcW, resultSrcM, jumpE, 20 | PCSrcE, resultSrcE, forwardAE, forwardBE; 21 | wire [2:0] branchE, ALUControlE; 22 | wire [4:0] RdW, RdM, Rs1E, Rs2E, RdE, Rs1D, Rs2D, RdD; 23 | 24 | wire [31:0] ALUResultM, writeDataM, PCPlus4M, extImmM, RDM, 25 | resultW, extImmW, ALUResultW, PCPlus4W, RDW, 26 | RD1E, RD2E, PCE, SrcAE, SrcBE, writeDataE, 27 | PCTargetE, extImmE, PCPlus4E, ALUResultE, 28 | PCPlus4D, instrD, PCD, RD1D, RD2D, extImmD, 29 | PCF_Prime, PCF, instrF, PCPlus4F; 30 | 31 | // F 32 | Adder PCFAdder( 33 | .a(PCF), .b(32'd4), .w(PCPlus4F) 34 | ); 35 | 36 | Register PCreg( 37 | .in(PCF_Prime), .clk(clk), .en(~stallF), 38 | .rst(rst), .out(PCF) 39 | ); 40 | 41 | InstructionMemory IM( 42 | .pc(PCF), .instruction(instrF) 43 | ); 44 | 45 | Mux4to1 PCmux( 46 | .slc(PCSrcE), .a(PCPlus4F), .b(PCTargetE), 47 | .c(ALUResultE), .d(32'bz), .w(PCF_Prime) 48 | ); 49 | 50 | RegIF_ID regIFID( 51 | .clk(clk), .rst(rst), 52 | .en(~stallD), .clr(flushD), 53 | 54 | .PCF(PCF), .PCD(PCD), 55 | .PCPlus4F(PCPlus4F), .PCPlus4D(PCPlus4D), 56 | .instrF(instrF), .instrD(instrD) 57 | ); 58 | // end F 59 | 60 | // D 61 | RegisterFile RF( 62 | .clk(clk), .regWrite(regWriteW), 63 | .writeRegister(RdW), 64 | .writeData(resultW), 65 | .readData1(RD1D), .readData2(RD2D), 66 | .readRegister1(instrD[19:15]), 67 | .readRegister2(instrD[24:20]) 68 | ); 69 | 70 | ImmExtension Extend( 71 | .immSrc(immSrcD), .w(extImmD), 72 | .data(instrD[31:7]) 73 | ); 74 | 75 | ALU ALU_Instance( 76 | .ALUControl(ALUControlE), .a(SrcAE), .b(SrcBE), 77 | .zero(zero), .neg(neg), .w(ALUResultE) 78 | ); 79 | 80 | assign op = instrD[6:0]; 81 | assign RdD = instrD[11:7]; 82 | assign func3 = instrD[14:12]; 83 | assign Rs1D = instrD[19:15]; 84 | assign Rs2D = instrD[24:20]; 85 | assign func7 = instrD[30]; 86 | 87 | RegID_EX regIDEX( 88 | .clk(clk), .rst(rst), .clr(flushE), 89 | 90 | .regWriteD(regWriteD), .regWriteE(regWriteE), 91 | .PCD(PCD), .PCE(PCE), 92 | .Rs1D(Rs1D), .Rs1E(Rs1E), 93 | .Rs2D(Rs2D), .Rs2E(Rs2E), 94 | .RdD(RdD), .RdE(RdE), 95 | .RD1D(RD1D), .RD1E(RD1E), 96 | .RD2D(RD2D), .RD2E(RD2E), 97 | .resultSrcD(resultSrcD), .resultSrcE(resultSrcE), 98 | .memWriteD(memWriteD), .memWriteE(memWriteE), 99 | .jumpD(jumpD), .jumpE(jumpE), 100 | .branchD(branchD), .branchE(branchE), 101 | .ALUControlD(ALUControlD), .ALUControlE(ALUControlE), 102 | .ALUSrcD(ALUSrcD), .ALUSrcE(ALUSrcE), 103 | .extImmD(extImmD), .extImmE(extImmE), 104 | .luiD(luiD), .luiE(luiE), 105 | .PCPlus4D(PCPlus4D), .PCPlus4E(PCPlus4E) 106 | ); 107 | 108 | // end D 109 | 110 | // E 111 | Mux4to1 SrcAreg ( 112 | .slc(forwardAE), .a(RD1E), .b(resultW), .c(ALUResultM), .d(luiM), .w(SrcAE) 113 | ); 114 | 115 | Mux4to1 BSrcBreg( 116 | .slc(forwardBE), .a(RD2E), .b(resultW), .c(ALUResultM), .d(luiM), .w(writeDataE) 117 | ); 118 | 119 | Mux2to1 SrcBreg( 120 | .slc(ALUSrcE), .a(writeDataE), .b(extImmE), .w(SrcBE) 121 | ); 122 | 123 | Adder PCEAdder( 124 | .a(PCE), .b(extImmE), .w(PCTargetE) 125 | ); 126 | 127 | RegEX_MEM regEXMEM( 128 | .clk(clk), .rst(rst), 129 | 130 | .PCPlus4M(PCPlus4M), .PCPlus4E(PCPlus4E), 131 | .resultSrcE(resultSrcE), .resultSrcM(resultSrcM), 132 | .writeDataE(writeDataE), .writeDataM(writeDataM), 133 | .luiE(luiE), .luiM(luiM), 134 | .regWriteE(regWriteE), .regWriteM(regWriteM), 135 | .RdE(RdE), .RdM(RdM), 136 | .memWriteE(memWriteE), .memWriteM(memWriteM), 137 | .ALUResultE(ALUResultE), .ALUResultM(ALUResultM), 138 | .extImmE(extImmE), .extImmM(extImmM) 139 | ); 140 | // end E 141 | 142 | // M 143 | DataMemory DM( 144 | .memAdr(ALUResultM), .writeData(writeDataM), 145 | .memWrite(memWriteM), .clk(clk), .readData(RDM) 146 | ); 147 | 148 | RegMEM_WB regMEMWB( 149 | .clk(clk), .rst(rst), 150 | 151 | .regWriteM(regWriteM), .regWriteW(regWriteW), 152 | .ALUResultM(ALUResultM), .ALUResultW(ALUResultW), 153 | .RDM(RDM), .RDW(RDW), 154 | .RdM(RdM), .RdW(RdW), 155 | .resultSrcM(resultSrcM), .resultSrcW(resultSrcW), 156 | .PCPlus4M(PCPlus4M), .PCPlus4W(PCPlus4W), 157 | .extImmM(extImmM), .extImmW(extImmW) 158 | ); 159 | // end M 160 | 161 | // W 162 | Mux4to1 resMux( 163 | .slc(resultSrcW), .a(ALUResultW), .b(RDW), 164 | .c(PCPlus4W), .d(extImmW), .w(resultW) 165 | ); 166 | // end W 167 | 168 | HazardUnit hazard( 169 | .Rs1D(Rs1D), .Rs2D(Rs2D), 170 | .Rs1E(Rs1E), .Rs2E(Rs2E), 171 | .RdE(RdE), .RdM(RdM), .RdW(RdW), .luiM(luiM) 172 | .PCSrcE(PCSrcE), .resultSrc0(resultSrcE[0]), 173 | .regWriteW(regWriteW), .regWriteM(regWriteM), 174 | .stallD(stallD), .stallF(stallF), 175 | .flushD(flushD), .flushE(flushE), 176 | .forwardAE(forwardAE), .forwardBE(forwardBE) 177 | ); 178 | 179 | BranchController JBprosecc( 180 | .branchE(branchE), .jumpE(jumpE), .neg(neg), 181 | .zero(zero), .PCSrcE(PCSrcE) 182 | ); 183 | 184 | endmodule -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/RegEX_Mem.v: -------------------------------------------------------------------------------- 1 | module RegEX_MEM(clk, rst, regWriteE, resultSrcE, memWriteE, 2 | ALUResultE, writeDataE, RdE, PCPlus4E, luiE, extImmE, 3 | regWriteM, resultSrcM, memWriteM, ALUResultM, 4 | writeDataM, RdM, PCPlus4M, luiM,extImmM); 5 | 6 | input clk, rst, memWriteE, regWriteE, luiE; 7 | input [1:0] resultSrcE; 8 | input [4:0] RdE; 9 | input [31:0] ALUResultE, writeDataE, PCPlus4E, extImmE; 10 | 11 | output reg memWriteM, regWriteM , luiM; 12 | output reg [1:0] resultSrcM; 13 | output reg [4:0] RdM; 14 | output reg [31:0] ALUResultM, writeDataM, PCPlus4M, extImmM; 15 | 16 | always @(posedge clk or posedge rst) begin 17 | 18 | if (rst) begin 19 | ALUResultM <= 32'b0; 20 | writeDataM <= 32'b0; 21 | PCPlus4M <= 32'b0; 22 | extImmM <= 32'b0; 23 | RdM <= 5'b0; 24 | memWriteM <= 1'b0; 25 | regWriteM <= 1'b0; 26 | resultSrcM <= 2'b0; 27 | luiM <= 1'b0; 28 | end 29 | 30 | else begin 31 | ALUResultM <= ALUResultE; 32 | writeDataM <= writeDataE; 33 | PCPlus4M <= PCPlus4E; 34 | RdM <= RdE; 35 | memWriteM <= memWriteE; 36 | regWriteM <= regWriteE; 37 | resultSrcM <= resultSrcE; 38 | luiM <= luiE; 39 | extImmM <= extImmE; 40 | end 41 | 42 | end 43 | 44 | endmodule 45 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/RegID_EX.v: -------------------------------------------------------------------------------- 1 | module RegID_EX(clk, rst, clr, regWriteD, resultSrcD, memWriteD, jumpD, 2 | branchD, ALUControlD, ALUSrcD, RD1D, RD2D, PCD,Rs1D, 3 | Rs2D,RdD, extImmD,PCPlus4D, luiD, 4 | regWriteE, ALUSrcE, memWriteE, jumpE, luiE, 5 | branchE, ALUControlE, resultSrcE, RD1E, RD2E, PCE,Rs1E, 6 | Rs2E,RdE, extImmE,PCPlus4E); 7 | 8 | input clk, rst, clr, ALUSrcD, luiD, regWriteD, memWriteD; 9 | input [31:0] RD1D, RD2D, PCD; 10 | input [31:0] PCPlus4D, extImmD; 11 | input [4:0] Rs1D, Rs2D,RdD; 12 | input [2:0] branchD, ALUControlD; 13 | input [1:0] jumpD, resultSrcD; 14 | output reg ALUSrcE ,luiE, regWriteE, memWriteE; 15 | output reg [31:0] RD1E, RD2E, PCE; 16 | output reg [31:0] PCPlus4E, extImmE; 17 | output reg [4:0] Rs1E, Rs2E,RdE; 18 | output reg [2:0] branchE, ALUControlE; 19 | output reg [1:0] jumpE, resultSrcE; 20 | 21 | always @(posedge clk or posedge rst) begin 22 | if (rst || clr) begin 23 | regWriteE <= 1'b0; 24 | memWriteE <= 1'b0; 25 | ALUControlE <= 3'b000; 26 | RD1E <= 32'b0; 27 | RD2E <= 32'b0; 28 | PCE <= 32'b0; 29 | PCPlus4E <= 32'b0; 30 | extImmE <= 32'b0; 31 | Rs1E <= 5'b0; 32 | Rs2E <= 5'b0; 33 | RdE <= 5'b0; 34 | branchE <= 3'b0; 35 | jumpE <= 2'b0; 36 | ALUSrcE <= 1'b0; 37 | resultSrcE <= 2'b00; 38 | luiE <= 1'b0; 39 | end 40 | else begin 41 | regWriteE <= regWriteD; 42 | memWriteE <= memWriteD; 43 | ALUControlE <= ALUControlD; 44 | RD1E <= RD1D; 45 | RD2E <= RD2D; 46 | PCE <= PCD; 47 | PCPlus4E <= PCPlus4D; 48 | extImmE <= extImmD; 49 | Rs1E <= Rs1D; 50 | Rs2E <= Rs2D; 51 | RdE <= RdD; 52 | branchE <= branchD; 53 | jumpE <= jumpD; 54 | ALUSrcE <= ALUSrcD; 55 | resultSrcE <= resultSrcD; 56 | luiE <= luiD; 57 | end 58 | end 59 | 60 | endmodule 61 | 62 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/RegIF_ID.v: -------------------------------------------------------------------------------- 1 | module RegIF_ID(clk, rst, en, clr, instrF, PCF, 2 | PCPlus4F, PCPlus4D, 3 | instrD, PCD); 4 | 5 | input clk, rst, clr, en; 6 | input [31:0] instrF, PCF, PCPlus4F; 7 | 8 | output reg [31:0] instrD, PCD, PCPlus4D; 9 | 10 | always @(posedge clk or posedge rst) begin 11 | 12 | if(rst || clr) begin 13 | instrD <= 32'b0; 14 | PCD <= 32'b0; 15 | PCPlus4D <= 3'b0; 16 | end 17 | 18 | else if(en) begin 19 | instrD <= instrF; 20 | PCD <= PCF; 21 | PCPlus4D <= PCPlus4F; 22 | end 23 | 24 | end 25 | 26 | endmodule 27 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/RegMEM_WB.v: -------------------------------------------------------------------------------- 1 | module RegMEM_WB(clk, rst, regWriteM, resultSrcM, 2 | ALUResultM, RDM, RdM, PCPlus4M, 3 | extImmM, extImmW, regWriteW, resultSrcW, 4 | ALUResultW, RDW, RdW, PCPlus4W); 5 | 6 | input clk, rst, regWriteM; 7 | input [1:0] resultSrcM; 8 | input [4:0] RdM; 9 | input [31:0] ALUResultM, RDM, PCPlus4M, extImmM; 10 | 11 | output reg regWriteW; 12 | output reg [1:0] resultSrcW; 13 | output reg [4:0] RdW; 14 | output reg [31:0] ALUResultW, RDW, PCPlus4W, extImmW; 15 | 16 | always @(posedge clk or posedge rst) begin 17 | 18 | if (rst) begin 19 | regWriteW <= 32'b0; 20 | ALUResultW <= 32'b0; 21 | PCPlus4W <= 32'b0; 22 | RDW <= 32'b0; 23 | RdW <= 5'b0; 24 | resultSrcW <= 2'b0; 25 | extImmW <= 32'b0; 26 | end 27 | 28 | else begin 29 | regWriteW <= regWriteM; 30 | ALUResultW <= ALUResultM; 31 | PCPlus4W <= PCPlus4M; 32 | RDW <= RDM; 33 | RdW <= RdM; 34 | resultSrcW <= resultSrcM; 35 | extImmW <= extImmM; 36 | end 37 | 38 | end 39 | 40 | endmodule 41 | 42 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/Register.v: -------------------------------------------------------------------------------- 1 | module Register(in, clk, en, rst, out); 2 | parameter N = 32; 3 | 4 | input [N-1:0] in; 5 | input clk, rst, en; 6 | 7 | output reg [N-1:0] out; 8 | 9 | always @(posedge clk or posedge rst) begin 10 | if(rst) 11 | out <= {N{1'b0}}; 12 | else if(en) 13 | out <= in; 14 | end 15 | 16 | endmodule -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/RegisterFile.v: -------------------------------------------------------------------------------- 1 | `define BITS(x) $rtoi($ceil($clog2(x))) 2 | 3 | module RegisterFile(clk, regWrite, 4 | readRegister1, readRegister2, 5 | writeRegister, writeData, 6 | readData1, readData2); 7 | 8 | parameter WordLen = 32; 9 | parameter WordCount = 32; 10 | 11 | input regWrite, clk; 12 | input [`BITS(WordCount)-1:0] readRegister1, readRegister2, writeRegister; 13 | input [WordLen-1:0] writeData; 14 | 15 | output reg [WordLen-1:0] readData1, readData2; 16 | 17 | reg [WordLen-1:0] registerFile [0:WordCount-1]; 18 | 19 | initial 20 | registerFile[0] = 32'd0; 21 | 22 | always @(negedge clk) begin 23 | if (regWrite & (|writeRegister)) 24 | registerFile[writeRegister] <= writeData; 25 | end 26 | 27 | always @(negedge clk) begin 28 | readData1 <= registerFile[readRegister1]; 29 | readData2 <= registerFile[readRegister2]; 30 | end 31 | 32 | endmodule 33 | 34 | -------------------------------------------------------------------------------- /4 - RISC-V Pipeline/code/TestBench.v: -------------------------------------------------------------------------------- 1 | module TB(); 2 | reg clk, rst; 3 | RISC_V risc_v(.clk(clk), .rst(rst)); 4 | always #5 clk = ~clk; 5 | 6 | initial begin 7 | clk = 1'b0; 8 | #2 rst = 1'b1; 9 | #6 rst = 1'b0; 10 | #4000 $stop; 11 | end 12 | 13 | endmodule -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Shahriar Attar and Elahe Khodaverdi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Computer Architecture Course Projects 2 | Projects for the computer architecture course at Tehran university. 3 | 4 | - [Computer Architecture Course Projects](#computer-architecture-course-projects) 5 | - [Intro](#intro) 6 | - [CA 1: Maze](#ca-1-maze) 7 | - [Maze Intro](#maze-intro) 8 | - [Maze Asset](#maze-asset) 9 | - [Maze code](#maze-code) 10 | - [CA 2-4: RISC-V](#ca-2-4-risc-v) 11 | - [RISC-V Intro](#risc-v--intro) 12 | - [RISC-V Assets](#risc-v-assets) 13 | - [RISC-V code](#risc-v-code) 14 | 15 | ## Intro 16 | 17 | Projects for the computer architecture course at Tehran university. Some parts were inspired by last semester projects that you can find [here](https://github.com/MisaghM/Computer-Architecture-Course-Projects), the archive folder is linked to that repository. 18 | 19 | ## CA 1: Maze 20 | 21 | ### Maze Intro 22 | In this project we read maze data from a file and then try to find a way from our mouse to the cheese. the priority for moving is up, right, left, down so the route we find is unique. 23 | 24 | ### Maze Asset 25 | 26 | - `utils`: Some useful python code for generating map and also checking accuracy of project and visualizing the path 27 | - `maps` : List of maps, in each file if you convert the 4 digit hex string to binary format, each **1** represent wall and each **0** shows empty cells that we can move between those. There is 16 lines each 4 digit hex, so the map is 16 * 16. 28 | - `maps with solution` : in this folder we have maps that there exists a way to get the cheese. `.dat` file are original map, `.txt` file contains binary converted map, and $result_{i}.txt$ are python code's results, and the $code result_{i}.txt$ file contains Verilog simulation results. result means the way we move in maze. you can understand it with this map. 29 | 30 | ```text 31 | 00 up 32 | 01 right 33 | 10 left 34 | 11 down 35 | ``` 36 | 37 | - `maps without solution` : in this folder we have maps that doesn't exist a way to get the cheese. 38 | - `photos` : contains datapath and controller designs 39 | 40 | ### Maze code 41 | 42 | Verilog files that you can use to simulate the project using ModelSim. When simulating make sure that a `.dat` file is in the project of ModelSim. 43 | 44 | --- 45 | 46 | ***The next three projects are different implementation of RISC-V*** 47 | ## CA 2-4: RISC-V 48 | ### RISC-V Intro 49 | In these projects we designed a RISC-V processor using Verilog but with different approaches. The first approach is to use a simple Single-Cycle model which is not very good when it comes to hardware-utilization. The second approach is to use a shorter cycle but multiple cycles (i.e. Multi-Cycles) so each command use as many cycles as it needs and we have better performance. The last is the Pipeline approach which combines some instructions and gave us the best performance. 50 | 51 | Supported commands are(for now): 52 | 53 | - R-Type: add, sub, and, or, slt 54 | - I-Type: lw, addi, xori, slti, jalr 55 | - S-Type: sw 56 | - J-Type: jal 57 | - B-Type: beq, bneq, blt, beg 58 | - U-Type: lui 59 | 60 | ### RISC-V Assets 61 | 62 | - `assembly` : Assembly code of RISC-V 63 | - `controller` and `datapath` : General design of RISC-V 64 | - `memory` : `data.mem` which shows the data storage and `instructions.mem` which have the instructions that our processor will execute. Note that for Multi-Cycles as shown in it's datapath, data memory and instruction memory are not apart so they are in `data.mem` 65 | - `utils`: Some utility functions 66 | - `assembler` : In this folder you can find a link to an online assembler and also an assembler that we designed for our processor, if you are familiar with python just run this 67 | 68 | ``` 69 | python main.py 70 | ``` 71 | if not just the `.bat` files, you can run each like this 72 | 73 | ``` 74 | ./bat_filename.bat 75 | ``` 76 | - `data generator` : Here you can generate data memory based on numbers you provided in `ArrayData.txt `in memory folder. 77 | 78 | ### RISC-V code 79 | 80 | Verilog files that you can use to simulate the project using ModelSim. When simulating make sure that a `.mem` files are in the project of ModelSim. 81 | --------------------------------------------------------------------------------