diff --git a/src/asm/addi.s b/src/asm/addi.s new file mode 100644 index 0000000..e7e1052 --- /dev/null +++ b/src/asm/addi.s @@ -0,0 +1,67 @@ +addi x1, x0, 5 # x01 = 5 +addi x2, x0, 5 # x02 = 5 +addi x3, x0, 5 # x03 = 5 +addi x4, x0, 5 # x04 = 5 +addi x5, x0, 5 # x05 = 5 +addi x6, x0, 5 # x06 = 5 +addi x7, x0, 5 # x07 = 5 +addi x8, x0, 5 # x08 = 5 +addi x9, x0, 5 # x09 = 5 +addi x10, x0, 5 # x10 = 5 +addi x11, x0, 5 # x11 = 5 +addi x12, x0, 5 # x12 = 5 +addi x13, x0, 5 # x13 = 5 +addi x14, x0, 5 # x14 = 5 +addi x15, x0, 5 # x15 = 5 +addi x16, x0, 5 # x16 = 5 +addi x17, x0, 5 # x17 = 5 +addi x18, x0, 5 # x18 = 5 +addi x19, x0, 5 # x19 = 5 +addi x20, x0, 5 # x20 = 5 +addi x21, x0, 5 # x21 = 5 +addi x22, x0, 5 # x22 = 5 +addi x23, x0, 5 # x23 = 5 +addi x24, x0, 5 # x24 = 5 +addi x25, x0, 5 # x25 = 5 +addi x26, x0, 5 # x26 = 5 +addi x27, x0, 5 # x27 = 5 +addi x28, x0, 5 # x28 = 5 +addi x29, x0, 5 # x29 = 5 +addi x30, x0, 5 # x30 = 5 +addi x31, x0, 5 # x31 = 5 +#TESTASSERTOUTPUT|---------------------------------------| +#TESTASSERTOUTPUT| Register File State :) | +#TESTASSERTOUTPUT|---------------------------------------| +#TESTASSERTOUTPUT| x00, zero = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x01, ra = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x02, sp = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x03, gp = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x04, tp = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x05, t0 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x06, t1 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x07, t2 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x08, s0 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x09, s1 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x10, a0 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x11, a1 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x12, a2 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x13, a3 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x14, a4 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x15, a5 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x16, a6 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x17, a7 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x18, s2 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x19, s3 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x20, s4 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x21, s5 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x22, s6 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x23, s7 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x24, s8 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x25, s9 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x26, s10 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x27, s11 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x28, t3 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x29, t4 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x30, t5 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x31, t6 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT|---------------------------------------| diff --git a/src/asm/ari.s b/src/asm/ari.s new file mode 100644 index 0000000..c0148ca --- /dev/null +++ b/src/asm/ari.s @@ -0,0 +1,147 @@ +addi x1, x0, -1 # x01 = -1 +addi x2, x0, 35 # x02 = 35 +jalr x27,x1,13 +xori x3, x2, 68 # x03 = 103 +ori x4, x2, 17 # x04 = 51 +andi x5, x2, 17 # x05 = 1 +slli x6, x1, 8 # x06 = -256 +srli x7, x3, 2 # x07 = 25 +srai x8, x6, 6 # x08 = -4 +slti x9, x1, 35 # x09 = 1 +sltiu x10, x1, 35 # x10 = 0 +add x11, x1, x1 # x11 = -2 +sub x12, x1, x1 # x12 = 0 +xor x13, x1, x12 # x13 = -1 +or x14, x2, x3 # x14 = 103 +and x15, x2, x3 # x15 = 35 +addi x16, x0, 4 # x16 = 4 +sll x17, x2, x16 # x17 = 560 +srl x18, x3, x16 # x18 = 6 +sra x19, x6, x16 # x19 = -16 +slt x20, x1, x2 # x20 = 1 +sltu x21, x1, x2 # x20 = 0 +loop_head: +beq x22, x2, loop_end +addi x22, x22, 1 +jal x28, loop_head +loop_end: +addi x29, x29, 420 +loop_head2: +addi x23, x23, -1 +bne x23, x8, loop_head2 +addi x30, x30, 69 +lw x31, 24(x0) #8426259 +sw x30, 760(x0) #69 +lw x26, 776(x19) #69 +sw x29, -16(x17) #420 +sb x16, 544(x0) #4 +lw x25, 544(x0) #260 +sh x31, 126(x29) #37651 +lw x24, 800(x6) #-1827471100 +#stage 2 testing, overwriting register file entries +lb x8, 803(x6) #-109 +lbu x9, 803(x6) #147 +lh x10, 802(x6) #-27885 +lhu x11, 802(x6) #37651 +# x12 should remain zero +blt x6, x5, add_one #test -256<1 +addi x12, x12, 1 #should not run +add_one: +bgeu x6, x5, add_two #test big_number>1 +addi x12, x12, 2 #should not run +add_two: +bltu x19, x23, add_four #test -16<-4 +addi x12, x12, 4 #should not run +add_four: +bge x19, x19, add_eight #test -16=-16 +addi x12, x12, 8 #should not run +add_eight: +bge x19, x8, add_sixteen #test -16>-109 +addi x12, x12, 16 #should not run +add_sixteen: +bltu x15, x14, add_more #test 35<103 +addi x12, x12, 32 #should not run +add_more: +auipc x21, 0 +auipc x22, 2048 #8388608+216=8388824 +lui x23, 42069 #172314624 +nop + +# LMAO I CREATED AN UNBOUNDED MEMORY READ BY RUNNING THE PC INTO THE SAVED DATA HAHAHAHA +# LMAO NOW I ENDED UP OVERWRITING AN INSTRUCTION WITH 69 OOPS + +#stage 1 testing +|---------------------------------------| +| Register File State | +|---------------------------------------| +| x00, zero = 0x00000000 ( 0)| +| x01, ra = 0xffffffff ( -1)| +| x02, sp = 0x00000023 ( 35)| +| x03, gp = 0x00000067 ( 103)| +| x04, tp = 0x00000033 ( 51)| +| x05, t0 = 0x00000001 ( 1)| +| x06, t1 = 0xffffff00 ( -256)| +| x07, t2 = 0x00000019 ( 25)| +| x08, s0 = 0xfffffffc ( -4)| +| x09, s1 = 0x00000001 ( 1)| +| x10, a0 = 0x00000000 ( 0)| +| x11, a1 = 0xfffffffe ( -2)| +| x12, a2 = 0x00000000 ( 0)| +| x13, a3 = 0xffffffff ( -1)| +| x14, a4 = 0x00000067 ( 103)| +| x15, a5 = 0x00000023 ( 35)| +| x16, a6 = 0x00000004 ( 4)| +| x17, a7 = 0x00000230 ( 560)| +| x18, s2 = 0x00000006 ( 6)| +| x19, s3 = 0xfffffff0 ( -16)| +| x20, s4 = 0x00000001 ( 1)| +| x21, s5 = 0x00000000 ( 0)| +| x22, s6 = 0x00000023 ( 35)| #35 times increment +| x23, s7 = 0xfffffffc ( -4)| #-4 times decrement +| x24, s8 = 0x93130104 (-1827471100)| #sh x31<<16 on top of 260 = -1827471100 +| x25, s9 = 0x00000104 ( 260)| #lw sw 420 then sb 4 so it's 260 +| x26, s10 = 0x00000045 ( 69)| #add 69 +| x27, s11 = 0x0000000c ( 12)| #jalr link 12 +| x28, t3 = 0x00000064 ( 100)| #jal link 100 +| x29, t4 = 0x000001a4 ( 420)| #add 420 +| x30, t5 = 0x00000045 ( 69)| #lw sw 69 +| x31, t6 = 0x00809313 ( 8426259)| #lw instruction 24 +|---------------------------------------| + +#stage 2 testing +|---------------------------------------| +| Register File State | +|---------------------------------------| +| x00, zero = 0x00000000 ( 0)| +| x01, ra = 0xffffffff ( -1)| +| x02, sp = 0x00000023 ( 35)| +| x03, gp = 0x00000067 ( 103)| +| x04, tp = 0x00000033 ( 51)| +| x05, t0 = 0x00000001 ( 1)| +| x06, t1 = 0xffffff00 ( -256)| +| x07, t2 = 0x00000019 ( 25)| +| x08, s0 = 0xffffff93 ( -109)| +| x09, s1 = 0x00000093 ( 147)| +| x10, a0 = 0xffff9313 ( -27885)| +| x11, a1 = 0x00009313 ( 37651)| +| x12, a2 = 0x00000000 ( 0)| +| x13, a3 = 0xffffffff ( -1)| +| x14, a4 = 0x00000067 ( 103)| +| x15, a5 = 0x00000023 ( 35)| +| x16, a6 = 0x00000004 ( 4)| +| x17, a7 = 0x00000230 ( 560)| +| x18, s2 = 0x00000006 ( 6)| +| x19, s3 = 0xfffffff0 ( -16)| +| x20, s4 = 0x00000001 ( 1)| +| x21, s5 = 0x000000d4 ( 212)| +| x22, s6 = 0x008000d8 ( 8388824)| +| x23, s7 = 0x0a455000 ( 172314624)| +| x24, s8 = 0x93130104 (-1827471100)| +| x25, s9 = 0x00000104 ( 260)| +| x26, s10 = 0x00000045 ( 69)| +| x27, s11 = 0x0000000c ( 12)| +| x28, t3 = 0x00000064 ( 100)| +| x29, t4 = 0x000001a4 ( 420)| +| x30, t5 = 0x00000045 ( 69)| +| x31, t6 = 0x00809313 ( 8426259)| +|---------------------------------------| \ No newline at end of file diff --git a/src/asm/beq.s b/src/asm/beq.s new file mode 100644 index 0000000..fa9fc60 --- /dev/null +++ b/src/asm/beq.s @@ -0,0 +1,9 @@ +addi x1, x0, 5 # x01 = 5 + +addi x8, x0, 0 # x08 = 0 +loop_head: +addi x8, x8, 1 # x08 ++ +beq x8, x1, loop_end +beq x0, x0, loop_head +loop_end: + # x08 = 5 \ No newline at end of file diff --git a/src/asm/out/addi.memh b/src/asm/out/addi.memh new file mode 100644 index 0000000..d603035 --- /dev/null +++ b/src/asm/out/addi.memh @@ -0,0 +1,31 @@ +00500093 // PC=0x0 line=1: addi x1, x0, 5 # x01 = 5 +00500113 // PC=0x4 line=2: addi x2, x0, 5 # x02 = 5 +00500193 // PC=0x8 line=3: addi x3, x0, 5 # x03 = 5 +00500213 // PC=0xc line=4: addi x4, x0, 5 # x04 = 5 +00500293 // PC=0x10 line=5: addi x5, x0, 5 # x05 = 5 +00500313 // PC=0x14 line=6: addi x6, x0, 5 # x06 = 5 +00500393 // PC=0x18 line=7: addi x7, x0, 5 # x07 = 5 +00500413 // PC=0x1c line=8: addi x8, x0, 5 # x08 = 5 +00500493 // PC=0x20 line=9: addi x9, x0, 5 # x09 = 5 +00500513 // PC=0x24 line=10: addi x10, x0, 5 # x10 = 5 +00500593 // PC=0x28 line=11: addi x11, x0, 5 # x11 = 5 +00500613 // PC=0x2c line=12: addi x12, x0, 5 # x12 = 5 +00500693 // PC=0x30 line=13: addi x13, x0, 5 # x13 = 5 +00500713 // PC=0x34 line=14: addi x14, x0, 5 # x14 = 5 +00500793 // PC=0x38 line=15: addi x15, x0, 5 # x15 = 5 +00500813 // PC=0x3c line=16: addi x16, x0, 5 # x16 = 5 +00500893 // PC=0x40 line=17: addi x17, x0, 5 # x17 = 5 +00500913 // PC=0x44 line=18: addi x18, x0, 5 # x18 = 5 +00500993 // PC=0x48 line=19: addi x19, x0, 5 # x19 = 5 +00500a13 // PC=0x4c line=20: addi x20, x0, 5 # x20 = 5 +00500a93 // PC=0x50 line=21: addi x21, x0, 5 # x21 = 5 +00500b13 // PC=0x54 line=22: addi x22, x0, 5 # x22 = 5 +00500b93 // PC=0x58 line=23: addi x23, x0, 5 # x23 = 5 +00500c13 // PC=0x5c line=24: addi x24, x0, 5 # x24 = 5 +00500c93 // PC=0x60 line=25: addi x25, x0, 5 # x25 = 5 +00500d13 // PC=0x64 line=26: addi x26, x0, 5 # x26 = 5 +00500d93 // PC=0x68 line=27: addi x27, x0, 5 # x27 = 5 +00500e13 // PC=0x6c line=28: addi x28, x0, 5 # x28 = 5 +00500e93 // PC=0x70 line=29: addi x29, x0, 5 # x29 = 5 +00500f13 // PC=0x74 line=30: addi x30, x0, 5 # x30 = 5 +00500f93 // PC=0x78 line=31: addi x31, x0, 5 # x31 = 5 diff --git a/src/asm/out/beq.memh b/src/asm/out/beq.memh new file mode 100644 index 0000000..aab6180 --- /dev/null +++ b/src/asm/out/beq.memh @@ -0,0 +1,5 @@ +00500093 // PC=0x0 line=1: addi x1, x0, 5 # x01 = 5 +00000413 // PC=0x4 line=3: addi x8, x0, 0 # x08 = 0 +00140413 // PC=0x8 line=5: addi x8, x8, 1 # x08 ++ +00140463 // PC=0xc line=6: beq x8, x1, loop_end +fe000ce3 // PC=0x10 line=7: beq x0, x0, loop_head diff --git a/src/asm/test/addi.result b/src/asm/test/addi.result new file mode 100644 index 0000000..b3b81fa --- /dev/null +++ b/src/asm/test/addi.result @@ -0,0 +1,50 @@ +Usage: + ./rv32_simulator +initial_memory=path/to/memh/file + Additional arguments: + +initial_memory=path/to/memh/file + Required: path to a memh file that containes the assembled binary to run. + +max_cycles=NUMBER_OF_CYCLES_TO_RUN + +wave_fn=path/to/wave/file + default is rv32_simulator.fst + +final_memory=path/to/memh/file + If provided, the final memory contents will be saved here. Use this to debug your store instructions. +WARNING: ./tests/provided/bytewise_distributed_ram.sv:58: $readmemh(../asm/out/addi.memh): Not enough words in the file for the requested range [0:1023]. +Running simulation of memory ../asm/out/addi.memh for up to 10000 cycles. Waves will be stored to rv32_simulator.fst. +FST info: dumpfile rv32_simulator.fst opened for output. +Ran 10000 cycles, finishing. +#TESTASSERTOUTPUT|---------------------------------------| +#TESTASSERTOUTPUT| Register File State :) | +#TESTASSERTOUTPUT|---------------------------------------| +#TESTASSERTOUTPUT| x00, zero = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x01, ra = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x02, sp = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x03, gp = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x04, tp = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x05, t0 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x06, t1 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x07, t2 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x08, s0 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x09, s1 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x10, a0 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x11, a1 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x12, a2 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x13, a3 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x14, a4 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x15, a5 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x16, a6 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x17, a7 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x18, s2 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x19, s3 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x20, s4 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x21, s5 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x22, s6 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x23, s7 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x24, s8 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x25, s9 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x26, s10 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x27, s11 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x28, t3 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x29, t4 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x30, t5 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x31, t6 = 0x00000005 ( 5)| +#TESTASSERTOUTPUT|---------------------------------------| diff --git a/src/asm/test/beq.result b/src/asm/test/beq.result new file mode 100644 index 0000000..dbdecc6 --- /dev/null +++ b/src/asm/test/beq.result @@ -0,0 +1,50 @@ +Usage: + ./rv32_simulator +initial_memory=path/to/memh/file + Additional arguments: + +initial_memory=path/to/memh/file + Required: path to a memh file that containes the assembled binary to run. + +max_cycles=NUMBER_OF_CYCLES_TO_RUN + +wave_fn=path/to/wave/file + default is rv32_simulator.fst + +final_memory=path/to/memh/file + If provided, the final memory contents will be saved here. Use this to debug your store instructions. +WARNING: ./tests/provided/bytewise_distributed_ram.sv:58: $readmemh(../asm/out/beq.memh): Not enough words in the file for the requested range [0:1023]. +Running simulation of memory ../asm/out/beq.memh for up to 10000 cycles. Waves will be stored to rv32_simulator.fst. +FST info: dumpfile rv32_simulator.fst opened for output. +Ran 10000 cycles, finishing. +#TESTASSERTOUTPUT|---------------------------------------| +#TESTASSERTOUTPUT| Register File State :) | +#TESTASSERTOUTPUT|---------------------------------------| +#TESTASSERTOUTPUT| x00, zero = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x01, ra = 0x00000005 ( 5)| +#TESTASSERTOUTPUT| x02, sp = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x03, gp = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x04, tp = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x05, t0 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x06, t1 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x07, t2 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x08, s0 = 0x00000008 ( 8)| +#TESTASSERTOUTPUT| x09, s1 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x10, a0 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x11, a1 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x12, a2 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x13, a3 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x14, a4 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x15, a5 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x16, a6 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x17, a7 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x18, s2 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x19, s3 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x20, s4 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x21, s5 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x22, s6 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x23, s7 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x24, s8 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x25, s9 = 0x00000008 ( 8)| +#TESTASSERTOUTPUT| x26, s10 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x27, s11 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x28, t3 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x29, t4 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x30, t5 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x31, t6 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT|---------------------------------------| diff --git a/src/components/Makefile b/src/components/Makefile index 44a6a4b..fe43de4 100644 --- a/src/components/Makefile +++ b/src/components/Makefile @@ -99,13 +99,13 @@ rv32_simulator: tests/provided/rv32_simulator.sv src/**/*.sv # Runs the assembled .memh files through the simulator and writes out the register file state %.result: %.memh rv32_simulator - ./rv32_simulator.bin +initial_memory=../asm/out/$< ${VVP_POST} 2>&1 | tee ../asm/test/$(basename $<).result + ./rv32_simulator.bin +max_cycles=10000 +initial_memory=../asm/out/$< ${VVP_POST} 2>&1 | tee ../asm/test/$(basename $<).result # Validates that the simulator output is as expected %.validate: %.result node ../asm/validate.js $(basename $<).s test/$< -test_rv32_all: itypes.validate irtypes.validate storeload.validate +test_rv32_all: itypes.validate irtypes.validate storeload.validate beq.validate # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Instruction Type Tests diff --git a/src/components/src/cpu/rv32i_multicycle_core.sv b/src/components/src/cpu/rv32i_multicycle_core.sv index 9934e0d..2acf38d 100644 --- a/src/components/src/cpu/rv32i_multicycle_core.sv +++ b/src/components/src/cpu/rv32i_multicycle_core.sv @@ -8,10 +8,10 @@ `include "memory_map.sv" module rv32i_multicycle_core( - clk, rst, ena, - mem_addr, mem_rd_data, mem_wr_data, mem_wr_ena, - mem_access, mem_exception, - PC, instructions_completed, instruction_done + clk, rst, ena, + mem_addr, mem_rd_data, mem_wr_data, mem_wr_ena, + mem_access, mem_exception, + PC, instructions_completed, instruction_done ); `define OP_IMMEDIATE_I_EXECUTE 7'b0010011 @@ -19,6 +19,10 @@ module rv32i_multicycle_core( `define OP_R_EXECUTE 7'b0110011 `define OP_I_STORE 7'b0100011 `define OP_BRANCH 7'b1100011 + `define OP_JAL 7'b1101111 + `define OP_JALR 7'b1100111 + `define OP_U_IPC 7'b0010111 + `define OP_U_LUI 7'b0110111 /* enum values assigned for debug purposes. Sync them with the gtkwave folder */ enum logic [3:0] { @@ -30,7 +34,8 @@ module rv32i_multicycle_core( S_EXECUTE_RI = 5, S_ALUWB = 6, S_MEMWRITE = 7, - S_BRANCH = 8 + S_BRANCH = 8, + S_JAL = 9 } state; /* ---------------------- Standard Control Signals ---------------------- */ @@ -53,8 +58,6 @@ module rv32i_multicycle_core( logic [4:0] rd, rs1, rs2; logic [31:0] extended_immediate; - enum logic[3:0] {rtype, itype, ltype, stype, btype, jtype} instruction_type; - always_comb op = IR[6:0]; always_comb funct3 = IR[14:12]; always_comb funct7 = IR[31:25]; @@ -62,19 +65,13 @@ module rv32i_multicycle_core( always_comb rs1 = IR[19:15]; always_comb rs2 = IR[24:20]; - always_comb begin : instruction_type_decoder - case(op) - `OP_I_LOAD: instruction_type = itype; - `OP_IMMEDIATE_I_EXECUTE: instruction_type = itype; - `OP_R_EXECUTE: instruction_type = rtype; - `OP_I_STORE: instruction_type = stype; - endcase - end - always_comb begin : extended_immediate_decoder - case(instruction_type) - itype: extended_immediate = {{20{IR[31]}}, IR[31:20]}; - stype: extended_immediate = {{20{IR[31]}}, IR[31:25], IR[11:7]}; + case(op) + `OP_IMMEDIATE_I_EXECUTE, `OP_I_LOAD: extended_immediate = {{20{IR[31]}}, IR[31:20]}; + `OP_I_STORE: extended_immediate = {{20{IR[31]}}, IR[31:25], IR[11:7]}; + `OP_BRANCH: extended_immediate = {{19{IR[31]}}, IR[31], IR[7], IR[30:25], IR[11:8], 1'b0}; + `OP_JAL, `OP_JALR: extended_immediate = {{11{IR[31]}}, IR[31], IR[19:12], IR[20], IR[30:21], 1'b0}; + `OP_U_IPC, `OP_U_LUI: extended_immediate = {IR[31:12], 12'b0}; endcase end /* -------------------------------------------------------------------------------------------------------------------*/ @@ -125,7 +122,7 @@ module rv32i_multicycle_core( /* ---------------------- Result SRC Signals ---------------------- */ - enum logic [1:0] {RESULT_SRC_ALU, RESULT_SRC_MEM_DATA, RESULT_SRC_ALU_LAST} result_src; + enum logic [1:0] {RESULT_SRC_ALU, RESULT_SRC_MEM_DATA, RESULT_SRC_ALU_LAST, RESULT_SRC_PC_NEXT_INSTRUCTION} result_src; logic [31:0] result; always_comb begin : result_signals @@ -133,6 +130,7 @@ module rv32i_multicycle_core( RESULT_SRC_ALU: result = alu_result; RESULT_SRC_MEM_DATA: result = mem_data; RESULT_SRC_ALU_LAST: result = alu_last; + RESULT_SRC_PC_NEXT_INSTRUCTION: result = PC_next_instruction; endcase end @@ -224,6 +222,7 @@ module rv32i_multicycle_core( alu_last_ena = 0; mem_data_ena = 0; mem_wr_ena = 0; + reg_write = 0; endtask /* -------------------------------------------------------------------------------------------------------------------*/ @@ -253,14 +252,6 @@ module rv32i_multicycle_core( PC_old_ena = 1; PC_next_instruction_ena = 1; end - // use the alu in this phase to compute jump target if needed - S_DECODE: begin - set_default; - alu_control = ALU_ADD; - alu_src_a = ALU_SRC_A_OLD_PC; - alu_src_b = ALU_SRC_B_IMM; - alu_last_ena = 1; - end // LOAD INSTRUCTION compute offset S_MEMADR: begin set_default; @@ -348,26 +339,80 @@ module rv32i_multicycle_core( end endcase end + + endcase + end + /* -------------------------------------------------------------------------------------------------------------------*/ + /* DATAPATH for RI (end) */ + /* -------------------------------------------------------------------------------------------------------------------*/ + + /* -------------------------------------------------------------------------------------------------------------------*/ + /* DATAPATH for ALU WB (begin) */ + /* -------------------------------------------------------------------------------------------------------------------*/ + always_comb begin: datapath_aluwb + case(state) S_ALUWB: begin set_default; - result_src = RESULT_SRC_ALU_LAST; reg_write = 1; PC_ena = 1; - pc_next_src = PC_NEXT_INSTRUCTION; + case(op) + `OP_R_EXECUTE, `OP_IMMEDIATE_I_EXECUTE: begin + result_src = RESULT_SRC_ALU_LAST; + pc_next_src = PC_NEXT_INSTRUCTION; + end + `OP_JAL: begin + result_src = RESULT_SRC_PC_NEXT_INSTRUCTION; + pc_next_src = PC_NEXT_JUMP; + end + `OP_JALR: begin + result_src = RESULT_SRC_PC_NEXT_INSTRUCTION; + pc_next_src = PC_NEXT_JUMP; + end + endcase end - endcase + endcase end /* -------------------------------------------------------------------------------------------------------------------*/ - /* DATAPATH for RI (end) */ + /* DATAPATH for ALU WB (end) */ /* -------------------------------------------------------------------------------------------------------------------*/ + /* -------------------------------------------------------------------------------------------------------------------*/ + /* DATAPATH for decode / branch target (begin) */ + /* -------------------------------------------------------------------------------------------------------------------*/ + always_comb begin: datapath_decode + case(state) + // use the alu in this phase to compute jump target if needed + S_DECODE: begin + set_default; + alu_control = ALU_ADD; + alu_last_ena = 1; + case(op) + `OP_BRANCH: begin + alu_src_a = ALU_SRC_A_OLD_PC; + alu_src_b = ALU_SRC_B_IMM; + end + `OP_JAL: begin + alu_src_a = ALU_SRC_A_OLD_PC; + alu_src_b = ALU_SRC_B_IMM; + end + `OP_JALR: begin + alu_src_a = ALU_SRC_A_RF; + alu_src_b = ALU_SRC_B_IMM; + end + endcase + end + endcase + end + /* -------------------------------------------------------------------------------------------------------------------*/ + /* DATAPATH for decode / branch target (end) */ + /* -------------------------------------------------------------------------------------------------------------------*/ /* -------------------------------------------------------------------------------------------------------------------*/ /* DATAPATH for branch (begin) */ /* -------------------------------------------------------------------------------------------------------------------*/ logic will_jump; always_comb begin: datapath_branch - case(op) + case(state) S_BRANCH: begin set_default; alu_src_a = ALU_SRC_A_RF; @@ -402,14 +447,18 @@ module rv32i_multicycle_core( will_jump = ~alu_result[0]; end endcase - end - endcase - case(will_jump) - 1'b1: begin - pc_next_src = PC_NEXT_JUMP; - result_src = RESULT_SRC_ALU_LAST; - end + PC_ena = 1; + case(will_jump) + 1'b0: begin + pc_next_src = PC_NEXT_INSTRUCTION; + end + 1'b1: begin + pc_next_src = PC_NEXT_JUMP; + end + endcase + end endcase + end /* -------------------------------------------------------------------------------------------------------------------*/ /* DATAPATH for branch (end) */ @@ -431,6 +480,8 @@ module rv32i_multicycle_core( `OP_IMMEDIATE_I_EXECUTE: state <= S_EXECUTE_RI; `OP_R_EXECUTE: state <= S_EXECUTE_RI; `OP_BRANCH: state <= S_BRANCH; + `OP_JAL: state <= S_ALUWB; + `OP_JALR: state <= S_ALUWB; endcase end S_EXECUTE_RI: state <= S_ALUWB; @@ -444,6 +495,7 @@ module rv32i_multicycle_core( S_MEMREAD: state <= S_MEMWB; S_MEMWB: state <= S_FETCH; S_MEMWRITE: state <= S_FETCH; + S_BRANCH: state <= S_FETCH; endcase end end