Adapted descriptions to improved Core DSL and regenerated code
This commit is contained in:
		| @@ -10,15 +10,14 @@ | ||||
| 					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||||
| 					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||||
| 					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||||
| 					<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||||
| 				</extensions> | ||||
| 			</storageModule> | ||||
| 			<storageModule moduleId="cdtBuildSystem" version="4.0.0"> | ||||
| 				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1751741082" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=" parent="cdt.managedbuild.config.gnu.exe.debug"> | ||||
| 				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1751741082" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=" parent="cdt.managedbuild.config.gnu.exe.debug"> | ||||
| 					<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1751741082." name="/" resourcePath=""> | ||||
| 						<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.1289745146" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug"> | ||||
| 							<targetPlatform binaryParser="org.eclipse.cdt.core.GNU_ELF;org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.exe.debug.1460698591" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/> | ||||
| 							<builder buildPath="/DBT-RISE-RISCV/build/{ConfigName}" id="de.marw.cdt.cmake.core.genmakebuilder.2061143699" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="CMake Builder (GNU Make)" parallelBuildOn="true" parallelizationNumber="optimal" superClass="de.marw.cdt.cmake.core.genmakebuilder"/> | ||||
| 							<builder buildPath="/DBT-RISE-RISCV/build/Debug" id="de.marw.cdt.cmake.core.genscriptbuilder.2135578907" keepEnvironmentInBuildfile="false" name="CMake Builder (portable)" parallelBuildOn="false" superClass="de.marw.cdt.cmake.core.genscriptbuilder"/> | ||||
| 							<tool id="cdt.managedbuild.tool.gnu.archiver.base.366643800" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> | ||||
| 							<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1510612390" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug"> | ||||
| 								<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1768317780" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/> | ||||
| @@ -46,7 +45,7 @@ | ||||
| 			</storageModule> | ||||
| 			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> | ||||
| 			<storageModule buildDir="build/${ConfigName}" moduleId="de.marw.cdt.cmake.core.settings"> | ||||
| 				<options clearCache="true"/> | ||||
| 				<options/> | ||||
| 				<linux command="cmake" generator="UnixMakefiles" use-default="true"> | ||||
| 					<defs> | ||||
| 						<def name="CMAKE_VERBOSE_MAKEFILE" type="BOOL" val="OFF"/> | ||||
|   | ||||
							
								
								
									
										2
									
								
								dbt-core
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								dbt-core
									
									
									
									
									
								
							 Submodule dbt-core updated: 393c374cac...23dbab0b76
									
								
							| @@ -1,108 +1,108 @@ | ||||
| import "RV32IBase.core_desc" | ||||
|  | ||||
| InsructionSet RV32A extends RV32IBase{ | ||||
| 	  | ||||
| 	address_spaces {  | ||||
| 		RES[8] | ||||
| 	} | ||||
| 	 | ||||
| 	instructions{ | ||||
| 		LR.W { | ||||
| 			encoding: b00010 | aq[0:0] | rl[0:0]  | b00000 | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d"; | ||||
| 			if(rd!=0){ | ||||
| 				val offs[XLEN] <= X[rs1]; | ||||
| 				X[rd]<= sext(MEM[offs]{32}, XLEN); | ||||
| 				RES[offs]{32}<=sext(-1, 32); | ||||
| 			} | ||||
| 		} | ||||
| 		SC.W { | ||||
| 			encoding: b00011 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 			val offs[XLEN] <= X[rs1]; | ||||
| 			val res1[32] <= RES[offs]{32}; | ||||
| 			if(res1!=0) | ||||
| 				MEM[offs]{32} <= X[rs2]; | ||||
| 			if(rd!=0) X[rd]<= choose(res1!=0, 0, 1); | ||||
| 		} | ||||
| 		AMOSWAP.W{ | ||||
| 			encoding: b00001 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | ||||
| 			val offs[XLEN]<=X[rs1]; | ||||
| 			if(rd!=0) X[rd]<=sext(MEM[offs]{32}); | ||||
| 			MEM[offs]{32}<=X[rs2]; | ||||
| 		} | ||||
| 		AMOADD.W{ | ||||
| 			encoding: b00000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | ||||
| 			val offs[XLEN]<=X[rs1]; | ||||
| 			val res1[XLEN] <= sext(MEM[offs]{32}); | ||||
| 			if(rd!=0) X[rd]<=res1; | ||||
| 			val res2[XLEN]<=res1 + X[rs2]; | ||||
| 			MEM[offs]{32}<=res2; | ||||
| 		} | ||||
| 		AMOXOR.W{ | ||||
| 			encoding: b00100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | ||||
| 			val offs[XLEN]<=X[rs1]; | ||||
| 			val res1[XLEN] <= sext(MEM[offs]{32}); | ||||
| 			if(rd!=0) X[rd]<=res1; | ||||
| 			val res2[XLEN]<=res1 ^ X[rs2]; | ||||
| 			MEM[offs]{32}<=res2; | ||||
| 		} | ||||
| 		AMOAND.W{ | ||||
| 			encoding: b01100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | ||||
| 			val offs[XLEN]<=X[rs1]; | ||||
| 			val res1[XLEN] <= sext(MEM[offs]{32}); | ||||
| 			if(rd!=0) X[rd]<=res1; | ||||
| 			val res2[XLEN] <=res1 & X[rs2]; | ||||
| 			MEM[offs]{32}<=res2; | ||||
| 		} | ||||
| 		AMOOR.W { | ||||
| 			encoding: b01000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | ||||
| 			val offs[XLEN]<=X[rs1]; | ||||
| 			val res1[XLEN] <= sext(MEM[offs]{32}); | ||||
| 			if(rd!=0) X[rd]<=res1; | ||||
| 			val res2[XLEN]<=res1 | X[rs2]; | ||||
| 			MEM[offs]{32}<=res2; | ||||
| 		} | ||||
| 		AMOMIN.W{ | ||||
| 			encoding: b10000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | ||||
| 			val offs[XLEN]<=X[rs1]; | ||||
| 			val res1[XLEN] <= sext(MEM[offs]{32}); | ||||
| 			if(rd!=0) X[rd]<=res1; | ||||
| 			val res2[XLEN]<= choose(res1's>X[rs2]s, X[rs2], res1); | ||||
| 			MEM[offs]{32}<=res2; | ||||
| 		} | ||||
| 		AMOMAX.W{ | ||||
| 			encoding: b10100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | ||||
| 			val offs[XLEN]<=X[rs1]; | ||||
| 			val res1[XLEN] <= sext(MEM[offs]{32}); | ||||
| 			if(rd!=0) X[rd]<=res1; | ||||
| 			val res2[XLEN]<= choose(res1's<X[rs2]s, X[rs2], res1); | ||||
| 			MEM[offs]{32}<=res2; | ||||
| 		} | ||||
| 		AMOMINU.W{ | ||||
| 			encoding: b11000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | ||||
| 			val offs[XLEN]<=X[rs1]; | ||||
| 			val res1[XLEN] <= zext(MEM[offs]{32}); | ||||
| 			if(rd!=0) X[rd]<=res1; | ||||
| 			val res2[XLEN]<= choose(res1>X[rs2], X[rs2], res1); | ||||
| 			MEM[offs]{32}<=res2; | ||||
| 		} | ||||
| 		AMOMAXU.W{ | ||||
| 			encoding: b11100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | ||||
| 			val offs[XLEN]<=X[rs1]; | ||||
| 			val res1[XLEN] <= zext(MEM[offs]{32}); | ||||
| 			if(rd!=0) X[rd]<=res1; | ||||
| 			val res2[XLEN]<= choose(res1'u<X[rs2]'u, X[rs2], res1); | ||||
| 			MEM[offs]{32}<=res2; | ||||
| 		} | ||||
| 	} | ||||
|       | ||||
|     address_spaces {  | ||||
|         RES[8] | ||||
|     } | ||||
|      | ||||
|     instructions{ | ||||
|         LR.W { | ||||
|             encoding: b00010 | aq[0:0] | rl[0:0]  | b00000 | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d"; | ||||
|             if(rd!=0){ | ||||
|                 val offs[XLEN] <= X[rs1]; | ||||
|                 X[rd]<= sext(MEM[offs]{32}, XLEN); | ||||
|                 RES[offs]{32}<=sext(-1, 32); | ||||
|             } | ||||
|         } | ||||
|         SC.W { | ||||
|             encoding: b00011 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             val offs[XLEN] <= X[rs1]; | ||||
|             val res1[32] <= RES[offs]{32}; | ||||
|             if(res1!=0) | ||||
|                 MEM[offs]{32} <= X[rs2]; | ||||
|             if(rd!=0) X[rd]<= choose(res1!=0, 0, 1); | ||||
|         } | ||||
|         AMOSWAP.W{ | ||||
|             encoding: b00001 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | ||||
|             val offs[XLEN]<=X[rs1]; | ||||
|             if(rd!=0) X[rd]<=sext(MEM[offs]{32}); | ||||
|             MEM[offs]{32}<=X[rs2]; | ||||
|         } | ||||
|         AMOADD.W{ | ||||
|             encoding: b00000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | ||||
|             val offs[XLEN]<=X[rs1]; | ||||
|             val res1[XLEN] <= sext(MEM[offs]{32}); | ||||
|             if(rd!=0) X[rd]<=res1; | ||||
|             val res2[XLEN]<=res1 + X[rs2]; | ||||
|             MEM[offs]{32}<=res2; | ||||
|         } | ||||
|         AMOXOR.W{ | ||||
|             encoding: b00100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | ||||
|             val offs[XLEN]<=X[rs1]; | ||||
|             val res1[XLEN] <= sext(MEM[offs]{32}); | ||||
|             if(rd!=0) X[rd]<=res1; | ||||
|             val res2[XLEN]<=res1 ^ X[rs2]; | ||||
|             MEM[offs]{32}<=res2; | ||||
|         } | ||||
|         AMOAND.W{ | ||||
|             encoding: b01100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | ||||
|             val offs[XLEN]<=X[rs1]; | ||||
|             val res1[XLEN] <= sext(MEM[offs]{32}); | ||||
|             if(rd!=0) X[rd]<=res1; | ||||
|             val res2[XLEN] <=res1 & X[rs2]; | ||||
|             MEM[offs]{32}<=res2; | ||||
|         } | ||||
|         AMOOR.W { | ||||
|             encoding: b01000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | ||||
|             val offs[XLEN]<=X[rs1]; | ||||
|             val res1[XLEN] <= sext(MEM[offs]{32}); | ||||
|             if(rd!=0) X[rd]<=res1; | ||||
|             val res2[XLEN]<=res1 | X[rs2]; | ||||
|             MEM[offs]{32}<=res2; | ||||
|         } | ||||
|         AMOMIN.W{ | ||||
|             encoding: b10000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | ||||
|             val offs[XLEN]<=X[rs1]; | ||||
|             val res1[XLEN] <= sext(MEM[offs]{32}); | ||||
|             if(rd!=0) X[rd]<=res1; | ||||
|             val res2[XLEN]<= choose(res1's>X[rs2]s, X[rs2], res1); | ||||
|             MEM[offs]{32}<=res2; | ||||
|         } | ||||
|         AMOMAX.W{ | ||||
|             encoding: b10100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | ||||
|             val offs[XLEN]<=X[rs1]; | ||||
|             val res1[XLEN] <= sext(MEM[offs]{32}); | ||||
|             if(rd!=0) X[rd]<=res1; | ||||
|             val res2[XLEN]<= choose(res1's<X[rs2]s, X[rs2], res1); | ||||
|             MEM[offs]{32}<=res2; | ||||
|         } | ||||
|         AMOMINU.W{ | ||||
|             encoding: b11000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | ||||
|             val offs[XLEN]<=X[rs1]; | ||||
|             val res1[XLEN] <= zext(MEM[offs]{32}); | ||||
|             if(rd!=0) X[rd]<=res1; | ||||
|             val res2[XLEN]<= choose(res1>X[rs2], X[rs2], res1); | ||||
|             MEM[offs]{32}<=res2; | ||||
|         } | ||||
|         AMOMAXU.W{ | ||||
|             encoding: b11100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | ||||
|             val offs[XLEN]<=X[rs1]; | ||||
|             val res1[XLEN] <= zext(MEM[offs]{32}); | ||||
|             if(rd!=0) X[rd]<=res1; | ||||
|             val res2[XLEN]<= choose(res1'u<X[rs2]'u, X[rs2], res1); | ||||
|             MEM[offs]{32}<=res2; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,17 +1,17 @@ | ||||
| import "RV32IBase.core_desc" | ||||
|  | ||||
| InsructionSet RV32IC { | ||||
| 	constants { | ||||
| 		XLEN | ||||
| 	} | ||||
| 	address_spaces {  | ||||
| 		MEM[8] | ||||
| 	} | ||||
| 	registers {  | ||||
| 		[31:0]   X[XLEN], | ||||
| 				PC[XLEN](is_pc) | ||||
| 	} | ||||
| 	instructions{ | ||||
|     constants { | ||||
|         XLEN | ||||
|     } | ||||
|     address_spaces {  | ||||
|         MEM[8] | ||||
|     } | ||||
|     registers {  | ||||
|         [31:0]   X[XLEN], | ||||
|                 PC[XLEN](is_pc) | ||||
|     } | ||||
|     instructions{ | ||||
|         JALR(no_cont){ // overwriting the implementation if rv32i, alignment does not need to be word | ||||
|             encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b1100111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, 0x%imm$x"; | ||||
| @@ -19,366 +19,337 @@ InsructionSet RV32IC { | ||||
|             val ret[XLEN] <= X[rs1]+ imm; | ||||
|             PC<=ret& ~0x1; | ||||
|         } | ||||
| 		C.ADDI4SPN { //(RES, imm=0) | ||||
| 			encoding: b000 | imm[5:4] | imm[9:6] | imm[2:2] | imm[3:3] | rd[2:0] | b00; | ||||
| 			args_disass: "x%rd$d, 0x%imm$05x"; | ||||
| 			if(imm == 0) raise(0, 2); | ||||
| 			val rd_idx[5] <= rd+8; | ||||
| 			val x2_idx[5] <= 2; | ||||
| 			X[rd_idx] <= X[x2_idx] + imm; | ||||
| 		} | ||||
| 		C.LW { // (RV32) | ||||
| 			encoding: b010 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rd[2:0] | b00; | ||||
| 			args_disass: "x(8+%rd$d), x(8+%rs1$d), 0x%uimm$05x"; | ||||
| 			val rs1_idx[5] <= rs1+8; | ||||
| 			val rd_idx[5] <= rd+8; | ||||
| 			val offs[XLEN] <= X[rs1_idx]+uimm; | ||||
| 			X[rd_idx] <= MEM[offs]{32}; | ||||
| 		} | ||||
| 		C.SW {//(RV32) | ||||
| 			encoding: b110 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rs2[2:0] | b00; | ||||
| 			args_disass: "x(8+%rs1$d), x(8+%rs2$d), 0x%uimm$05x"; | ||||
| 			val rs1_idx[5] <= rs1+8; | ||||
| 			val rs2_idx[5] <= rs2+8; | ||||
| 			val offs[XLEN] <= X[rs1_idx]+uimm; | ||||
| 			MEM[offs]{32} <= X[rs2_idx]; | ||||
| 		} | ||||
| 		C.ADDI {//(RV32) | ||||
| 			encoding:b000 | imm[5:5]s | rs1[4:0] | imm[4:0]s | b01; | ||||
| 			args_disass: "x%rs1$d, 0x%imm$05x"; | ||||
| 			X[rs1] <= X[rs1] + imm; | ||||
| 		} | ||||
| 		C.NOP { | ||||
| 			encoding:b000 | b0 | b00000 | b00000 | b01; | ||||
| 		} | ||||
|         C.ADDI4SPN { //(RES, imm=0) | ||||
|             encoding: b000 | imm[5:4] | imm[9:6] | imm[2:2] | imm[3:3] | rd[2:0] | b00; | ||||
|             args_disass: "x%rd$d, 0x%imm$05x"; | ||||
|             if(imm == 0) raise(0, 2); | ||||
|             X[rd+8] <= X[2] + imm; | ||||
|         } | ||||
|         C.LW { // (RV32) | ||||
|             encoding: b010 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rd[2:0] | b00; | ||||
|             args_disass: "x(8+%rd$d), x(8+%rs1$d), 0x%uimm$05x"; | ||||
|             val offs[XLEN] <= X[rs1+8]+uimm; | ||||
|             X[rd+8] <= MEM[offs]{32}; | ||||
|         } | ||||
|         C.SW {//(RV32) | ||||
|             encoding: b110 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rs2[2:0] | b00; | ||||
|             args_disass: "x(8+%rs1$d), x(8+%rs2$d), 0x%uimm$05x"; | ||||
|             val offs[XLEN] <= X[rs1+8]+uimm; | ||||
|             MEM[offs]{32} <= X[rs2+8]; | ||||
|         } | ||||
|         C.ADDI {//(RV32) | ||||
|             encoding:b000 | imm[5:5]s | rs1[4:0] | imm[4:0]s | b01; | ||||
|             args_disass: "x%rs1$d, 0x%imm$05x"; | ||||
|             X[rs1] <= X[rs1] + imm; | ||||
|         } | ||||
|         C.NOP { | ||||
|             encoding:b000 | b0 | b00000 | b00000 | b01; | ||||
|         } | ||||
|         // C.JAL will be overwritten by C.ADDIW for RV64/128 | ||||
| 		C.JAL(no_cont) {//(RV32) | ||||
| 			encoding: b001 | imm[11:11]s | imm[4:4]s | imm[9:8]s | imm[10:10]s | imm[6:6]s | imm[7:7]s | imm[3:1]s | imm[5:5]s | b01; | ||||
| 			args_disass: "0x%imm$05x"; | ||||
| 			val rd[5] <= 1; | ||||
| 			X[rd] <= PC+2; | ||||
| 			PC<=PC+imm; | ||||
| 		} | ||||
| 		C.LI {//(RV32) | ||||
| 			encoding:b010 | imm[5:5]s | rd[4:0] | imm[4:0]s | b01; | ||||
| 			args_disass: "x%rd$d, 0x%imm$05x"; | ||||
| 			if(rd == 0)	raise(0, 2);   //TODO: should it be handled as trap? | ||||
| 			X[rd] <= imm; | ||||
| 		} | ||||
| 		// order matters here as C.ADDI16SP overwrites C.LUI vor rd==2 | ||||
| 		C.LUI {//(RV32) | ||||
| 			encoding:b011 | imm[17:17]s | rd[4:0] | imm[16:12]s | b01; | ||||
| 			args_disass: "x%rd$d, 0x%imm$05x"; | ||||
| 			if(rd == 0) raise(0, 2);   //TODO: should it be handled as trap? | ||||
| 			if(imm == 0) raise(0, 2);   //TODO: should it be handled as trap? | ||||
| 			X[rd] <= imm; | ||||
| 		} | ||||
| 		C.ADDI16SP {//(RV32) | ||||
| 			encoding:b011 | imm[9:9]s | b00010 | imm[4:4]s | imm[6:6]s | imm[8:7]s | imm[5:5]s | b01; | ||||
| 			args_disass: "0x%imm$05x"; | ||||
| 			val x2_idx[5] <= 2; | ||||
| 			X[x2_idx] <= X[x2_idx]s + imm; | ||||
| 		} | ||||
| 		C.SRLI {//(RV32 nse) | ||||
| 			encoding:b100 | b0 | b00 | rs1[2:0] | shamt[4:0] | b01; | ||||
| 			args_disass: "x(8+%rs1$d), %shamt$d"; | ||||
| 			val rs1_idx[5] <= rs1+8; | ||||
| 			X[rs1_idx] <= shrl(X[rs1_idx], shamt); | ||||
| 		} | ||||
| 		C.SRAI {//(RV32) | ||||
| 			encoding:b100 | b0 | b01 | rs1[2:0] | shamt[4:0] | b01; | ||||
| 			args_disass: "x(8+%rs1$d), %shamt$d"; | ||||
| 			val rs1_idx[5] <= rs1+8; | ||||
| 			X[rs1_idx] <= shra(X[rs1_idx], shamt); | ||||
| 		} | ||||
| 		C.ANDI {//(RV32) | ||||
| 			encoding:b100 | imm[5:5]s | b10 | rs1[2:0] | imm[4:0]s | b01; | ||||
| 			args_disass: "x(8+%rs1$d), 0x%imm$05x"; | ||||
| 			val rs1_idx[5] <= rs1 + 8; | ||||
| 			X[rs1_idx] <= X[rs1_idx] & imm; | ||||
| 		} | ||||
| 		C.SUB {//(RV32) | ||||
| 			encoding:b100 | b0 | b11 | rd[2:0] | b00 | rs2[2:0] | b01; | ||||
| 			args_disass: "x(8+%rd$d), x(8+%rs2$d)"; | ||||
| 			val rd_idx[5] <= rd + 8; | ||||
| 			val rs2_idx[5] <= rs2 + 8; | ||||
| 			X[rd_idx] <= X[rd_idx] - X[rs2_idx]; | ||||
| 		} | ||||
| 		C.XOR {//(RV32) | ||||
| 			encoding:b100 | b0 | b11 | rd[2:0] | b01 | rs2[2:0] | b01; | ||||
| 			args_disass: "x(8+%rd$d), x(8+%rs2$d)"; | ||||
| 			val rd_idx[5] <= rd + 8; | ||||
| 			val rs2_idx[5] <= rs2 + 8; | ||||
| 			X[rd_idx] <= X[rd_idx] ^ X[rs2_idx]; | ||||
| 		} | ||||
| 		C.OR {//(RV32) | ||||
| 			encoding:b100 | b0 | b11 | rd[2:0] | b10 | rs2[2:0] | b01; | ||||
| 			args_disass: "x(8+%rd$d), x(8+%rs2$d)"; | ||||
| 			val rd_idx[5] <= rd + 8; | ||||
| 			val rs2_idx[5] <= rs2 + 8; | ||||
| 			X[rd_idx] <= X[rd_idx] | X[rs2_idx]; | ||||
| 		} | ||||
| 		C.AND {//(RV32) | ||||
| 			encoding:b100 | b0 | b11 | rd[2:0] | b11 | rs2[2:0] | b01; | ||||
| 			args_disass: "x(8+%rd$d), x(8+%rs2$d)"; | ||||
| 			val rd_idx[5] <= rd + 8; | ||||
| 			val rs2_idx[5] <= rs2 + 8; | ||||
| 			X[rd_idx] <= X[rd_idx] & X[rs2_idx]; | ||||
| 		} | ||||
| 		C.J(no_cont) {//(RV32) | ||||
| 			encoding:b101 | imm[11:11]s | imm[4:4]s | imm[9:8]s | imm[10:10]s | imm[6:6]s | imm[7:7]s | imm[3:1]s | imm[5:5]s | b01; | ||||
| 			args_disass: "0x%imm$05x"; | ||||
| 			PC<=PC+imm; | ||||
| 		} | ||||
| 		C.BEQZ(no_cont,cond) {//(RV32) | ||||
| 			encoding:b110 | imm[8:8]s | imm[4:3]s | rs1[2:0] | imm[7:6]s |imm[2:1]s | imm[5:5]s | b01; | ||||
| 			args_disass: "x(8+%rs1$d), 0x%imm$05x"; | ||||
| 			val rs1_idx[5] <= rs1+8; | ||||
| 			PC<=choose(X[rs1_idx]==0, PC+imm, PC+2); | ||||
| 		} | ||||
| 		C.BNEZ(no_cont,cond) {//(RV32) | ||||
| 			encoding:b111 | imm[8:8]s | imm[4:3]s | rs1[2:0] | imm[7:6]s | imm[2:1]s | imm[5:5]s | b01; | ||||
| 			args_disass: "x(8+%rs1$d), 0x%imm$05x"; | ||||
|         C.JAL(no_cont) {//(RV32) | ||||
|             encoding: b001 | imm[11:11]s | imm[4:4]s | imm[9:8]s | imm[10:10]s | imm[6:6]s | imm[7:7]s | imm[3:1]s | imm[5:5]s | b01; | ||||
|             args_disass: "0x%imm$05x"; | ||||
|             X[1] <= PC+2; | ||||
|             PC<=PC+imm; | ||||
|         } | ||||
|         C.LI {//(RV32) | ||||
|             encoding:b010 | imm[5:5]s | rd[4:0] | imm[4:0]s | b01; | ||||
|             args_disass: "x%rd$d, 0x%imm$05x"; | ||||
|             if(rd == 0)    raise(0, 2);   //TODO: should it be handled as trap? | ||||
|             X[rd] <= imm; | ||||
|         } | ||||
|         // order matters here as C.ADDI16SP overwrites C.LUI vor rd==2 | ||||
|         C.LUI {//(RV32) | ||||
|             encoding:b011 | imm[17:17]s | rd[4:0] | imm[16:12]s | b01; | ||||
|             args_disass: "x%rd$d, 0x%imm$05x"; | ||||
|             if(rd == 0) raise(0, 2);   //TODO: should it be handled as trap? | ||||
|             if(imm == 0) raise(0, 2);   //TODO: should it be handled as trap? | ||||
|             X[rd] <= imm; | ||||
|         } | ||||
|         C.ADDI16SP {//(RV32) | ||||
|             encoding:b011 | imm[9:9]s | b00010 | imm[4:4]s | imm[6:6]s | imm[8:7]s | imm[5:5]s | b01; | ||||
|             args_disass: "0x%imm$05x"; | ||||
|             X[2] <= X[2]s + imm; | ||||
|         } | ||||
|         C.SRLI {//(RV32 nse) | ||||
|             encoding:b100 | b0 | b00 | rs1[2:0] | shamt[4:0] | b01; | ||||
|             args_disass: "x(8+%rs1$d), %shamt$d"; | ||||
|             val rs1_idx[5] <= rs1+8; | ||||
| 			PC<=choose(X[rs1_idx]!=0, PC+imm, PC+2); | ||||
| 		} | ||||
| 		C.SLLI {//(RV32) | ||||
| 			encoding:b000 | b0 | rs1[4:0] | shamt[4:0] | b10; | ||||
| 			args_disass: "x%rs1$d, %shamt$d"; | ||||
| 			if(rs1 == 0) raise(0, 2); | ||||
| 			X[rs1] <= shll(X[rs1], shamt); | ||||
| 		} | ||||
| 		C.LWSP {// | ||||
| 			encoding:b010 | uimm[5:5] | rd[4:0] | uimm[4:2] | uimm[7:6] | b10; | ||||
| 			args_disass: "x%rd$d, sp, 0x%uimm$05x"; | ||||
| 			val x2_idx[5] <= 2; | ||||
| 			val offs[XLEN] <= X[x2_idx] + uimm; | ||||
| 			X[rd] <= MEM[offs]{32}; | ||||
| 		} | ||||
| 		// order matters as C.JR is a special case of C.MV | ||||
|             X[rs1_idx] <= shrl(X[rs1_idx], shamt); | ||||
|         } | ||||
|         C.SRAI {//(RV32) | ||||
|             encoding:b100 | b0 | b01 | rs1[2:0] | shamt[4:0] | b01; | ||||
|             args_disass: "x(8+%rs1$d), %shamt$d"; | ||||
|             val rs1_idx[5] <= rs1+8; | ||||
|             X[rs1_idx] <= shra(X[rs1_idx], shamt); | ||||
|         } | ||||
|         C.ANDI {//(RV32) | ||||
|             encoding:b100 | imm[5:5]s | b10 | rs1[2:0] | imm[4:0]s | b01; | ||||
|             args_disass: "x(8+%rs1$d), 0x%imm$05x"; | ||||
|             val rs1_idx[5] <= rs1 + 8; | ||||
|             X[rs1_idx] <= X[rs1_idx] & imm; | ||||
|         } | ||||
|         C.SUB {//(RV32) | ||||
|             encoding:b100 | b0 | b11 | rd[2:0] | b00 | rs2[2:0] | b01; | ||||
|             args_disass: "x(8+%rd$d), x(8+%rs2$d)"; | ||||
|             val rd_idx[5] <= rd + 8; | ||||
|             X[rd_idx] <= X[rd_idx] - X[rs2 + 8]; | ||||
|         } | ||||
|         C.XOR {//(RV32) | ||||
|             encoding:b100 | b0 | b11 | rd[2:0] | b01 | rs2[2:0] | b01; | ||||
|             args_disass: "x(8+%rd$d), x(8+%rs2$d)"; | ||||
|             val rd_idx[5] <= rd + 8; | ||||
|             X[rd_idx] <= X[rd_idx] ^ X[rs2 + 8]; | ||||
|         } | ||||
|         C.OR {//(RV32) | ||||
|             encoding:b100 | b0 | b11 | rd[2:0] | b10 | rs2[2:0] | b01; | ||||
|             args_disass: "x(8+%rd$d), x(8+%rs2$d)"; | ||||
|             val rd_idx[5] <= rd + 8; | ||||
|             X[rd_idx] <= X[rd_idx] | X[rs2 + 8]; | ||||
|         } | ||||
|         C.AND {//(RV32) | ||||
|             encoding:b100 | b0 | b11 | rd[2:0] | b11 | rs2[2:0] | b01; | ||||
|             args_disass: "x(8+%rd$d), x(8+%rs2$d)"; | ||||
|             val rd_idx[5] <= rd + 8; | ||||
|             X[rd_idx] <= X[rd_idx] & X[rs2 + 8]; | ||||
|         } | ||||
|         C.J(no_cont) {//(RV32) | ||||
|             encoding:b101 | imm[11:11]s | imm[4:4]s | imm[9:8]s | imm[10:10]s | imm[6:6]s | imm[7:7]s | imm[3:1]s | imm[5:5]s | b01; | ||||
|             args_disass: "0x%imm$05x"; | ||||
|             PC<=PC+imm; | ||||
|         } | ||||
|         C.BEQZ(no_cont,cond) {//(RV32) | ||||
|             encoding:b110 | imm[8:8]s | imm[4:3]s | rs1[2:0] | imm[7:6]s |imm[2:1]s | imm[5:5]s | b01; | ||||
|             args_disass: "x(8+%rs1$d), 0x%imm$05x"; | ||||
|             PC<=choose(X[rs1+8]==0, PC+imm, PC+2); | ||||
|         } | ||||
|         C.BNEZ(no_cont,cond) {//(RV32) | ||||
|             encoding:b111 | imm[8:8]s | imm[4:3]s | rs1[2:0] | imm[7:6]s | imm[2:1]s | imm[5:5]s | b01; | ||||
|             args_disass: "x(8+%rs1$d), 0x%imm$05x"; | ||||
|             PC<=choose(X[rs1+8]!=0, PC+imm, PC+2); | ||||
|         } | ||||
|         C.SLLI {//(RV32) | ||||
|             encoding:b000 | b0 | rs1[4:0] | shamt[4:0] | b10; | ||||
|             args_disass: "x%rs1$d, %shamt$d"; | ||||
|             if(rs1 == 0) raise(0, 2); | ||||
|             X[rs1] <= shll(X[rs1], shamt); | ||||
|         } | ||||
|         C.LWSP {// | ||||
|             encoding:b010 | uimm[5:5] | rd[4:0] | uimm[4:2] | uimm[7:6] | b10; | ||||
|             args_disass: "x%rd$d, sp, 0x%uimm$05x"; | ||||
|             val offs[XLEN] <= X[2] + uimm; | ||||
|             X[rd] <= MEM[offs]{32}; | ||||
|         } | ||||
|         // order matters as C.JR is a special case of C.MV | ||||
|         C.MV {//(RV32) | ||||
|             encoding:b100 | b0 | rd[4:0] | rs2[4:0] | b10; | ||||
|             args_disass: "x%rd$d, x%rs2$d"; | ||||
|             X[rd] <= X[rs2]; | ||||
|         } | ||||
| 		C.JR(no_cont) {//(RV32) | ||||
| 			encoding:b100 | b0 | rs1[4:0] | b00000 | b10; | ||||
| 			args_disass: "x%rs1$d"; | ||||
| 			PC <= X[rs1]; | ||||
| 		} | ||||
|         C.JR(no_cont) {//(RV32) | ||||
|             encoding:b100 | b0 | rs1[4:0] | b00000 | b10; | ||||
|             args_disass: "x%rs1$d"; | ||||
|             PC <= X[rs1]; | ||||
|         } | ||||
|         // order matters as C.EBREAK is a special case of C.JALR which is a special case of C.ADD | ||||
|         C.ADD {//(RV32) | ||||
|             encoding:b100 | b1 | rd[4:0] | rs2[4:0] | b10; | ||||
|             args_disass: "x%rd$d, x%rs2$d"; | ||||
|         	X[rd] <= X[rd] + X[rs2]; | ||||
|             X[rd] <= X[rd] + X[rs2]; | ||||
|         } | ||||
| 		C.JALR(no_cont) {//(RV32) | ||||
| 			encoding:b100 | b1 | rs1[4:0] | b00000 | b10; | ||||
| 			args_disass: "x%rs1$d"; | ||||
| 			val r_idx[5] <= 1; | ||||
| 			X[r_idx] <= PC+2; | ||||
| 			PC<=X[rs1]; | ||||
| 		} | ||||
| 		C.EBREAK(no_cont) {//(RV32) | ||||
| 			encoding:b100 | b1 | b00000 | b00000 | b10; | ||||
| 			raise(0, 3); | ||||
| 		} | ||||
| 		C.SWSP {// | ||||
| 			encoding:b110 | uimm[5:2] | uimm[7:6] | rs2[4:0] | b10; | ||||
|         C.JALR(no_cont) {//(RV32) | ||||
|             encoding:b100 | b1 | rs1[4:0] | b00000 | b10; | ||||
|             args_disass: "x%rs1$d"; | ||||
|             X[1] <= PC+2; | ||||
|             PC<=X[rs1]; | ||||
|         } | ||||
|         C.EBREAK(no_cont) {//(RV32) | ||||
|             encoding:b100 | b1 | b00000 | b00000 | b10; | ||||
|             raise(0, 3); | ||||
|         } | ||||
|         C.SWSP {// | ||||
|             encoding:b110 | uimm[5:2] | uimm[7:6] | rs2[4:0] | b10; | ||||
|             args_disass: "x2+0x%uimm$05x, x%rs2$d"; | ||||
|             val x2_idx[5] <= 2; | ||||
|             val offs[XLEN] <= X[x2_idx] + uimm; | ||||
|             val offs[XLEN] <= X[2] + uimm; | ||||
|             MEM[offs]{32} <= X[rs2]; | ||||
| 		} | ||||
| 		DII { | ||||
| 			encoding:b000 | b0 | b00000 | b00000 | b00; | ||||
| 			raise(0, 2); | ||||
| 		} | ||||
| 	} | ||||
|         } | ||||
|         DII { | ||||
|             encoding:b000 | b0 | b00000 | b00000 | b00; | ||||
|             raise(0, 2); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| InsructionSet RV32FC extends RV32IC{ | ||||
| 	constants { | ||||
| 		XLEN, FLEN | ||||
| 	} | ||||
| 	address_spaces {  | ||||
| 		MEM[8] | ||||
| 	} | ||||
| 	registers {  | ||||
| 		[31:0]   X[XLEN], | ||||
| 		[31:0]   F[FLEN] | ||||
| 	} | ||||
| 	instructions{ | ||||
| 		C.FLW { | ||||
| 			encoding: b011 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rd[2:0] | b00; | ||||
| 			args_disass:"f(8+%rd$d), %uimm%(x(8+%rs1$d))"; | ||||
| 			val rs1_idx[5] <= rs1+8; | ||||
| 			val rd_idx[5] <= rd+8; | ||||
| 			val offs[XLEN] <= X[rs1_idx]+uimm; | ||||
| 			val res[32] <= MEM[offs]{32}; | ||||
| 			if(FLEN==32) | ||||
| 				F[rd_idx] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 		}  | ||||
| 		C.FSW { | ||||
| 			encoding: b111 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rs2[2:0] | b00; | ||||
| 			args_disass:"f(8+%rs2$d), %uimm%(x(8+%rs1$d))"; | ||||
| 			val rs1_idx[5] <= rs1+8; | ||||
| 			val rs2_idx[5] <= rs2+8; | ||||
| 			val offs[XLEN] <= X[rs1_idx]+uimm; | ||||
| 			MEM[offs]{32}<=F[rs2_idx]{32}; | ||||
| 		} | ||||
| 		C.FLWSP { | ||||
| 			encoding:b011 | uimm[5:5] | rd[4:0] | uimm[4:2] | uimm[7:6] | b10; | ||||
| 			args_disass:"f%rd$d, %uimm%(x2)"; | ||||
| 			val x2_idx[5] <= 2; | ||||
| 			val offs[XLEN] <= X[x2_idx]+uimm; | ||||
| 			val res[32] <= MEM[offs]{32}; | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 		} | ||||
| 		C.FSWSP { | ||||
| 			encoding:b111 | uimm[5:2] | uimm[7:6] | rs2[4:0] | b10; | ||||
| 			args_disass:"f%rs2$d, %uimm%(x2), "; | ||||
| 			val x2_idx[5] <= 2; | ||||
| 			val offs[XLEN] <= X[x2_idx]+uimm; | ||||
| 			MEM[offs]{32}<=F[rs2]{32}; | ||||
| 		}		 | ||||
| 	} | ||||
|     constants { | ||||
|         XLEN, FLEN | ||||
|     } | ||||
|     address_spaces {  | ||||
|         MEM[8] | ||||
|     } | ||||
|     registers {  | ||||
|         [31:0]   X[XLEN], | ||||
|         [31:0]   F[FLEN] | ||||
|     } | ||||
|     instructions{ | ||||
|         C.FLW { | ||||
|             encoding: b011 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rd[2:0] | b00; | ||||
|             args_disass:"f(8+%rd$d), %uimm%(x(8+%rs1$d))"; | ||||
|             val offs[XLEN] <= X[rs1+8]+uimm; | ||||
|             val res[32] <= MEM[offs]{32}; | ||||
|             if(FLEN==32) | ||||
|                 F[rd+8] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd+8] <= (upper<<32) | zext(res, FLEN); | ||||
|             } | ||||
|         }  | ||||
|         C.FSW { | ||||
|             encoding: b111 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rs2[2:0] | b00; | ||||
|             args_disass:"f(8+%rs2$d), %uimm%(x(8+%rs1$d))"; | ||||
|             val offs[XLEN] <= X[rs1+8]+uimm; | ||||
|             MEM[offs]{32}<=F[rs2+8]{32}; | ||||
|         } | ||||
|         C.FLWSP { | ||||
|             encoding:b011 | uimm[5:5] | rd[4:0] | uimm[4:2] | uimm[7:6] | b10; | ||||
|             args_disass:"f%rd$d, %uimm%(x2)"; | ||||
|             val offs[XLEN] <= X[2]+uimm; | ||||
|             val res[32] <= MEM[offs]{32}; | ||||
|             if(FLEN==32) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
|             } | ||||
|         } | ||||
|         C.FSWSP { | ||||
|             encoding:b111 | uimm[5:2] | uimm[7:6] | rs2[4:0] | b10; | ||||
|             args_disass:"f%rs2$d, %uimm%(x2), "; | ||||
|             val offs[XLEN] <= X[2]+uimm; | ||||
|             MEM[offs]{32}<=F[rs2]{32}; | ||||
|         }         | ||||
|     } | ||||
| } | ||||
|  | ||||
| InsructionSet RV32DC extends RV32IC{ | ||||
| 	constants { | ||||
| 		XLEN, FLEN | ||||
| 	} | ||||
| 	address_spaces {  | ||||
| 		MEM[8] | ||||
| 	} | ||||
| 	registers {  | ||||
| 		[31:0]   X[XLEN], | ||||
| 		[31:0]   F[FLEN] | ||||
| 	} | ||||
| 	instructions{ | ||||
| 		C.FLD { //(RV32/64) | ||||
| 			encoding: b001 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00; | ||||
| 			args_disass:"f(8+%rd$d), %uimm%(x(8+%rs1$d))"; | ||||
| 			val rs1_idx[5] <= rs1+8; | ||||
| 			val rd_idx[5] <= rd+8; | ||||
| 			val offs[XLEN] <= X[rs1_idx]+uimm; | ||||
| 			val res[64] <= MEM[offs]{64}; | ||||
| 			if(FLEN==64) | ||||
| 				F[rd_idx] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd_idx] <= (upper<<64) | res; | ||||
| 			} | ||||
| 	 	} | ||||
| 		C.FSD { //(RV32/64) | ||||
| 			encoding: b101 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rs2[2:0] | b00; | ||||
| 			args_disass:"f(8+%rs2$d), %uimm%(x(8+%rs1$d))"; | ||||
| 			val rs1_idx[5] <= rs1+8; | ||||
| 			val rs2_idx[5] <= rs2+8; | ||||
| 			val offs[XLEN] <= X[rs1_idx]+uimm; | ||||
| 			MEM[offs]{64}<=F[rs2_idx]{64}; | ||||
| 		}  | ||||
| 		C.FLDSP {//(RV32/64) | ||||
| 			encoding:b001 | uimm[5:5] | rd[4:0] | uimm[4:3] | uimm[8:6] | b10; | ||||
| 			args_disass:"f%rd$d, %uimm%(x2)"; | ||||
| 			val x2_idx[5] <= 2; | ||||
| 			val offs[XLEN] <= X[x2_idx]+uimm; | ||||
| 			val res[64] <= MEM[offs]{64}; | ||||
| 			if(FLEN==64) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | zext(res, FLEN); | ||||
| 			} | ||||
| 		} | ||||
| 		C.FSDSP {//(RV32/64) | ||||
| 			encoding:b101 | uimm[5:3] | uimm[8:6] | rs2[4:0] | b10; | ||||
| 			args_disass:"f%rs2$d, %uimm%(x2), "; | ||||
| 			val x2_idx[5] <= 2; | ||||
| 			val offs[XLEN] <= X[x2_idx]+uimm; | ||||
| 			MEM[offs]{64}<=F[rs2]{64}; | ||||
| 		} | ||||
| 	} | ||||
|     constants { | ||||
|         XLEN, FLEN | ||||
|     } | ||||
|     address_spaces {  | ||||
|         MEM[8] | ||||
|     } | ||||
|     registers {  | ||||
|         [31:0]   X[XLEN], | ||||
|         [31:0]   F[FLEN] | ||||
|     } | ||||
|     instructions{ | ||||
|         C.FLD { //(RV32/64) | ||||
|             encoding: b001 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00; | ||||
|             args_disass:"f(8+%rd$d), %uimm%(x(8+%rs1$d))"; | ||||
|             val offs[XLEN] <= X[rs1+8]+uimm; | ||||
|             val res[64] <= MEM[offs]{64}; | ||||
|             if(FLEN==64) | ||||
|                 F[rd+8] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd+8] <= (upper<<64) | res; | ||||
|             } | ||||
|          } | ||||
|         C.FSD { //(RV32/64) | ||||
|             encoding: b101 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rs2[2:0] | b00; | ||||
|             args_disass:"f(8+%rs2$d), %uimm%(x(8+%rs1$d))"; | ||||
|             val offs[XLEN] <= X[rs1+8]+uimm; | ||||
|             MEM[offs]{64}<=F[rs2+8]{64}; | ||||
|         }  | ||||
|         C.FLDSP {//(RV32/64) | ||||
|             encoding:b001 | uimm[5:5] | rd[4:0] | uimm[4:3] | uimm[8:6] | b10; | ||||
|             args_disass:"f%rd$d, %uimm%(x2)"; | ||||
|             val offs[XLEN] <= X[2]+uimm; | ||||
|             val res[64] <= MEM[offs]{64}; | ||||
|             if(FLEN==64) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<64) | zext(res, FLEN); | ||||
|             } | ||||
|         } | ||||
|         C.FSDSP {//(RV32/64) | ||||
|             encoding:b101 | uimm[5:3] | uimm[8:6] | rs2[4:0] | b10; | ||||
|             args_disass:"f%rs2$d, %uimm%(x2), "; | ||||
|             val offs[XLEN] <= X[2]+uimm; | ||||
|             MEM[offs]{64}<=F[rs2]{64}; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| InsructionSet RV64IC extends RV32IC { | ||||
| 	constants { | ||||
| 		XLEN | ||||
| 	} | ||||
| 	address_spaces {  | ||||
| 		MEM[8] | ||||
| 	} | ||||
| 	registers {  | ||||
| 		[31:0]   X[XLEN], | ||||
| 				PC[XLEN](is_pc) | ||||
| 	} | ||||
| 	instructions{ | ||||
| 		C.LD {//(RV64/128)  | ||||
| 			encoding:b011 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00; | ||||
| 		} | ||||
| 		C.SD { //(RV64/128)  | ||||
| 			encoding:b111 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rs2[2:0] | b00; | ||||
| 		} | ||||
| 		C.SUBW {//(RV64/128, RV32 res) | ||||
| 			encoding:b100 | b1 | b11 | rd[2:0] | b00 | rs2[2:0] | b01; | ||||
| 			args_disass: "x%rd$d, sp, 0x%imm$05x"; | ||||
| 		} | ||||
| 		C.ADDW {//(RV64/128 RV32 res) | ||||
| 			encoding:b100 | b1 | b11 | rd[2:0] | b01 | rs2[2:0] | b01; | ||||
| 			args_disass: "x%rd$d, sp, 0x%imm$05x"; | ||||
| 		} | ||||
|     constants { | ||||
|         XLEN | ||||
|     } | ||||
|     address_spaces {  | ||||
|         MEM[8] | ||||
|     } | ||||
|     registers {  | ||||
|         [31:0]   X[XLEN], | ||||
|                 PC[XLEN](is_pc) | ||||
|     } | ||||
|     instructions{ | ||||
|         C.LD {//(RV64/128)  | ||||
|             encoding:b011 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00; | ||||
|         } | ||||
|         C.SD { //(RV64/128)  | ||||
|             encoding:b111 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rs2[2:0] | b00; | ||||
|         } | ||||
|         C.SUBW {//(RV64/128, RV32 res) | ||||
|             encoding:b100 | b1 | b11 | rd[2:0] | b00 | rs2[2:0] | b01; | ||||
|             args_disass: "x%rd$d, sp, 0x%imm$05x"; | ||||
|         } | ||||
|         C.ADDW {//(RV64/128 RV32 res) | ||||
|             encoding:b100 | b1 | b11 | rd[2:0] | b01 | rs2[2:0] | b01; | ||||
|             args_disass: "x%rd$d, sp, 0x%imm$05x"; | ||||
|         } | ||||
|         C.ADDIW {//(RV64/128) | ||||
|             encoding:b001 | imm[5:5] | rs1[4:0] | imm[4:0] | b01; | ||||
|         } | ||||
|        	C.SRLI64 {//(RV32/64/128) | ||||
|           	encoding:b100 | b0 | b00 | rs1[2:0] | b00000 | b01; | ||||
|       	} | ||||
| 		C.SRAI64 {//(RV32/64/128) | ||||
| 			encoding:b100 | b0 | b01 | rs1[2:0] | b00000 | b01; | ||||
| 		} | ||||
| 		C.SLLI64 {//(RV128 RV32/64) | ||||
| 			encoding:b000 | b0 | rs1[4:0] | b00000 | b10; | ||||
| 		} | ||||
| 		C.LDSP {//(RV64/128 | ||||
| 			encoding:b011 | uimm[5:5] | rd[4:0] | uimm[4:3] | uimm[8:6] | b10; | ||||
| 			args_disass: "x%rd$d, sp, 0x%imm$05x"; | ||||
| 		} | ||||
| 		C.SDSP {//(RV64/128) | ||||
| 			encoding:b111 | uimm[5:3] | uimm[8:6] | rs2[4:0] | b10; | ||||
| 		} | ||||
| 	} | ||||
|            C.SRLI64 {//(RV32/64/128) | ||||
|               encoding:b100 | b0 | b00 | rs1[2:0] | b00000 | b01; | ||||
|           } | ||||
|         C.SRAI64 {//(RV32/64/128) | ||||
|             encoding:b100 | b0 | b01 | rs1[2:0] | b00000 | b01; | ||||
|         } | ||||
|         C.SLLI64 {//(RV128 RV32/64) | ||||
|             encoding:b000 | b0 | rs1[4:0] | b00000 | b10; | ||||
|         } | ||||
|         C.LDSP {//(RV64/128 | ||||
|             encoding:b011 | uimm[5:5] | rd[4:0] | uimm[4:3] | uimm[8:6] | b10; | ||||
|             args_disass: "x%rd$d, sp, 0x%imm$05x"; | ||||
|         } | ||||
|         C.SDSP {//(RV64/128) | ||||
|             encoding:b111 | uimm[5:3] | uimm[8:6] | rs2[4:0] | b10; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| InsructionSet RV128IC extends RV64IC { | ||||
| 	constants { | ||||
| 		XLEN | ||||
| 	} | ||||
| 	address_spaces {  | ||||
| 		MEM[8] | ||||
| 	} | ||||
| 	registers {  | ||||
| 		[31:0]   X[XLEN], | ||||
| 				PC[XLEN](is_pc) | ||||
| 	} | ||||
| 	instructions{ | ||||
| 		C.LQ { //(RV128) | ||||
| 			 encoding:b001 | uimm[5:4] | uimm[8:8] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00; | ||||
| 		} | ||||
| 		C.SQ { //(RV128)  | ||||
| 			encoding:b101 | uimm[5:4] | uimm[8:8] | rs1[2:0] | uimm[7:6] | rs2[2:0] | b00; | ||||
| 		} | ||||
| 		C.SQSP {//(RV128) | ||||
| 			encoding:b101 | uimm[5:4] | uimm[9:6] | rs2[4:0] | b10; | ||||
| 		} | ||||
| 	} | ||||
|     constants { | ||||
|         XLEN | ||||
|     } | ||||
|     address_spaces {  | ||||
|         MEM[8] | ||||
|     } | ||||
|     registers {  | ||||
|         [31:0]   X[XLEN], | ||||
|                 PC[XLEN](is_pc) | ||||
|     } | ||||
|     instructions{ | ||||
|         C.LQ { //(RV128) | ||||
|              encoding:b001 | uimm[5:4] | uimm[8:8] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00; | ||||
|         } | ||||
|         C.SQ { //(RV128)  | ||||
|             encoding:b101 | uimm[5:4] | uimm[8:8] | rs1[2:0] | uimm[7:6] | rs2[2:0] | b00; | ||||
|         } | ||||
|         C.SQSP {//(RV128) | ||||
|             encoding:b101 | uimm[5:4] | uimm[9:6] | rs2[4:0] | b10; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,298 +1,298 @@ | ||||
| import "RV32IBase.core_desc" | ||||
|  | ||||
| InsructionSet RV32D extends RV32IBase{ | ||||
| 	constants { | ||||
| 		FLEN, FFLAG_MASK := 0x1f | ||||
| 	}  | ||||
| 	registers { | ||||
| 		[31:0]    F[FLEN],  FCSR[32] | ||||
|     }	 | ||||
| 	instructions{ | ||||
| 		FLD { | ||||
| 			encoding: imm[11:0]s | rs1[4:0] | b011 | rd[4:0] | b0000111; | ||||
| 			args_disass:"f%rd$d, %imm%(x%rs1$d)"; | ||||
| 			val offs[XLEN] <= X[rs1]+imm; | ||||
| 			val res[64] <= MEM[offs]{64}; | ||||
| 			if(FLEN==64) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | res; | ||||
| 			} | ||||
| 		} | ||||
| 		FSD { | ||||
| 			encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b011 | imm[4:0]s | b0100111; | ||||
| 			args_disass:"f%rs2$d, %imm%(x%rs1$d)"; | ||||
| 			val offs[XLEN] <= X[rs1]+imm; | ||||
| 			MEM[offs]{64}<=F[rs2]{64}; | ||||
| 		} | ||||
| 		FMADD.D { | ||||
| 			encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; | ||||
| 			//F[rd]f<= F[rs1]f * F[rs2]f + F[rs3]f; | ||||
| 			val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(0, 64), choose(rm<7, rm{8}, FCSR{8})); | ||||
| 			if(FLEN==64) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | res; | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FMSUB.D { | ||||
| 			encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000111; | ||||
| 			args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; | ||||
| 			//F[rd]f<=F[rs1]f * F[rs2]f - F[rs3]f; | ||||
| 			val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(1, 32), choose(rm<7, rm{8}, FCSR{8})); | ||||
| 			if(FLEN==64) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | res; | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};	 | ||||
| 		} | ||||
| 		FNMADD.D { | ||||
| 			encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001111; | ||||
| 			args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; | ||||
| 			//F[rd]f<=-F[rs1]f * F[rs2]f + F[rs3]f; | ||||
| 			val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(2, 32), choose(rm<7, rm{8}, FCSR{8})); | ||||
| 			if(FLEN==64) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | res; | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FNMSUB.D { | ||||
| 			encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; | ||||
| 			//F[rd]f<=-F[rs1]f * F[rs2]f - F[rs3]f; | ||||
| 			val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(3, 32), choose(rm<7, rm{8}, FCSR{8})); | ||||
| 			if(FLEN==64) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | res; | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FADD.D { | ||||
| 			encoding: b0000001 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			// F[rd]f <= F[rs1]f + F[rs2]f; | ||||
| 			val res[64] <= fdispatch_fadd_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8})); | ||||
| 			if(FLEN==64) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | res; | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FSUB.D { | ||||
| 			encoding: b0000101 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			// F[rd]f <= F[rs1]f - F[rs2]f; | ||||
| 			val res[64] <= fdispatch_fsub_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8})); | ||||
| 			if(FLEN==64) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | res; | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FMUL.D { | ||||
| 			encoding: b0001001 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			// F[rd]f <= F[rs1]f * F[rs2]f; | ||||
| 			val res[64] <= fdispatch_fmul_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8})); | ||||
| 			if(FLEN==64) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | res; | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FDIV.D { | ||||
| 			encoding: b0001101 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			// F[rd]f <= F[rs1]f / F[rs2]f; | ||||
| 			val res[64] <= fdispatch_fdiv_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8})); | ||||
| 			if(FLEN==64) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | res; | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FSQRT.D { | ||||
| 			encoding: b0101101 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d"; | ||||
| 			//F[rd]f<=sqrt(F[rs1]f); | ||||
| 			val res[64] <= fdispatch_fsqrt_d(F[rs1]{64}, choose(rm<7, rm{8}, FCSR{8})); | ||||
| 			if(FLEN==64) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | res; | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FSGNJ.D { | ||||
| 			encoding: b0010001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			val res[64] <= (F[rs1]{64} & 0x7fffffff) | (F[rs2]{64} & 0x80000000); | ||||
| 			if(FLEN==64) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | res; | ||||
| 			} | ||||
| 		} | ||||
| 		FSGNJN.D { | ||||
| 			encoding: b0010001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			val res[64] <= (F[rs1]{64} & 0x7fffffff) | (~F[rs2]{64} & 0x80000000); | ||||
| 			if(FLEN==64) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | res; | ||||
| 			} | ||||
| 		} | ||||
| 		FSGNJX.D { | ||||
| 			encoding: b0010001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			val res[64] <= F[rs1]{64} ^ (F[rs2]{64} & 0x80000000); | ||||
| 			if(FLEN==64) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | res; | ||||
| 			} | ||||
| 		} | ||||
| 		FMIN.D  { | ||||
| 			encoding: b0010101 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			//F[rd]f<= choose(F[rs1]f<F[rs2]f, F[rs1]f, F[rs2]f); | ||||
| 			val res[64] <= fdispatch_fsel_d(F[rs1]{64}, F[rs2]{64}, zext(0, 32)); | ||||
| 			if(FLEN==64) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | res; | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FMAX.D { | ||||
| 			encoding: b0010101 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			//F[rd]f<= choose(F[rs1]f>F[rs2]f, F[rs1]f, F[rs2]f); | ||||
| 			val res[64] <= fdispatch_fsel_d(F[rs1]{64}, F[rs2]{64}, zext(1, 32)); | ||||
| 			if(FLEN==64) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | res; | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FCVT.S.D { | ||||
| 			encoding: b0100000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, f%rs1$d"; | ||||
| 			val res[32] <= fdispatch_fconv_d2f(F[rs1], rm{8}); | ||||
| 			// NaN boxing | ||||
| 			val upper[FLEN] <= -1; | ||||
| 			F[rd] <= upper<<32 | zext(res, FLEN); | ||||
| 		} | ||||
| 		FCVT.D.S { | ||||
| 			encoding: b0100001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, f%rs1$d"; | ||||
| 			val res[64] <= fdispatch_fconv_f2d(F[rs1]{32}, rm{8}); | ||||
| 			if(FLEN==64){ | ||||
| 				F[rd] <= res; | ||||
| 			} else { | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | res; | ||||
| 			} | ||||
| 		} | ||||
| 		FEQ.D { | ||||
| 			encoding: b1010001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(0, 32)); | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FLT.D { | ||||
| 			encoding: b1010001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(2, 32)); | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FLE.D { | ||||
| 			encoding: b1010001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(1, 32)); | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FCLASS.D { | ||||
| 			encoding: b1110001 | b00000 | rs1[4:0] | b001 | rd[4:0] | b1010011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d"; | ||||
| 			X[rd]<=fdispatch_fclass_d(F[rs1]{64}); | ||||
| 		} | ||||
| 		FCVT.W.D { | ||||
| 			encoding: b1100001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d"; | ||||
| 			X[rd]<= sext(fdispatch_fcvt_d(F[rs1]{64}, zext(0, 32), rm{8}), XLEN); | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FCVT.WU.D { | ||||
| 			encoding: b1100001 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d"; | ||||
| 			X[rd]<= zext(fdispatch_fcvt_d(F[rs1]{64}, zext(1, 32), rm{8}), XLEN); | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FCVT.D.W { | ||||
| 			encoding: b1101001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, x%rs1$d"; | ||||
| 			val res[64] <= fdispatch_fcvt_d(sext(X[rs1],64), zext(2, 32), rm{8}); | ||||
| 			if(FLEN==64) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | res; | ||||
| 			} | ||||
| 		} | ||||
| 		FCVT.D.WU { | ||||
| 			encoding: b1101001 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, x%rs1$d"; | ||||
| 			val res[64] <=fdispatch_fcvt_d(zext(X[rs1],64), zext(3,32), rm{8}); | ||||
| 			if(FLEN==64) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | res; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|     constants { | ||||
|         FLEN, FFLAG_MASK := 0x1f | ||||
|     }  | ||||
|     registers { | ||||
|         [31:0]    F[FLEN],  FCSR[32] | ||||
|     }     | ||||
|     instructions{ | ||||
|         FLD { | ||||
|             encoding: imm[11:0]s | rs1[4:0] | b011 | rd[4:0] | b0000111; | ||||
|             args_disass:"f%rd$d, %imm%(x%rs1$d)"; | ||||
|             val offs[XLEN] <= X[rs1]+imm; | ||||
|             val res[64] <= MEM[offs]{64}; | ||||
|             if(FLEN==64) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<64) | res; | ||||
|             } | ||||
|         } | ||||
|         FSD { | ||||
|             encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b011 | imm[4:0]s | b0100111; | ||||
|             args_disass:"f%rs2$d, %imm%(x%rs1$d)"; | ||||
|             val offs[XLEN] <= X[rs1]+imm; | ||||
|             MEM[offs]{64}<=F[rs2]{64}; | ||||
|         } | ||||
|         FMADD.D { | ||||
|             encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000011; | ||||
|             args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; | ||||
|             //F[rd]f<= F[rs1]f * F[rs2]f + F[rs3]f; | ||||
|             val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(0, 64), choose(rm<7, rm{8}, FCSR{8})); | ||||
|             if(FLEN==64) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<64) | res; | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FMSUB.D { | ||||
|             encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000111; | ||||
|             args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; | ||||
|             //F[rd]f<=F[rs1]f * F[rs2]f - F[rs3]f; | ||||
|             val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(1, 32), choose(rm<7, rm{8}, FCSR{8})); | ||||
|             if(FLEN==64) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<64) | res; | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};     | ||||
|         } | ||||
|         FNMADD.D { | ||||
|             encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001111; | ||||
|             args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; | ||||
|             //F[rd]f<=-F[rs1]f * F[rs2]f + F[rs3]f; | ||||
|             val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(2, 32), choose(rm<7, rm{8}, FCSR{8})); | ||||
|             if(FLEN==64) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<64) | res; | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FNMSUB.D { | ||||
|             encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001011; | ||||
|             args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; | ||||
|             //F[rd]f<=-F[rs1]f * F[rs2]f - F[rs3]f; | ||||
|             val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(3, 32), choose(rm<7, rm{8}, FCSR{8})); | ||||
|             if(FLEN==64) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<64) | res; | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FADD.D { | ||||
|             encoding: b0000001 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             // F[rd]f <= F[rs1]f + F[rs2]f; | ||||
|             val res[64] <= fdispatch_fadd_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8})); | ||||
|             if(FLEN==64) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<64) | res; | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FSUB.D { | ||||
|             encoding: b0000101 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             // F[rd]f <= F[rs1]f - F[rs2]f; | ||||
|             val res[64] <= fdispatch_fsub_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8})); | ||||
|             if(FLEN==64) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<64) | res; | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FMUL.D { | ||||
|             encoding: b0001001 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             // F[rd]f <= F[rs1]f * F[rs2]f; | ||||
|             val res[64] <= fdispatch_fmul_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8})); | ||||
|             if(FLEN==64) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<64) | res; | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FDIV.D { | ||||
|             encoding: b0001101 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             // F[rd]f <= F[rs1]f / F[rs2]f; | ||||
|             val res[64] <= fdispatch_fdiv_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8})); | ||||
|             if(FLEN==64) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<64) | res; | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FSQRT.D { | ||||
|             encoding: b0101101 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"x%rd$d, f%rs1$d"; | ||||
|             //F[rd]f<=sqrt(F[rs1]f); | ||||
|             val res[64] <= fdispatch_fsqrt_d(F[rs1]{64}, choose(rm<7, rm{8}, FCSR{8})); | ||||
|             if(FLEN==64) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<64) | res; | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FSGNJ.D { | ||||
|             encoding: b0010001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             val res[64] <= (F[rs1]{64} & 0x7fffffff) | (F[rs2]{64} & 0x80000000); | ||||
|             if(FLEN==64) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<64) | res; | ||||
|             } | ||||
|         } | ||||
|         FSGNJN.D { | ||||
|             encoding: b0010001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             val res[64] <= (F[rs1]{64} & 0x7fffffff) | (~F[rs2]{64} & 0x80000000); | ||||
|             if(FLEN==64) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<64) | res; | ||||
|             } | ||||
|         } | ||||
|         FSGNJX.D { | ||||
|             encoding: b0010001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             val res[64] <= F[rs1]{64} ^ (F[rs2]{64} & 0x80000000); | ||||
|             if(FLEN==64) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<64) | res; | ||||
|             } | ||||
|         } | ||||
|         FMIN.D  { | ||||
|             encoding: b0010101 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             //F[rd]f<= choose(F[rs1]f<F[rs2]f, F[rs1]f, F[rs2]f); | ||||
|             val res[64] <= fdispatch_fsel_d(F[rs1]{64}, F[rs2]{64}, zext(0, 32)); | ||||
|             if(FLEN==64) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<64) | res; | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FMAX.D { | ||||
|             encoding: b0010101 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             //F[rd]f<= choose(F[rs1]f>F[rs2]f, F[rs1]f, F[rs2]f); | ||||
|             val res[64] <= fdispatch_fsel_d(F[rs1]{64}, F[rs2]{64}, zext(1, 32)); | ||||
|             if(FLEN==64) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<64) | res; | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FCVT.S.D { | ||||
|             encoding: b0100000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, f%rs1$d"; | ||||
|             val res[32] <= fdispatch_fconv_d2f(F[rs1], rm{8}); | ||||
|             // NaN boxing | ||||
|             val upper[FLEN] <= -1; | ||||
|             F[rd] <= upper<<32 | zext(res, FLEN); | ||||
|         } | ||||
|         FCVT.D.S { | ||||
|             encoding: b0100001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, f%rs1$d"; | ||||
|             val res[64] <= fdispatch_fconv_f2d(F[rs1]{32}, rm{8}); | ||||
|             if(FLEN==64){ | ||||
|                 F[rd] <= res; | ||||
|             } else { | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<64) | res; | ||||
|             } | ||||
|         } | ||||
|         FEQ.D { | ||||
|             encoding: b1010001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011; | ||||
|             args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(0, 32)); | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FLT.D { | ||||
|             encoding: b1010001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; | ||||
|             args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(2, 32)); | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FLE.D { | ||||
|             encoding: b1010001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; | ||||
|             args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(1, 32)); | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FCLASS.D { | ||||
|             encoding: b1110001 | b00000 | rs1[4:0] | b001 | rd[4:0] | b1010011; | ||||
|             args_disass:"x%rd$d, f%rs1$d"; | ||||
|             X[rd]<=fdispatch_fclass_d(F[rs1]{64}); | ||||
|         } | ||||
|         FCVT.W.D { | ||||
|             encoding: b1100001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"x%rd$d, f%rs1$d"; | ||||
|             X[rd]<= sext(fdispatch_fcvt_d(F[rs1]{64}, zext(0, 32), rm{8}), XLEN); | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FCVT.WU.D { | ||||
|             encoding: b1100001 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"x%rd$d, f%rs1$d"; | ||||
|             X[rd]<= zext(fdispatch_fcvt_d(F[rs1]{64}, zext(1, 32), rm{8}), XLEN); | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FCVT.D.W { | ||||
|             encoding: b1101001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, x%rs1$d"; | ||||
|             val res[64] <= fdispatch_fcvt_d(sext(X[rs1],64), zext(2, 32), rm{8}); | ||||
|             if(FLEN==64) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<64) | res; | ||||
|             } | ||||
|         } | ||||
|         FCVT.D.WU { | ||||
|             encoding: b1101001 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, x%rs1$d"; | ||||
|             val res[64] <=fdispatch_fcvt_d(zext(X[rs1],64), zext(3,32), rm{8}); | ||||
|             if(FLEN==64) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<64) | res; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,294 +1,294 @@ | ||||
| import "RV32IBase.core_desc" | ||||
|  | ||||
| InsructionSet RV32F extends RV32IBase{ | ||||
| 	constants { | ||||
| 		FLEN, FFLAG_MASK := 0x1f | ||||
| 	}  | ||||
| 	registers { | ||||
| 		[31:0]    F[FLEN],  FCSR[32] | ||||
|     }	 | ||||
| 	instructions{ | ||||
| 		FLW { | ||||
| 			encoding: imm[11:0]s | rs1[4:0] | b010 | rd[4:0] | b0000111; | ||||
| 			args_disass:"f%rd$d, %imm%(x%rs1$d)"; | ||||
| 			val offs[XLEN] <= X[rs1]+imm; | ||||
| 			val res[32] <= MEM[offs]{32}; | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 		} | ||||
| 		FSW { | ||||
| 			encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b010 | imm[4:0]s | b0100111; | ||||
| 			args_disass:"f%rs2$d, %imm%(x%rs1$d)"; | ||||
| 			val offs[XLEN] <= X[rs1]+imm; | ||||
| 			MEM[offs]{32}<=F[rs2]{32}; | ||||
| 		} | ||||
| 		FMADD.S { | ||||
| 			encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; | ||||
| 			//F[rd]f<= F[rs1]f * F[rs2]f + F[rs3]f; | ||||
| 			val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(0, 32), choose(rm<7, rm{8}, FCSR{8})); | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FMSUB.S { | ||||
| 			encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000111; | ||||
| 			args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; | ||||
| 			//F[rd]f<=F[rs1]f * F[rs2]f - F[rs3]f; | ||||
| 			val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(1, 32), choose(rm<7, rm{8}, FCSR{8})); | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};	 | ||||
| 		} | ||||
| 		FNMADD.S { | ||||
| 			encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001111; | ||||
| 			args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; | ||||
| 			//F[rd]f<=-F[rs1]f * F[rs2]f + F[rs3]f; | ||||
| 			val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(2, 32), choose(rm<7, rm{8}, FCSR{8})); | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FNMSUB.S { | ||||
| 			encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; | ||||
| 			//F[rd]f<=-F[rs1]f * F[rs2]f - F[rs3]f; | ||||
| 			val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(3, 32), choose(rm<7, rm{8}, FCSR{8})); | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FADD.S { | ||||
| 			encoding: b0000000 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			// F[rd]f <= F[rs1]f + F[rs2]f; | ||||
| 			val res[32] <= fdispatch_fadd_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8})); | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FSUB.S { | ||||
| 			encoding: b0000100 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			// F[rd]f <= F[rs1]f - F[rs2]f; | ||||
| 			val res[32] <= fdispatch_fsub_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8})); | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FMUL.S { | ||||
| 			encoding: b0001000 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			// F[rd]f <= F[rs1]f * F[rs2]f; | ||||
| 			val res[32] <= fdispatch_fmul_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8})); | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FDIV.S { | ||||
| 			encoding: b0001100 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			// F[rd]f <= F[rs1]f / F[rs2]f; | ||||
| 			val res[32] <= fdispatch_fdiv_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8})); | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FSQRT.S { | ||||
| 			encoding: b0101100 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, f%rs1$d"; | ||||
| 			//F[rd]f<=sqrt(F[rs1]f); | ||||
| 			val res[32] <= fdispatch_fsqrt_s(F[rs1]{32}, choose(rm<7, rm{8}, FCSR{8})); | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FSGNJ.S { | ||||
| 			encoding: b0010000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			val res[32] <= (F[rs1]{32} & 0x7fffffff) | (F[rs2]{32} & 0x80000000); | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 		} | ||||
| 		FSGNJN.S { | ||||
| 			encoding: b0010000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			val res[32] <= (F[rs1]{32} & 0x7fffffff) | (~F[rs2]{32} & 0x80000000); | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 		} | ||||
| 		FSGNJX.S { | ||||
| 			encoding: b0010000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			val res[32] <= F[rs1]{32} ^ (F[rs2]{32} & 0x80000000); | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 		} | ||||
| 		FMIN.S  { | ||||
| 			encoding: b0010100 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			//F[rd]f<= choose(F[rs1]f<F[rs2]f, F[rs1]f, F[rs2]f); | ||||
| 			val res[32] <= fdispatch_fsel_s(F[rs1]{32}, F[rs2]{32}, zext(0, 32)); | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FMAX.S { | ||||
| 			encoding: b0010100 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			//F[rd]f<= choose(F[rs1]f>F[rs2]f, F[rs1]f, F[rs2]f); | ||||
| 			val res[32] <= fdispatch_fsel_s(F[rs1]{32}, F[rs2]{32}, zext(1, 32)); | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FCVT.W.S { | ||||
| 			encoding: b1100000 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d"; | ||||
| 			X[rd]<= sext(fdispatch_fcvt_s(F[rs1]{32}, zext(0, 32), rm{8}), XLEN); | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FCVT.WU.S { | ||||
| 			encoding: b1100000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d"; | ||||
| 			X[rd]<= zext(fdispatch_fcvt_s(F[rs1]{32}, zext(1, 32), rm{8}), XLEN); | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FEQ.S { | ||||
| 			encoding: b1010000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			X[rd]<=fdispatch_fcmp_s(F[rs1]{32}, F[rs2]{32}, zext(0, 32)); | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FLT.S { | ||||
| 			encoding: b1010000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			X[rd]<=fdispatch_fcmp_s(F[rs1]{32}, F[rs2]{32}, zext(2, 32)); | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FLE.S { | ||||
| 			encoding: b1010000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
| 			X[rd]<=fdispatch_fcmp_s(F[rs1]{32}, F[rs2]{32}, zext(1, 32)); | ||||
| 			val flags[32] <= fdispatch_fget_flags(); | ||||
| 			FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
| 		} | ||||
| 		FCLASS.S { | ||||
| 			encoding: b1110000 | b00000 | rs1[4:0] | b001 | rd[4:0] | b1010011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d"; | ||||
| 			X[rd]<=fdispatch_fclass_s(F[rs1]{32}); | ||||
| 		} | ||||
| 		FCVT.S.W { | ||||
| 			encoding: b1101000 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, x%rs1$d"; | ||||
| 			val res[32] <= fdispatch_fcvt_s(X[rs1]{32}, zext(2, 32), rm{8}); | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 		} | ||||
| 		FCVT.S.WU { | ||||
| 			encoding: b1101000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, x%rs1$d"; | ||||
| 			val res[32] <=fdispatch_fcvt_s(X[rs1]{32}, zext(3,32), rm{8}); | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 		} | ||||
| 		FMV.X.W { | ||||
| 			encoding: b1110000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011; | ||||
| 			args_disass:"x%rd$d, f%rs1$d"; | ||||
| 			X[rd]<=sext(F[rs1]{32}); | ||||
| 		} | ||||
| 		FMV.W.X { | ||||
| 			encoding: b1111000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011; | ||||
| 			args_disass:"f%rd$d, x%rs1$d"; | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= X[rs1]; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(X[rs1], FLEN); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|     constants { | ||||
|         FLEN, FFLAG_MASK := 0x1f | ||||
|     }  | ||||
|     registers { | ||||
|         [31:0]    F[FLEN],  FCSR[32] | ||||
|     }     | ||||
|     instructions{ | ||||
|         FLW { | ||||
|             encoding: imm[11:0]s | rs1[4:0] | b010 | rd[4:0] | b0000111; | ||||
|             args_disass:"f%rd$d, %imm%(x%rs1$d)"; | ||||
|             val offs[XLEN] <= X[rs1]+imm; | ||||
|             val res[32] <= MEM[offs]{32}; | ||||
|             if(FLEN==32) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
|             } | ||||
|         } | ||||
|         FSW { | ||||
|             encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b010 | imm[4:0]s | b0100111; | ||||
|             args_disass:"f%rs2$d, %imm%(x%rs1$d)"; | ||||
|             val offs[XLEN] <= X[rs1]+imm; | ||||
|             MEM[offs]{32}<=F[rs2]{32}; | ||||
|         } | ||||
|         FMADD.S { | ||||
|             encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000011; | ||||
|             args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; | ||||
|             //F[rd]f<= F[rs1]f * F[rs2]f + F[rs3]f; | ||||
|             val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(0, 32), choose(rm<7, rm{8}, FCSR{8})); | ||||
|             if(FLEN==32) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FMSUB.S { | ||||
|             encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000111; | ||||
|             args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; | ||||
|             //F[rd]f<=F[rs1]f * F[rs2]f - F[rs3]f; | ||||
|             val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(1, 32), choose(rm<7, rm{8}, FCSR{8})); | ||||
|             if(FLEN==32) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};     | ||||
|         } | ||||
|         FNMADD.S { | ||||
|             encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001111; | ||||
|             args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; | ||||
|             //F[rd]f<=-F[rs1]f * F[rs2]f + F[rs3]f; | ||||
|             val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(2, 32), choose(rm<7, rm{8}, FCSR{8})); | ||||
|             if(FLEN==32) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FNMSUB.S { | ||||
|             encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001011; | ||||
|             args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; | ||||
|             //F[rd]f<=-F[rs1]f * F[rs2]f - F[rs3]f; | ||||
|             val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(3, 32), choose(rm<7, rm{8}, FCSR{8})); | ||||
|             if(FLEN==32) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FADD.S { | ||||
|             encoding: b0000000 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             // F[rd]f <= F[rs1]f + F[rs2]f; | ||||
|             val res[32] <= fdispatch_fadd_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8})); | ||||
|             if(FLEN==32) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FSUB.S { | ||||
|             encoding: b0000100 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             // F[rd]f <= F[rs1]f - F[rs2]f; | ||||
|             val res[32] <= fdispatch_fsub_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8})); | ||||
|             if(FLEN==32) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FMUL.S { | ||||
|             encoding: b0001000 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             // F[rd]f <= F[rs1]f * F[rs2]f; | ||||
|             val res[32] <= fdispatch_fmul_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8})); | ||||
|             if(FLEN==32) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FDIV.S { | ||||
|             encoding: b0001100 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             // F[rd]f <= F[rs1]f / F[rs2]f; | ||||
|             val res[32] <= fdispatch_fdiv_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8})); | ||||
|             if(FLEN==32) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FSQRT.S { | ||||
|             encoding: b0101100 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, f%rs1$d"; | ||||
|             //F[rd]f<=sqrt(F[rs1]f); | ||||
|             val res[32] <= fdispatch_fsqrt_s(F[rs1]{32}, choose(rm<7, rm{8}, FCSR{8})); | ||||
|             if(FLEN==32) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FSGNJ.S { | ||||
|             encoding: b0010000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             val res[32] <= (F[rs1]{32} & 0x7fffffff) | (F[rs2]{32} & 0x80000000); | ||||
|             if(FLEN==32) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
|             } | ||||
|         } | ||||
|         FSGNJN.S { | ||||
|             encoding: b0010000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             val res[32] <= (F[rs1]{32} & 0x7fffffff) | (~F[rs2]{32} & 0x80000000); | ||||
|             if(FLEN==32) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
|             } | ||||
|         } | ||||
|         FSGNJX.S { | ||||
|             encoding: b0010000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             val res[32] <= F[rs1]{32} ^ (F[rs2]{32} & 0x80000000); | ||||
|             if(FLEN==32) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
|             } | ||||
|         } | ||||
|         FMIN.S  { | ||||
|             encoding: b0010100 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             //F[rd]f<= choose(F[rs1]f<F[rs2]f, F[rs1]f, F[rs2]f); | ||||
|             val res[32] <= fdispatch_fsel_s(F[rs1]{32}, F[rs2]{32}, zext(0, 32)); | ||||
|             if(FLEN==32) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FMAX.S { | ||||
|             encoding: b0010100 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             //F[rd]f<= choose(F[rs1]f>F[rs2]f, F[rs1]f, F[rs2]f); | ||||
|             val res[32] <= fdispatch_fsel_s(F[rs1]{32}, F[rs2]{32}, zext(1, 32)); | ||||
|             if(FLEN==32) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
|             } | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FCVT.W.S { | ||||
|             encoding: b1100000 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"x%rd$d, f%rs1$d"; | ||||
|             X[rd]<= sext(fdispatch_fcvt_s(F[rs1]{32}, zext(0, 32), rm{8}), XLEN); | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FCVT.WU.S { | ||||
|             encoding: b1100000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"x%rd$d, f%rs1$d"; | ||||
|             X[rd]<= zext(fdispatch_fcvt_s(F[rs1]{32}, zext(1, 32), rm{8}), XLEN); | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FEQ.S { | ||||
|             encoding: b1010000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011; | ||||
|             args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             X[rd]<=fdispatch_fcmp_s(F[rs1]{32}, F[rs2]{32}, zext(0, 32)); | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FLT.S { | ||||
|             encoding: b1010000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; | ||||
|             args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             X[rd]<=fdispatch_fcmp_s(F[rs1]{32}, F[rs2]{32}, zext(2, 32)); | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FLE.S { | ||||
|             encoding: b1010000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; | ||||
|             args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; | ||||
|             X[rd]<=fdispatch_fcmp_s(F[rs1]{32}, F[rs2]{32}, zext(1, 32)); | ||||
|             val flags[32] <= fdispatch_fget_flags(); | ||||
|             FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | ||||
|         } | ||||
|         FCLASS.S { | ||||
|             encoding: b1110000 | b00000 | rs1[4:0] | b001 | rd[4:0] | b1010011; | ||||
|             args_disass:"x%rd$d, f%rs1$d"; | ||||
|             X[rd]<=fdispatch_fclass_s(F[rs1]{32}); | ||||
|         } | ||||
|         FCVT.S.W { | ||||
|             encoding: b1101000 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, x%rs1$d"; | ||||
|             val res[32] <= fdispatch_fcvt_s(X[rs1]{32}, zext(2, 32), rm{8}); | ||||
|             if(FLEN==32) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
|             } | ||||
|         } | ||||
|         FCVT.S.WU { | ||||
|             encoding: b1101000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, x%rs1$d"; | ||||
|             val res[32] <=fdispatch_fcvt_s(X[rs1]{32}, zext(3,32), rm{8}); | ||||
|             if(FLEN==32) | ||||
|                 F[rd] <= res; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
|             } | ||||
|         } | ||||
|         FMV.X.W { | ||||
|             encoding: b1110000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011; | ||||
|             args_disass:"x%rd$d, f%rs1$d"; | ||||
|             X[rd]<=sext(F[rs1]{32}); | ||||
|         } | ||||
|         FMV.W.X { | ||||
|             encoding: b1111000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011; | ||||
|             args_disass:"f%rd$d, x%rs1$d"; | ||||
|             if(FLEN==32) | ||||
|                 F[rd] <= X[rs1]; | ||||
|             else { // NaN boxing | ||||
|                 val upper[FLEN] <= -1; | ||||
|                 F[rd] <= (upper<<32) | zext(X[rs1], FLEN); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,325 +1,326 @@ | ||||
| InsructionSet RV32IBase { | ||||
| 	constants { | ||||
| 		XLEN, | ||||
| 		PCLEN, | ||||
| 		XLEN_BIT_MASK:=0x1f, | ||||
|     constants { | ||||
|         XLEN, | ||||
|         PCLEN, | ||||
|         XLEN_BIT_MASK:=0x1f, | ||||
|         fence:=0, | ||||
|         fencei:=1, | ||||
|         fencevmal:=2, | ||||
|         fencevmau:=3 | ||||
| 	} | ||||
| 	 | ||||
| 	address_spaces {  | ||||
| 		MEM[8], CSR[XLEN], FENCE[XLEN] | ||||
| 	} | ||||
| 				 | ||||
| 	registers {  | ||||
| 		[31:0]   X[XLEN], | ||||
|                 PC[XLEN](is_pc) | ||||
| 	} | ||||
| 	  | ||||
| 	instructions {  | ||||
| 		LUI{ | ||||
| 		    encoding: imm[31:12]s | rd[4:0] | b0110111; | ||||
| 		    args_disass: "x%rd$d, 0x%imm$05x"; | ||||
| 		    if(rd!=0) X[rd] <= imm; | ||||
| 		} | ||||
| 		AUIPC{ | ||||
| 		    encoding: imm[31:12]s | rd[4:0] | b0010111; | ||||
| 		    args_disass: "x%rd%, 0x%imm$08x"; | ||||
| 		    if(rd!=0) X[rd] <= PC+imm; | ||||
| 		} | ||||
| 	    JAL(no_cont){ | ||||
|     		encoding: imm[20:20]s | imm[10:1]s | imm[11:11]s | imm[19:12]s | rd[4:0] | b1101111; | ||||
| 		    args_disass: "x%rd$d, 0x%imm$x"; | ||||
|     		if(rd!=0) X[rd] <= PC+4; | ||||
|     		PC<=PC+imm; | ||||
| 		} | ||||
| 	    JALR(no_cont){ | ||||
| 	    	encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b1100111; | ||||
| 		    args_disass: "x%rd$d, x%rs1$d, 0x%imm$x"; | ||||
|     } | ||||
|      | ||||
|     address_spaces {  | ||||
|         MEM[8], CSR[XLEN], FENCE[XLEN] | ||||
|     } | ||||
|                  | ||||
|     registers {  | ||||
|         [31:0]   X[XLEN], | ||||
|                 PC[XLEN](is_pc), | ||||
|                 alias ZERO[XLEN] is X[0]  | ||||
|     } | ||||
|       | ||||
|     instructions {  | ||||
|         LUI{ | ||||
|             encoding: imm[31:12]s | rd[4:0] | b0110111; | ||||
|             args_disass: "x%rd$d, 0x%imm$05x"; | ||||
|             if(rd!=0) X[rd] <= imm; | ||||
|         } | ||||
|         AUIPC{ | ||||
|             encoding: imm[31:12]s | rd[4:0] | b0010111; | ||||
|             args_disass: "x%rd%, 0x%imm$08x"; | ||||
|             if(rd!=0) X[rd] <= PC+imm; | ||||
|         } | ||||
|         JAL(no_cont){ | ||||
|             encoding: imm[20:20]s | imm[10:1]s | imm[11:11]s | imm[19:12]s | rd[4:0] | b1101111; | ||||
|             args_disass: "x%rd$d, 0x%imm$x"; | ||||
|             if(rd!=0) X[rd] <= PC+4; | ||||
|             PC<=PC+imm; | ||||
|         } | ||||
|         JALR(no_cont){ | ||||
|             encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b1100111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, 0x%imm$x"; | ||||
|             val new_pc[XLEN] <= X[rs1]+ imm; | ||||
|             val align[XLEN] <= new_pc & 0x2; | ||||
| 		    if(align != 0){ | ||||
| 		        raise(0, 0); | ||||
| 		    } else { | ||||
|         		if(rd!=0) X[rd] <= PC+4; | ||||
|         		PC<=new_pc & ~0x1; | ||||
|     		} | ||||
| 	    } | ||||
| 		BEQ(no_cont,cond){ | ||||
| 		    encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b000 | imm[4:1]s | imm[11:11]s | b1100011; | ||||
| 		    args_disass:"x%rs1$d, x%rs2$d, 0x%imm$x"; | ||||
| 		    PC<=choose(X[rs1]==X[rs2], PC+imm, PC+4); | ||||
| 		} | ||||
| 		BNE(no_cont,cond){ | ||||
| 		    encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b001 | imm[4:1]s | imm[11:11]s | b1100011; | ||||
| 		    args_disass:"x%rs1$d, x%rs2$d, 0x%imm$x"; | ||||
| 	    	PC<=choose(X[rs1]!=X[rs2], PC+imm, PC+4); | ||||
| 		} | ||||
| 		BLT(no_cont,cond){ | ||||
| 		    encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b100 | imm[4:1]s | imm[11:11]s | b1100011; | ||||
| 		    args_disass:"x%rs1$d, x%rs2$d, 0x%imm$x"; | ||||
| 	    	PC<=choose(X[rs1]s<X[rs2]s, PC+imm, PC+4); | ||||
| 		} | ||||
| 		BGE(no_cont,cond) { | ||||
| 		    encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b101 | imm[4:1]s | imm[11:11]s | b1100011; | ||||
| 		    args_disass:"x%rs1$d, x%rs2$d, 0x%imm$x"; | ||||
| 	    	PC<=choose(X[rs1]s>=X[rs2]s, PC+imm, PC+4); | ||||
| 		} | ||||
| 		BLTU(no_cont,cond) { | ||||
| 		    encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b110 | imm[4:1]s | imm[11:11]s | b1100011; | ||||
| 		    args_disass:"x%rs1$d, x%rs2$d, 0x%imm$x"; | ||||
| 	    	PC<=choose(X[rs1]<X[rs2],PC+imm, PC+4); | ||||
| 		} | ||||
| 		BGEU(no_cont,cond) { | ||||
| 		    encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b111 | imm[4:1]s | imm[11:11]s | b1100011; | ||||
| 		    args_disass:"x%rs1$d, x%rs2$d, 0x%imm$x"; | ||||
| 	    	PC<=choose(X[rs1]>=X[rs2], PC+imm, PC+4); | ||||
| 		} | ||||
| 		LB { | ||||
| 		    encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b0000011; | ||||
| 		    args_disass:"x%rd$d, %imm%(x%rs1$d)"; | ||||
| 		    val offs[XLEN] <= X[rs1]+imm; | ||||
| 		    if(rd!=0) X[rd]<=sext(MEM[offs]); | ||||
| 		} | ||||
| 		LH { | ||||
| 		    encoding: imm[11:0]s | rs1[4:0] | b001 | rd[4:0] | b0000011; | ||||
| 		    args_disass:"x%rd$d, %imm%(x%rs1$d)"; | ||||
| 		    val offs[XLEN] <= X[rs1]+imm; | ||||
| 		    if(rd!=0) X[rd]<=sext(MEM[offs]{16});		     | ||||
| 		} | ||||
| 		LW { | ||||
| 		    encoding: imm[11:0]s | rs1[4:0] | b010 | rd[4:0] | b0000011; | ||||
| 		    args_disass:"x%rd$d, %imm%(x%rs1$d)"; | ||||
| 		    val offs[XLEN] <= X[rs1]+imm; | ||||
| 		    if(rd!=0) X[rd]<=sext(MEM[offs]{32}); | ||||
| 		} | ||||
| 		LBU { | ||||
| 		    encoding: imm[11:0]s | rs1[4:0] | b100 | rd[4:0] | b0000011; | ||||
| 		    args_disass:"x%rd$d, %imm%(x%rs1$d)"; | ||||
| 		    val offs[XLEN] <= X[rs1]+imm; | ||||
| 		    if(rd!=0) X[rd]<=zext(MEM[offs]); | ||||
| 		} | ||||
| 		LHU { | ||||
| 		    encoding: imm[11:0]s | rs1[4:0] | b101 | rd[4:0] | b0000011; | ||||
| 		    args_disass:"x%rd$d, %imm%(x%rs1$d)"; | ||||
| 		    val offs[XLEN] <= X[rs1]+imm; | ||||
| 		    if(rd!=0) X[rd]<=zext(MEM[offs]{16});		     | ||||
| 		} | ||||
| 		SB { | ||||
| 		    encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b000 | imm[4:0]s | b0100011; | ||||
| 		    args_disass:"x%rs2$d, %imm%(x%rs1$d)"; | ||||
| 	    	val offs[XLEN] <= X[rs1] + imm; | ||||
| 	    	MEM[offs] <= X[rs2]; | ||||
| 		} | ||||
| 		SH { | ||||
| 		    encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b001 | imm[4:0]s | b0100011; | ||||
| 		    args_disass:"x%rs2$d, %imm%(x%rs1$d)"; | ||||
| 	    	val offs[XLEN] <= X[rs1] + imm; | ||||
| 	    	MEM[offs]{16} <= X[rs2]; | ||||
| 		} | ||||
| 	    SW { | ||||
| 	    	encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b010 | imm[4:0]s | b0100011; | ||||
| 		    args_disass:"x%rs2$d, %imm%(x%rs1$d)"; | ||||
| 	    	val offs[XLEN] <= X[rs1] + imm; | ||||
| 	    	MEM[offs]{32} <= X[rs2]; | ||||
| 	    } | ||||
| 		ADDI { | ||||
| 			encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b0010011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, %imm%"; | ||||
| 			if(rd != 0) X[rd] <= X[rs1] + imm; | ||||
| 		} | ||||
| 		SLTI { | ||||
| 			encoding: imm[11:0]s | rs1[4:0] | b010 | rd[4:0] | b0010011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, %imm%"; | ||||
| 			if (rd != 0) X[rd] <= choose(X[rs1]s < imm's, 1, 0); //TODO: needs fix | ||||
| 		} | ||||
| 	    SLTIU { | ||||
| 	        encoding: imm[11:0]s | rs1[4:0] | b011 | rd[4:0] | b0010011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, %imm%"; | ||||
| 		    val full_imm[XLEN] <= imm's; | ||||
| 	        if (rd != 0) X[rd] <= choose(X[rs1]'u < full_imm'u, 1, 0); | ||||
| 	    } | ||||
| 		XORI { | ||||
| 			encoding: imm[11:0]s | rs1[4:0] | b100 | rd[4:0] | b0010011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, %imm%"; | ||||
| 			if(rd != 0) X[rd] <= X[rs1] ^ imm; | ||||
| 		} | ||||
| 		ORI { | ||||
| 			encoding: imm[11:0]s | rs1[4:0] | b110 | rd[4:0] | b0010011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, %imm%"; | ||||
| 			if(rd != 0) X[rd] <= X[rs1] | imm; | ||||
| 		} | ||||
| 		ANDI { | ||||
| 			encoding: imm[11:0]s | rs1[4:0] | b111 | rd[4:0] | b0010011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, %imm%"; | ||||
| 			if(rd != 0) X[rd] <= X[rs1] & imm; | ||||
| 		} | ||||
| 		SLLI { | ||||
| 		    encoding: b0000000 | shamt[4:0] | rs1[4:0] | b001 | rd[4:0] | b0010011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, %shamt%"; | ||||
| 		    if(shamt > 31){ | ||||
| 		        raise(0,0); | ||||
| 		    } else { | ||||
| 		        if(rd != 0) X[rd] <= shll(X[rs1], shamt); | ||||
| 		    } | ||||
| 		} | ||||
| 		SRLI { | ||||
| 		    encoding: b0000000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0010011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, %shamt%"; | ||||
|             if(align != 0){ | ||||
|                 raise(0, 0); | ||||
|             } else { | ||||
|                 if(rd!=0) X[rd] <= PC+4; | ||||
|                 PC<=new_pc & ~0x1; | ||||
|             } | ||||
|         } | ||||
|         BEQ(no_cont,cond){ | ||||
|             encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b000 | imm[4:1]s | imm[11:11]s | b1100011; | ||||
|             args_disass:"x%rs1$d, x%rs2$d, 0x%imm$x"; | ||||
|             PC<=choose(X[rs1]==X[rs2], PC+imm, PC+4); | ||||
|         } | ||||
|         BNE(no_cont,cond){ | ||||
|             encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b001 | imm[4:1]s | imm[11:11]s | b1100011; | ||||
|             args_disass:"x%rs1$d, x%rs2$d, 0x%imm$x"; | ||||
|             PC<=choose(X[rs1]!=X[rs2], PC+imm, PC+4); | ||||
|         } | ||||
|         BLT(no_cont,cond){ | ||||
|             encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b100 | imm[4:1]s | imm[11:11]s | b1100011; | ||||
|             args_disass:"x%rs1$d, x%rs2$d, 0x%imm$x"; | ||||
|             PC<=choose(X[rs1]s<X[rs2]s, PC+imm, PC+4); | ||||
|         } | ||||
|         BGE(no_cont,cond) { | ||||
|             encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b101 | imm[4:1]s | imm[11:11]s | b1100011; | ||||
|             args_disass:"x%rs1$d, x%rs2$d, 0x%imm$x"; | ||||
|             PC<=choose(X[rs1]s>=X[rs2]s, PC+imm, PC+4); | ||||
|         } | ||||
|         BLTU(no_cont,cond) { | ||||
|             encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b110 | imm[4:1]s | imm[11:11]s | b1100011; | ||||
|             args_disass:"x%rs1$d, x%rs2$d, 0x%imm$x"; | ||||
|             PC<=choose(X[rs1]<X[rs2],PC+imm, PC+4); | ||||
|         } | ||||
|         BGEU(no_cont,cond) { | ||||
|             encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b111 | imm[4:1]s | imm[11:11]s | b1100011; | ||||
|             args_disass:"x%rs1$d, x%rs2$d, 0x%imm$x"; | ||||
|             PC<=choose(X[rs1]>=X[rs2], PC+imm, PC+4); | ||||
|         } | ||||
|         LB { | ||||
|             encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b0000011; | ||||
|             args_disass:"x%rd$d, %imm%(x%rs1$d)"; | ||||
|             val offs[XLEN] <= X[rs1]+imm; | ||||
|             if(rd!=0) X[rd]<=sext(MEM[offs]); | ||||
|         } | ||||
|         LH { | ||||
|             encoding: imm[11:0]s | rs1[4:0] | b001 | rd[4:0] | b0000011; | ||||
|             args_disass:"x%rd$d, %imm%(x%rs1$d)"; | ||||
|             val offs[XLEN] <= X[rs1]+imm; | ||||
|             if(rd!=0) X[rd]<=sext(MEM[offs]{16});             | ||||
|         } | ||||
|         LW { | ||||
|             encoding: imm[11:0]s | rs1[4:0] | b010 | rd[4:0] | b0000011; | ||||
|             args_disass:"x%rd$d, %imm%(x%rs1$d)"; | ||||
|             val offs[XLEN] <= X[rs1]+imm; | ||||
|             if(rd!=0) X[rd]<=sext(MEM[offs]{32}); | ||||
|         } | ||||
|         LBU { | ||||
|             encoding: imm[11:0]s | rs1[4:0] | b100 | rd[4:0] | b0000011; | ||||
|             args_disass:"x%rd$d, %imm%(x%rs1$d)"; | ||||
|             val offs[XLEN] <= X[rs1]+imm; | ||||
|             if(rd!=0) X[rd]<=zext(MEM[offs]); | ||||
|         } | ||||
|         LHU { | ||||
|             encoding: imm[11:0]s | rs1[4:0] | b101 | rd[4:0] | b0000011; | ||||
|             args_disass:"x%rd$d, %imm%(x%rs1$d)"; | ||||
|             val offs[XLEN] <= X[rs1]+imm; | ||||
|             if(rd!=0) X[rd]<=zext(MEM[offs]{16});             | ||||
|         } | ||||
|         SB { | ||||
|             encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b000 | imm[4:0]s | b0100011; | ||||
|             args_disass:"x%rs2$d, %imm%(x%rs1$d)"; | ||||
|             val offs[XLEN] <= X[rs1] + imm; | ||||
|             MEM[offs] <= X[rs2]; | ||||
|         } | ||||
|         SH { | ||||
|             encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b001 | imm[4:0]s | b0100011; | ||||
|             args_disass:"x%rs2$d, %imm%(x%rs1$d)"; | ||||
|             val offs[XLEN] <= X[rs1] + imm; | ||||
|             MEM[offs]{16} <= X[rs2]; | ||||
|         } | ||||
|         SW { | ||||
|             encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b010 | imm[4:0]s | b0100011; | ||||
|             args_disass:"x%rs2$d, %imm%(x%rs1$d)"; | ||||
|             val offs[XLEN] <= X[rs1] + imm; | ||||
|             MEM[offs]{32} <= X[rs2]; | ||||
|         } | ||||
|         ADDI { | ||||
|             encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b0010011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, %imm%"; | ||||
|             if(rd != 0) X[rd] <= X[rs1] + imm; | ||||
|         } | ||||
|         SLTI { | ||||
|             encoding: imm[11:0]s | rs1[4:0] | b010 | rd[4:0] | b0010011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, %imm%"; | ||||
|             if (rd != 0) X[rd] <= choose(X[rs1]s < imm's, 1, 0); | ||||
|         } | ||||
|         SLTIU { | ||||
|             encoding: imm[11:0]s | rs1[4:0] | b011 | rd[4:0] | b0010011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, %imm%"; | ||||
|             val full_imm[XLEN] <= imm's; | ||||
|             if (rd != 0) X[rd] <= choose(X[rs1]'u < full_imm'u, 1, 0); | ||||
|         } | ||||
|         XORI { | ||||
|             encoding: imm[11:0]s | rs1[4:0] | b100 | rd[4:0] | b0010011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, %imm%"; | ||||
|             if(rd != 0) X[rd] <= X[rs1] ^ imm; | ||||
|         } | ||||
|         ORI { | ||||
|             encoding: imm[11:0]s | rs1[4:0] | b110 | rd[4:0] | b0010011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, %imm%"; | ||||
|             if(rd != 0) X[rd] <= X[rs1] | imm; | ||||
|         } | ||||
|         ANDI { | ||||
|             encoding: imm[11:0]s | rs1[4:0] | b111 | rd[4:0] | b0010011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, %imm%"; | ||||
|             if(rd != 0) X[rd] <= X[rs1] & imm; | ||||
|         } | ||||
|         SLLI { | ||||
|             encoding: b0000000 | shamt[4:0] | rs1[4:0] | b001 | rd[4:0] | b0010011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, %shamt%"; | ||||
|             if(shamt > 31){ | ||||
|                 raise(0,0); | ||||
|             } else { | ||||
| 		        if(rd != 0) X[rd] <= shrl(X[rs1], shamt); | ||||
| 		    } | ||||
| 		} | ||||
| 		SRAI { | ||||
| 		    encoding: b0100000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0010011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, %shamt%"; | ||||
| 		    if(shamt > 31){ | ||||
|                 if(rd != 0) X[rd] <= shll(X[rs1], shamt); | ||||
|             } | ||||
|         } | ||||
|         SRLI { | ||||
|             encoding: b0000000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0010011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, %shamt%"; | ||||
|             if(shamt > 31){ | ||||
|                 raise(0,0); | ||||
|             } else { | ||||
| 		        if(rd != 0) X[rd] <= shra(X[rs1], shamt); | ||||
| 		    } | ||||
| 		} | ||||
| 		ADD { | ||||
| 		    encoding: b0000000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0110011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 			if(rd != 0) X[rd] <= X[rs1] + X[rs2]; | ||||
| 		} | ||||
| 		SUB { | ||||
| 		    encoding: b0100000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0110011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 			if(rd != 0) X[rd] <= X[rs1] - X[rs2]; | ||||
| 		} | ||||
| 		SLL { | ||||
| 		    encoding: b0000000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b0110011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 		    if(rd != 0) X[rd] <= shll(X[rs1], X[rs2]&XLEN_BIT_MASK); | ||||
| 		} | ||||
| 		SLT { | ||||
| 		    encoding: b0000000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0110011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 	        if (rd != 0) X[rd] <= choose(X[rs1]s < X[rs2]s, 1, 0); | ||||
| 		} | ||||
| 		SLTU { | ||||
| 		    encoding: b0000000 | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0110011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 	        if (rd != 0) X[rd] <= choose(zext(X[rs1]) < zext(X[rs2]), 1, 0); | ||||
| 		} | ||||
| 		XOR { | ||||
| 		    encoding: b0000000 | rs2[4:0] | rs1[4:0] | b100 | rd[4:0] | b0110011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 			if(rd != 0) X[rd] <= X[rs1] ^ X[rs2]; | ||||
| 		} | ||||
| 		SRL { | ||||
| 		    encoding: b0000000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 		    if(rd != 0) X[rd] <= shrl(X[rs1], X[rs2]&XLEN_BIT_MASK); | ||||
| 		} | ||||
| 		SRA { | ||||
| 		    encoding: b0100000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 		    if(rd != 0) X[rd] <= shra(X[rs1], X[rs2]&XLEN_BIT_MASK); | ||||
| 		} | ||||
| 		OR { | ||||
| 		    encoding: b0000000 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0110011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 			if(rd != 0) X[rd] <= X[rs1] | X[rs2]; | ||||
| 		} | ||||
| 		AND { | ||||
| 		    encoding: b0000000 | rs2[4:0] | rs1[4:0] | b111 | rd[4:0] | b0110011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 			if(rd != 0) X[rd] <= X[rs1] & X[rs2]; | ||||
| 		} | ||||
| 		FENCE { | ||||
| 			encoding: b0000 | pred[3:0] | succ[3:0] | rs1[4:0] | b000 | rd[4:0] | b0001111; | ||||
| 		    FENCE[fence] <= pred<<4 | succ; | ||||
| 		} | ||||
| 		FENCE_I(flush) { | ||||
| 		    encoding: imm[11:0] | rs1[4:0] | b001 | rd[4:0] | b0001111 ; | ||||
| 		    FENCE[fencei] <= imm; | ||||
| 		} | ||||
| 		ECALL(no_cont) { | ||||
| 		    encoding: b000000000000 | b00000 | b000 | b00000 | b1110011; | ||||
| 		    raise(0, 11); | ||||
| 		} | ||||
| 		EBREAK(no_cont) { | ||||
| 		    encoding: b000000000001 | b00000 | b000 | b00000 | b1110011; | ||||
| 		    raise(0, 3); | ||||
| 		} | ||||
| 		URET(no_cont) { | ||||
| 			encoding: b0000000 | b00010 | b00000 | b000 | b00000 | b1110011; | ||||
| 			leave(0); | ||||
| 		} | ||||
| 		SRET(no_cont)  { | ||||
| 			encoding: b0001000 | b00010 | b00000 | b000 | b00000 | b1110011; | ||||
| 			leave(1); | ||||
| 		} | ||||
| 		MRET(no_cont) { | ||||
| 			encoding: b0011000 | b00010 | b00000 | b000 | b00000 | b1110011; | ||||
| 			leave(3); | ||||
| 		} | ||||
| 		WFI  { | ||||
| 			encoding: b0001000 | b00101 | b00000 | b000 | b00000 | b1110011; | ||||
| 			wait(1); | ||||
| 		} | ||||
| 		SFENCE.VMA { | ||||
| 			encoding: b0001001 | rs2[4:0] | rs1[4:0] | b000 | b00000 | b1110011; | ||||
| 		    FENCE[fencevmal] <= rs1; | ||||
| 		    FENCE[fencevmau] <= rs2; | ||||
| 		} | ||||
| 		CSRRW { | ||||
| 		    encoding: csr[11:0] | rs1[4:0] | b001 | rd[4:0] | b1110011; | ||||
| 		    args_disass:"x%rd$d, %csr$d, x%rs1$d"; | ||||
|                 if(rd != 0) X[rd] <= shrl(X[rs1], shamt); | ||||
|             } | ||||
|         } | ||||
|         SRAI { | ||||
|             encoding: b0100000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0010011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, %shamt%"; | ||||
|             if(shamt > 31){ | ||||
|                 raise(0,0); | ||||
|             } else { | ||||
|                 if(rd != 0) X[rd] <= shra(X[rs1], shamt); | ||||
|             } | ||||
|         } | ||||
|         ADD { | ||||
|             encoding: b0000000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0110011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0) X[rd] <= X[rs1] + X[rs2]; | ||||
|         } | ||||
|         SUB { | ||||
|             encoding: b0100000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0110011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0) X[rd] <= X[rs1] - X[rs2]; | ||||
|         } | ||||
|         SLL { | ||||
|             encoding: b0000000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b0110011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0) X[rd] <= shll(X[rs1], X[rs2]&XLEN_BIT_MASK); | ||||
|         } | ||||
|         SLT { | ||||
|             encoding: b0000000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0110011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if (rd != 0) X[rd] <= choose(X[rs1]s < X[rs2]s, 1, 0); | ||||
|         } | ||||
|         SLTU { | ||||
|             encoding: b0000000 | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0110011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if (rd != 0) X[rd] <= choose(zext(X[rs1]) < zext(X[rs2]), 1, 0); | ||||
|         } | ||||
|         XOR { | ||||
|             encoding: b0000000 | rs2[4:0] | rs1[4:0] | b100 | rd[4:0] | b0110011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0) X[rd] <= X[rs1] ^ X[rs2]; | ||||
|         } | ||||
|         SRL { | ||||
|             encoding: b0000000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0) X[rd] <= shrl(X[rs1], X[rs2]&XLEN_BIT_MASK); | ||||
|         } | ||||
|         SRA { | ||||
|             encoding: b0100000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0) X[rd] <= shra(X[rs1], X[rs2]&XLEN_BIT_MASK); | ||||
|         } | ||||
|         OR { | ||||
|             encoding: b0000000 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0110011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0) X[rd] <= X[rs1] | X[rs2]; | ||||
|         } | ||||
|         AND { | ||||
|             encoding: b0000000 | rs2[4:0] | rs1[4:0] | b111 | rd[4:0] | b0110011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0) X[rd] <= X[rs1] & X[rs2]; | ||||
|         } | ||||
|         FENCE { | ||||
|             encoding: b0000 | pred[3:0] | succ[3:0] | rs1[4:0] | b000 | rd[4:0] | b0001111; | ||||
|             FENCE[fence] <= pred<<4 | succ; | ||||
|         } | ||||
|         FENCE_I(flush) { | ||||
|             encoding: imm[11:0] | rs1[4:0] | b001 | rd[4:0] | b0001111 ; | ||||
|             FENCE[fencei] <= imm; | ||||
|         } | ||||
|         ECALL(no_cont) { | ||||
|             encoding: b000000000000 | b00000 | b000 | b00000 | b1110011; | ||||
|             raise(0, 11); | ||||
|         } | ||||
|         EBREAK(no_cont) { | ||||
|             encoding: b000000000001 | b00000 | b000 | b00000 | b1110011; | ||||
|             raise(0, 3); | ||||
|         } | ||||
|         URET(no_cont) { | ||||
|             encoding: b0000000 | b00010 | b00000 | b000 | b00000 | b1110011; | ||||
|             leave(0); | ||||
|         } | ||||
|         SRET(no_cont)  { | ||||
|             encoding: b0001000 | b00010 | b00000 | b000 | b00000 | b1110011; | ||||
|             leave(1); | ||||
|         } | ||||
|         MRET(no_cont) { | ||||
|             encoding: b0011000 | b00010 | b00000 | b000 | b00000 | b1110011; | ||||
|             leave(3); | ||||
|         } | ||||
|         WFI  { | ||||
|             encoding: b0001000 | b00101 | b00000 | b000 | b00000 | b1110011; | ||||
|             wait(1); | ||||
|         } | ||||
|         SFENCE.VMA { | ||||
|             encoding: b0001001 | rs2[4:0] | rs1[4:0] | b000 | b00000 | b1110011; | ||||
|             FENCE[fencevmal] <= rs1; | ||||
|             FENCE[fencevmau] <= rs2; | ||||
|         } | ||||
|         CSRRW { | ||||
|             encoding: csr[11:0] | rs1[4:0] | b001 | rd[4:0] | b1110011; | ||||
|             args_disass:"x%rd$d, %csr$d, x%rs1$d"; | ||||
|             val rs_val[XLEN] <= X[rs1]; | ||||
| 		    if(rd!=0){ | ||||
| 		        val csr_val[XLEN] <= CSR[csr]; | ||||
|             if(rd!=0){ | ||||
|                 val csr_val[XLEN] <= CSR[csr]; | ||||
|                 CSR[csr] <= rs_val;  | ||||
|                 // make sure Xrd is updated once CSR write succeeds | ||||
| 	   	        X[rd] <= csr_val; | ||||
|    	        } else { | ||||
| 		        CSR[csr] <= rs_val; | ||||
| 	        } | ||||
| 		} | ||||
| 		CSRRS { | ||||
| 		    encoding: csr[11:0] | rs1[4:0] | b010 | rd[4:0] | b1110011; | ||||
| 		    args_disass:"x%rd$d, %csr$d, x%rs1$d"; | ||||
| 		    val xrd[XLEN] <= CSR[csr]; | ||||
| 		    val xrs1[XLEN] <= X[rs1]; | ||||
| 		    if(rd!=0) X[rd] <= xrd; | ||||
| 		    if(rs1!=0) CSR[csr] <= xrd | xrs1;	 | ||||
| 		} | ||||
| 		CSRRC { | ||||
| 		    encoding: csr[11:0] | rs1[4:0] | b011 | rd[4:0] | b1110011; | ||||
| 		    args_disass:"x%rd$d, %csr$d, x%rs1$d"; | ||||
| 		    val xrd[XLEN] <= CSR[csr]; | ||||
| 		    val xrs1[XLEN] <= X[rs1]; | ||||
| 		    if(rd!=0) X[rd] <= xrd; | ||||
| 		    if(rs1!=0) CSR[csr] <= xrd & ~xrs1;	 | ||||
| 		} | ||||
| 		CSRRWI { | ||||
| 		    encoding: csr[11:0] | zimm[4:0] | b101 | rd[4:0] | b1110011; | ||||
| 		    args_disass:"x%rd$d, %csr$d, 0x%zimm$x"; | ||||
| 		    if(rd!=0) X[rd] <= CSR[csr]; | ||||
| 		    CSR[csr] <= zext(zimm);	 | ||||
| 		} | ||||
| 		CSRRSI { | ||||
| 		    encoding: csr[11:0] | zimm[4:0] | b110 | rd[4:0] | b1110011; | ||||
| 		    args_disass:"x%rd$d, %csr$d, 0x%zimm$x"; | ||||
| 		    val res[XLEN] <= CSR[csr]; | ||||
| 		    if(zimm!=0) CSR[csr] <= res | zext(zimm); | ||||
| 		    // make sure rd is written after csr write succeeds	 | ||||
|                    X[rd] <= csr_val; | ||||
|                } else { | ||||
|                 CSR[csr] <= rs_val; | ||||
|             } | ||||
|         } | ||||
|         CSRRS { | ||||
|             encoding: csr[11:0] | rs1[4:0] | b010 | rd[4:0] | b1110011; | ||||
|             args_disass:"x%rd$d, %csr$d, x%rs1$d"; | ||||
|             val xrd[XLEN] <= CSR[csr]; | ||||
|             val xrs1[XLEN] <= X[rs1]; | ||||
|             if(rd!=0) X[rd] <= xrd; | ||||
|             if(rs1!=0) CSR[csr] <= xrd | xrs1;     | ||||
|         } | ||||
|         CSRRC { | ||||
|             encoding: csr[11:0] | rs1[4:0] | b011 | rd[4:0] | b1110011; | ||||
|             args_disass:"x%rd$d, %csr$d, x%rs1$d"; | ||||
|             val xrd[XLEN] <= CSR[csr]; | ||||
|             val xrs1[XLEN] <= X[rs1]; | ||||
|             if(rd!=0) X[rd] <= xrd; | ||||
|             if(rs1!=0) CSR[csr] <= xrd & ~xrs1;     | ||||
|         } | ||||
|         CSRRWI { | ||||
|             encoding: csr[11:0] | zimm[4:0] | b101 | rd[4:0] | b1110011; | ||||
|             args_disass:"x%rd$d, %csr$d, 0x%zimm$x"; | ||||
|             if(rd!=0) X[rd] <= CSR[csr]; | ||||
|             CSR[csr] <= zext(zimm);     | ||||
|         } | ||||
|         CSRRSI { | ||||
|             encoding: csr[11:0] | zimm[4:0] | b110 | rd[4:0] | b1110011; | ||||
|             args_disass:"x%rd$d, %csr$d, 0x%zimm$x"; | ||||
|             val res[XLEN] <= CSR[csr]; | ||||
|             if(zimm!=0) CSR[csr] <= res | zext(zimm); | ||||
|             // make sure rd is written after csr write succeeds     | ||||
|             if(rd!=0) X[rd] <= res; | ||||
| 		} | ||||
| 		CSRRCI { | ||||
| 		    encoding: csr[11:0] | zimm[4:0] | b111 | rd[4:0] | b1110011; | ||||
| 		    args_disass:"x%rd$d, %csr$d, 0x%zimm$x"; | ||||
| 		    val res[XLEN] <= CSR[csr]; | ||||
| 		    if(rd!=0) X[rd] <= res; | ||||
| 		    if(zimm!=0) CSR[csr] <= res & ~zext(zimm, XLEN);	 | ||||
| 		}    | ||||
| 	} | ||||
|         } | ||||
|         CSRRCI { | ||||
|             encoding: csr[11:0] | zimm[4:0] | b111 | rd[4:0] | b1110011; | ||||
|             args_disass:"x%rd$d, %csr$d, 0x%zimm$x"; | ||||
|             val res[XLEN] <= CSR[csr]; | ||||
|             if(rd!=0) X[rd] <= res; | ||||
|             if(zimm!=0) CSR[csr] <= res & ~zext(zimm, XLEN);     | ||||
|         }    | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,97 +1,97 @@ | ||||
| import "RV32IBase.core_desc" | ||||
|  | ||||
| InsructionSet RV32M extends RV32IBase { | ||||
| 	constants { | ||||
| 		MAXLEN:=128 | ||||
| 	} | ||||
| 	instructions{        | ||||
| 		MUL{ | ||||
| 			encoding: b0000001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0110011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 		    if(rd != 0){ | ||||
| 		        val res[MAXLEN] <= zext(X[rs1], MAXLEN) * zext(X[rs2], MAXLEN); | ||||
| 		    	X[rd]<= zext(res , XLEN); | ||||
| 		    } | ||||
| 		} | ||||
| 		MULH { | ||||
| 			encoding: b0000001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b0110011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 		    if(rd != 0){ | ||||
| 		        val res[MAXLEN] <= sext(X[rs1], MAXLEN) * sext(X[rs2], MAXLEN); | ||||
|     constants { | ||||
|         MAXLEN:=128 | ||||
|     } | ||||
|     instructions{        | ||||
|         MUL{ | ||||
|             encoding: b0000001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0110011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0){ | ||||
|                 val res[MAXLEN] <= zext(X[rs1], MAXLEN) * zext(X[rs2], MAXLEN); | ||||
|                 X[rd]<= zext(res , XLEN); | ||||
|             } | ||||
|         } | ||||
|         MULH { | ||||
|             encoding: b0000001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b0110011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0){ | ||||
|                 val res[MAXLEN] <= sext(X[rs1], MAXLEN) * sext(X[rs2], MAXLEN); | ||||
|                 X[rd]<= zext(res >> XLEN, XLEN); | ||||
| 		    } | ||||
| 		} | ||||
| 		MULHSU { | ||||
| 			encoding: b0000001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0110011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 		    if(rd != 0){ | ||||
|             } | ||||
|         } | ||||
|         MULHSU { | ||||
|             encoding: b0000001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0110011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0){ | ||||
|                 val res[MAXLEN] <= sext(X[rs1], MAXLEN) * zext(X[rs2], MAXLEN); | ||||
|                 X[rd]<= zext(res >> XLEN, XLEN); | ||||
| 		    } | ||||
| 		} | ||||
| 		MULHU { | ||||
| 			encoding: b0000001 | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0110011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 		    if(rd != 0){ | ||||
|             } | ||||
|         } | ||||
|         MULHU { | ||||
|             encoding: b0000001 | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0110011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0){ | ||||
|                 val res[MAXLEN] <= zext(X[rs1], MAXLEN) * zext(X[rs2], MAXLEN); | ||||
|                 X[rd]<= zext(res >> XLEN, XLEN); | ||||
| 		    } | ||||
| 		} | ||||
| 		DIV { | ||||
| 			encoding: b0000001 | rs2[4:0] | rs1[4:0] | b100 | rd[4:0] | b0110011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 		    if(rd != 0){ | ||||
| 		    	if(X[rs2]!=0){ | ||||
| 		    		val M1[XLEN] <= -1; | ||||
| 		    		val MMIN[XLEN] <= -1<<(XLEN-1); | ||||
| 		    		if(X[rs1]s==MMIN's) | ||||
| 			    		if(X[rs2]s==M1's) | ||||
| 			    			X[rd]<=MMIN; | ||||
| 		    			else | ||||
| 			    			X[rd] <= X[rs1]s / X[rs2]s; | ||||
| 	    			else | ||||
| 		    			X[rd] <= X[rs1]s / X[rs2]s; | ||||
| 		    	}else  | ||||
| 		    		X[rd] <= -1; | ||||
| 		    } | ||||
| 		} | ||||
| 		DIVU { | ||||
| 			encoding: b0000001 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 		    if(rd != 0){ | ||||
| 		    	if(X[rs2]!=0) | ||||
| 		    		X[rd] <= zext(X[rs1], 32) / zext(X[rs2], 32); | ||||
| 		    	else  | ||||
| 		    		X[rd] <= -1; | ||||
| 		    } | ||||
| 		} | ||||
| 		REM { | ||||
| 			encoding: b0000001 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0110011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 		    if(rd != 0){ | ||||
| 		    	if(X[rs2]!=0) { | ||||
| 		    		val M1[XLEN] <= -1; | ||||
| 		    		val MMIN[XLEN] <= -1<<(XLEN-1); | ||||
| 		    		if(X[rs1]s==MMIN's) | ||||
| 			    		if(X[rs2]s==M1's) | ||||
| 			    			X[rd] <= 0; | ||||
| 			    		else | ||||
| 			    			X[rd] <= sext(X[rs1], 32) % sext(X[rs2], 32); | ||||
| 	    			else | ||||
| 		    			X[rd] <= sext(X[rs1], 32) % sext(X[rs2], 32); | ||||
| 		    	} else  | ||||
| 		    		X[rd] <= X[rs1]; | ||||
| 		    } | ||||
| 		} | ||||
| 		REMU { | ||||
| 			encoding: b0000001 | rs2[4:0] | rs1[4:0] | b111 | rd[4:0] | b0110011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 		    if(rd != 0){ | ||||
| 		    	if(X[rs2]!=0) | ||||
| 			    	X[rd] <= zext(X[rs1], 32) % zext(X[rs2], 32); | ||||
| 		    	else  | ||||
| 		    		X[rd] <= X[rs1]; | ||||
| 		    } | ||||
| 		} | ||||
| 	} | ||||
|             } | ||||
|         } | ||||
|         DIV { | ||||
|             encoding: b0000001 | rs2[4:0] | rs1[4:0] | b100 | rd[4:0] | b0110011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0){ | ||||
|                 if(X[rs2]!=0){ | ||||
|                     val M1[XLEN] <= -1; | ||||
|                     val MMIN[XLEN] <= -1<<(XLEN-1); | ||||
|                     if(X[rs1]s==MMIN's) | ||||
|                         if(X[rs2]s==M1's) | ||||
|                             X[rd]<=MMIN; | ||||
|                         else | ||||
|                             X[rd] <= X[rs1]s / X[rs2]s; | ||||
|                     else | ||||
|                         X[rd] <= X[rs1]s / X[rs2]s; | ||||
|                 }else  | ||||
|                     X[rd] <= -1; | ||||
|             } | ||||
|         } | ||||
|         DIVU { | ||||
|             encoding: b0000001 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0){ | ||||
|                 if(X[rs2]!=0) | ||||
|                     X[rd] <= zext(X[rs1], 32) / zext(X[rs2], 32); | ||||
|                 else  | ||||
|                     X[rd] <= -1; | ||||
|             } | ||||
|         } | ||||
|         REM { | ||||
|             encoding: b0000001 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0110011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0){ | ||||
|                 if(X[rs2]!=0) { | ||||
|                     val M1[XLEN] <= -1; | ||||
|                     val MMIN[XLEN] <= -1<<(XLEN-1); | ||||
|                     if(X[rs1]s==MMIN's) | ||||
|                         if(X[rs2]s==M1's) | ||||
|                             X[rd] <= 0; | ||||
|                         else | ||||
|                             X[rd] <= sext(X[rs1], 32) % sext(X[rs2], 32); | ||||
|                     else | ||||
|                         X[rd] <= sext(X[rs1], 32) % sext(X[rs2], 32); | ||||
|                 } else  | ||||
|                     X[rd] <= X[rs1]; | ||||
|             } | ||||
|         } | ||||
|         REMU { | ||||
|             encoding: b0000001 | rs2[4:0] | rs1[4:0] | b111 | rd[4:0] | b0110011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0){ | ||||
|                 if(X[rs2]!=0) | ||||
|                     X[rd] <= zext(X[rs1], 32) % zext(X[rs2], 32); | ||||
|                 else  | ||||
|                     X[rd] <= X[rs1]; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -2,111 +2,111 @@ import "RV64IBase.core_desc" | ||||
| import "RV32A.core_desc" | ||||
|  | ||||
| InsructionSet RV64A extends RV64IBase { | ||||
| 	  | ||||
| 	address_spaces {  | ||||
| 		RES[8] | ||||
| 	} | ||||
| 	 | ||||
| 	instructions{ | ||||
| 		LR.D { | ||||
| 			encoding: b00010 | aq[0:0] | rl[0:0]  | b00000 | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d"; | ||||
| 			if(rd!=0){ | ||||
| 				val offs[XLEN] <= X[rs1]; | ||||
| 				X[rd]<= sext(MEM[offs]{64}, XLEN); | ||||
| 				RES[offs]{64}<=sext(-1, 64); | ||||
| 			}		 | ||||
| 		} | ||||
| 		SC.D { | ||||
| 			encoding: b00011 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 			val offs[XLEN] <= X[rs1]; | ||||
| 			val res[64] <= RES[offs]; | ||||
| 			if(res!=0){ | ||||
| 				MEM[offs]{64} <= X[rs2]; | ||||
| 				if(rd!=0) X[rd]<=0; | ||||
| 			} else{  | ||||
| 				if(rd!=0) X[rd]<= 1; | ||||
| 			} | ||||
| 		} | ||||
| 		AMOSWAP.D{ | ||||
| 			encoding: b00001 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; | ||||
| 			val offs[XLEN] <= X[rs1]; | ||||
| 			if(rd!=0) X[rd] <= sext(MEM[offs]{64}); | ||||
| 			MEM[offs]{64} <= X[rs2];			 | ||||
| 		} | ||||
| 		AMOADD.D{ | ||||
| 			encoding: b00000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; | ||||
| 			val offs[XLEN] <= X[rs1]; | ||||
| 			val res[XLEN] <= sext(MEM[offs]{64}); | ||||
| 			if(rd!=0) X[rd]<=res; | ||||
| 			val res2[XLEN] <= res + X[rs2]; | ||||
| 			MEM[offs]{64}<=res2;			 | ||||
| 		} | ||||
| 		AMOXOR.D{ | ||||
| 			encoding: b00100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; | ||||
| 			val offs[XLEN] <= X[rs1]; | ||||
| 			val res[XLEN] <= sext(MEM[offs]{64}); | ||||
| 			if(rd!=0) X[rd] <= res; | ||||
| 			val res2[XLEN] <= res ^ X[rs2]; | ||||
| 			MEM[offs]{64} <= res2;			 | ||||
| 		} | ||||
| 		AMOAND.D{ | ||||
| 			encoding: b01100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; | ||||
| 			val offs[XLEN] <= X[rs1]; | ||||
| 			val res[XLEN] <= sext(MEM[offs]{64}); | ||||
| 			if(rd!=0) X[rd] <= res; | ||||
| 			val res2[XLEN] <= res & X[rs2]; | ||||
| 			MEM[offs]{64} <= res2;			 | ||||
| 		} | ||||
| 		AMOOR.D { | ||||
| 			encoding: b01000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; | ||||
| 			val offs[XLEN] <= X[rs1]; | ||||
| 			val res[XLEN] <= sext(MEM[offs]{64}); | ||||
| 			if(rd!=0) X[rd] <= res; | ||||
| 			val res2[XLEN] <= res | X[rs2]; | ||||
| 			MEM[offs]{64} <= res2;			 | ||||
| 		} | ||||
| 		AMOMIN.D{ | ||||
| 			encoding: b10000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; | ||||
| 			val offs[XLEN] <= X[rs1]; | ||||
| 			val res[XLEN] <= sext(MEM[offs]{64}); | ||||
| 			if(rd!=0) X[rd] <= res; | ||||
| 			val res2[XLEN] <= choose(res s > X[rs2]s, X[rs2], res);			 | ||||
| 			MEM[offs]{64} <= res;			 | ||||
| 		} | ||||
| 		AMOMAX.D{ | ||||
| 			encoding: b10100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; | ||||
| 			val offs[XLEN] <= X[rs1]; | ||||
| 			val res[XLEN] <= sext(MEM[offs]{64}); | ||||
| 			if(rd!=0) X[rd] <= res; | ||||
| 			val res2[XLEN] <= choose(res s < X[rs2]s, X[rs2], res);			 | ||||
| 			MEM[offs]{64} <= res2;			 | ||||
| 		} | ||||
| 		AMOMINU.D{ | ||||
| 			encoding: b11000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; | ||||
| 			val offs[XLEN] <= X[rs1]; | ||||
| 			val res[XLEN] <= zext(MEM[offs]{64}); | ||||
| 			if(rd!=0) X[rd] <= res; | ||||
| 			val res2[XLEN] <= choose(res > X[rs2], X[rs2], res);			 | ||||
| 			MEM[offs]{64} <= res2;			 | ||||
| 		} | ||||
| 		AMOMAXU.D{ | ||||
| 			encoding: b11100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
| 			args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; | ||||
| 			val offs[XLEN] <= X[rs1]; | ||||
| 			val res[XLEN] <= zext(MEM[offs]{64}); | ||||
| 			if(rd!=0) X[rd] <= res; | ||||
| 			val res2[XLEN] <= choose(res < X[rs2], X[rs2], res);			 | ||||
| 			MEM[offs]{64} <= res2;			 | ||||
| 		} | ||||
| 	} | ||||
|       | ||||
|     address_spaces {  | ||||
|         RES[8] | ||||
|     } | ||||
|      | ||||
|     instructions{ | ||||
|         LR.D { | ||||
|             encoding: b00010 | aq[0:0] | rl[0:0]  | b00000 | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d"; | ||||
|             if(rd!=0){ | ||||
|                 val offs[XLEN] <= X[rs1]; | ||||
|                 X[rd]<= sext(MEM[offs]{64}, XLEN); | ||||
|                 RES[offs]{64}<=sext(-1, 64); | ||||
|             }         | ||||
|         } | ||||
|         SC.D { | ||||
|             encoding: b00011 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             val offs[XLEN] <= X[rs1]; | ||||
|             val res[64] <= RES[offs]; | ||||
|             if(res!=0){ | ||||
|                 MEM[offs]{64} <= X[rs2]; | ||||
|                 if(rd!=0) X[rd]<=0; | ||||
|             } else{  | ||||
|                 if(rd!=0) X[rd]<= 1; | ||||
|             } | ||||
|         } | ||||
|         AMOSWAP.D{ | ||||
|             encoding: b00001 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; | ||||
|             val offs[XLEN] <= X[rs1]; | ||||
|             if(rd!=0) X[rd] <= sext(MEM[offs]{64}); | ||||
|             MEM[offs]{64} <= X[rs2];             | ||||
|         } | ||||
|         AMOADD.D{ | ||||
|             encoding: b00000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; | ||||
|             val offs[XLEN] <= X[rs1]; | ||||
|             val res[XLEN] <= sext(MEM[offs]{64}); | ||||
|             if(rd!=0) X[rd]<=res; | ||||
|             val res2[XLEN] <= res + X[rs2]; | ||||
|             MEM[offs]{64}<=res2;             | ||||
|         } | ||||
|         AMOXOR.D{ | ||||
|             encoding: b00100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; | ||||
|             val offs[XLEN] <= X[rs1]; | ||||
|             val res[XLEN] <= sext(MEM[offs]{64}); | ||||
|             if(rd!=0) X[rd] <= res; | ||||
|             val res2[XLEN] <= res ^ X[rs2]; | ||||
|             MEM[offs]{64} <= res2;             | ||||
|         } | ||||
|         AMOAND.D{ | ||||
|             encoding: b01100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; | ||||
|             val offs[XLEN] <= X[rs1]; | ||||
|             val res[XLEN] <= sext(MEM[offs]{64}); | ||||
|             if(rd!=0) X[rd] <= res; | ||||
|             val res2[XLEN] <= res & X[rs2]; | ||||
|             MEM[offs]{64} <= res2;             | ||||
|         } | ||||
|         AMOOR.D { | ||||
|             encoding: b01000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; | ||||
|             val offs[XLEN] <= X[rs1]; | ||||
|             val res[XLEN] <= sext(MEM[offs]{64}); | ||||
|             if(rd!=0) X[rd] <= res; | ||||
|             val res2[XLEN] <= res | X[rs2]; | ||||
|             MEM[offs]{64} <= res2;             | ||||
|         } | ||||
|         AMOMIN.D{ | ||||
|             encoding: b10000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; | ||||
|             val offs[XLEN] <= X[rs1]; | ||||
|             val res[XLEN] <= sext(MEM[offs]{64}); | ||||
|             if(rd!=0) X[rd] <= res; | ||||
|             val res2[XLEN] <= choose(res s > X[rs2]s, X[rs2], res);             | ||||
|             MEM[offs]{64} <= res;             | ||||
|         } | ||||
|         AMOMAX.D{ | ||||
|             encoding: b10100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; | ||||
|             val offs[XLEN] <= X[rs1]; | ||||
|             val res[XLEN] <= sext(MEM[offs]{64}); | ||||
|             if(rd!=0) X[rd] <= res; | ||||
|             val res2[XLEN] <= choose(res s < X[rs2]s, X[rs2], res);             | ||||
|             MEM[offs]{64} <= res2;             | ||||
|         } | ||||
|         AMOMINU.D{ | ||||
|             encoding: b11000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; | ||||
|             val offs[XLEN] <= X[rs1]; | ||||
|             val res[XLEN] <= zext(MEM[offs]{64}); | ||||
|             if(rd!=0) X[rd] <= res; | ||||
|             val res2[XLEN] <= choose(res > X[rs2], X[rs2], res);             | ||||
|             MEM[offs]{64} <= res2;             | ||||
|         } | ||||
|         AMOMAXU.D{ | ||||
|             encoding: b11100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; | ||||
|             args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; | ||||
|             val offs[XLEN] <= X[rs1]; | ||||
|             val res[XLEN] <= zext(MEM[offs]{64}); | ||||
|             if(rd!=0) X[rd] <= res; | ||||
|             val res2[XLEN] <= choose(res < X[rs2], X[rs2], res);             | ||||
|             MEM[offs]{64} <= res2;             | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,116 +1,116 @@ | ||||
| import "RV32IBase.core_desc" | ||||
|  | ||||
| InsructionSet RV64IBase extends RV32IBase { | ||||
| 	instructions{ | ||||
| 		LWU { //	80000104: 0000ef03			lwu t5,0(ra) | ||||
| 			encoding: imm[11:0]s | rs1[4:0] | b110 | rd[4:0] | b0000011; | ||||
| 			args_disass:"x%rd$d, %imm%(x%rs1$d)"; | ||||
| 			val offs[XLEN] <= X[rs1]+imm; | ||||
| 			if(rd!=0) X[rd]<=zext(MEM[offs]{32}); | ||||
| 		} | ||||
| 		LD{ | ||||
| 			encoding: imm[11:0]s | rs1[4:0] | b011 | rd[4:0] | b0000011; | ||||
| 			args_disass:"x%rd$d, %imm%(x%rs1$d)"; | ||||
| 			val offs[XLEN] <= X[rs1]+imm; | ||||
| 			if(rd!=0) X[rd]<=sext(MEM[offs]{64}); | ||||
| 		} | ||||
| 		SD{ | ||||
| 			encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b011 | imm[4:0]s | b0100011; | ||||
| 			args_disass:"x%rs2$d, %imm%(x%rs1$d)"; | ||||
| 			val offs[XLEN] <= X[rs1] + imm; | ||||
| 			MEM[offs]{64} <= X[rs2]; | ||||
| 		} | ||||
| 		SLLI { | ||||
| 			encoding: b000000 | shamt[5:0] | rs1[4:0] | b001 | rd[4:0] | b0010011; | ||||
| 			args_disass:"x%rd$d, x%rs1$d, %shamt%"; | ||||
| 			if(rd != 0) X[rd] <= shll(X[rs1], shamt); | ||||
| 		} | ||||
| 		SRLI { | ||||
| 			encoding: b000000 | shamt[5:0] | rs1[4:0] | b101 | rd[4:0] | b0010011; | ||||
| 			args_disass:"x%rd$d, x%rs1$d, %shamt%"; | ||||
| 			if(rd != 0) X[rd] <= shrl(X[rs1], shamt); | ||||
| 		} | ||||
| 		SRAI { | ||||
| 			encoding: b010000 | shamt[5:0] | rs1[4:0] | b101 | rd[4:0] | b0010011; | ||||
| 			args_disass:"x%rd$d, x%rs1$d, %shamt%"; | ||||
| 			if(rd != 0) X[rd] <= shra(X[rs1], shamt); | ||||
| 		} | ||||
| 		ADDIW { | ||||
| 			encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b0011011; | ||||
| 			args_disass:"x%rd$d, x%rs1$d, %imm%"; | ||||
| 			if(rd != 0){ | ||||
| 				val res[32] <= X[rs1]{32} + imm; | ||||
| 				X[rd] <= sext(res); | ||||
| 			}  | ||||
| 		} | ||||
| 		SLLIW { | ||||
| 			encoding: b0000000 | shamt[4:0] | rs1[4:0] | b001 | rd[4:0] | b0011011; | ||||
| 			args_disass:"x%rd$d, x%rs1$d, %shamt%"; | ||||
| 			if(rd != 0){ | ||||
| 				val sh_val[32] <= shll(X[rs1]{32}, shamt); | ||||
| 				X[rd] <= sext(sh_val); | ||||
| 			}  | ||||
| 		} | ||||
| 		SRLIW { | ||||
| 			encoding: b0000000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0011011; | ||||
| 			args_disass:"x%rd$d, x%rs1$d, %shamt%"; | ||||
| 			if(rd != 0){ | ||||
| 				val sh_val[32] <= shrl(X[rs1]{32}, shamt); | ||||
| 				X[rd] <= sext(sh_val); | ||||
| 			}  | ||||
| 		} | ||||
| 		SRAIW { | ||||
| 			encoding: b0100000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0011011; | ||||
| 			args_disass:"x%rd$d, x%rs1$d, %shamt%"; | ||||
| 			if(rd != 0){ | ||||
| 				val sh_val[32] <= shra(X[rs1]{32}, shamt);	 | ||||
| 				X[rd] <= sext(sh_val); | ||||
| 			} | ||||
| 		} | ||||
| 		ADDW { | ||||
| 			encoding: b0000000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0111011; | ||||
| 			if(rd != 0){ | ||||
| 				val res[32] <= X[rs1]{32} + X[rs2]{32}; | ||||
| 				X[rd] <= sext(res); | ||||
| 			}  | ||||
| 		} | ||||
| 		SUBW { | ||||
| 			encoding: b0100000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0111011; | ||||
| 			if(rd != 0){ | ||||
| 				val res[32] <= X[rs1]{32} - X[rs2]{32}; | ||||
| 				X[rd] <= sext(res); | ||||
| 			}  | ||||
| 		} | ||||
| 		SLLW { | ||||
| 			encoding: b0000000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b0111011; | ||||
| 			args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 			if(rd != 0){ | ||||
| 				val mask[32] <= 0x1f; | ||||
| 				val count[32] <= X[rs2]{32} & mask; | ||||
| 				val sh_val[32] <= shll(X[rs1]{32}, count); | ||||
| 				X[rd] <= sext(sh_val); | ||||
| 			}  | ||||
| 		} | ||||
| 		SRLW { | ||||
| 			encoding: b0000000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011; | ||||
| 			args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 			if(rd != 0){ | ||||
|     instructions{ | ||||
|         LWU { //    80000104: 0000ef03            lwu t5,0(ra) | ||||
|             encoding: imm[11:0]s | rs1[4:0] | b110 | rd[4:0] | b0000011; | ||||
|             args_disass:"x%rd$d, %imm%(x%rs1$d)"; | ||||
|             val offs[XLEN] <= X[rs1]+imm; | ||||
|             if(rd!=0) X[rd]<=zext(MEM[offs]{32}); | ||||
|         } | ||||
|         LD{ | ||||
|             encoding: imm[11:0]s | rs1[4:0] | b011 | rd[4:0] | b0000011; | ||||
|             args_disass:"x%rd$d, %imm%(x%rs1$d)"; | ||||
|             val offs[XLEN] <= X[rs1]+imm; | ||||
|             if(rd!=0) X[rd]<=sext(MEM[offs]{64}); | ||||
|         } | ||||
|         SD{ | ||||
|             encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b011 | imm[4:0]s | b0100011; | ||||
|             args_disass:"x%rs2$d, %imm%(x%rs1$d)"; | ||||
|             val offs[XLEN] <= X[rs1] + imm; | ||||
|             MEM[offs]{64} <= X[rs2]; | ||||
|         } | ||||
|         SLLI { | ||||
|             encoding: b000000 | shamt[5:0] | rs1[4:0] | b001 | rd[4:0] | b0010011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, %shamt%"; | ||||
|             if(rd != 0) X[rd] <= shll(X[rs1], shamt); | ||||
|         } | ||||
|         SRLI { | ||||
|             encoding: b000000 | shamt[5:0] | rs1[4:0] | b101 | rd[4:0] | b0010011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, %shamt%"; | ||||
|             if(rd != 0) X[rd] <= shrl(X[rs1], shamt); | ||||
|         } | ||||
|         SRAI { | ||||
|             encoding: b010000 | shamt[5:0] | rs1[4:0] | b101 | rd[4:0] | b0010011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, %shamt%"; | ||||
|             if(rd != 0) X[rd] <= shra(X[rs1], shamt); | ||||
|         } | ||||
|         ADDIW { | ||||
|             encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b0011011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, %imm%"; | ||||
|             if(rd != 0){ | ||||
|                 val res[32] <= X[rs1]{32} + imm; | ||||
|                 X[rd] <= sext(res); | ||||
|             }  | ||||
|         } | ||||
|         SLLIW { | ||||
|             encoding: b0000000 | shamt[4:0] | rs1[4:0] | b001 | rd[4:0] | b0011011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, %shamt%"; | ||||
|             if(rd != 0){ | ||||
|                 val sh_val[32] <= shll(X[rs1]{32}, shamt); | ||||
|                 X[rd] <= sext(sh_val); | ||||
|             }  | ||||
|         } | ||||
|         SRLIW { | ||||
|             encoding: b0000000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0011011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, %shamt%"; | ||||
|             if(rd != 0){ | ||||
|                 val sh_val[32] <= shrl(X[rs1]{32}, shamt); | ||||
|                 X[rd] <= sext(sh_val); | ||||
|             }  | ||||
|         } | ||||
|         SRAIW { | ||||
|             encoding: b0100000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0011011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, %shamt%"; | ||||
|             if(rd != 0){ | ||||
|                 val sh_val[32] <= shra(X[rs1]{32}, shamt);     | ||||
|                 X[rd] <= sext(sh_val); | ||||
|             } | ||||
|         } | ||||
|         ADDW { | ||||
|             encoding: b0000000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0111011; | ||||
|             if(rd != 0){ | ||||
|                 val res[32] <= X[rs1]{32} + X[rs2]{32}; | ||||
|                 X[rd] <= sext(res); | ||||
|             }  | ||||
|         } | ||||
|         SUBW { | ||||
|             encoding: b0100000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0111011; | ||||
|             if(rd != 0){ | ||||
|                 val res[32] <= X[rs1]{32} - X[rs2]{32}; | ||||
|                 X[rd] <= sext(res); | ||||
|             }  | ||||
|         } | ||||
|         SLLW { | ||||
|             encoding: b0000000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b0111011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0){ | ||||
|                 val mask[32] <= 0x1f; | ||||
|                 val count[32] <= X[rs2]{32} & mask; | ||||
| 				val sh_val[32] <= shrl(X[rs1]{32}, count); | ||||
| 				X[rd] <= sext(sh_val); | ||||
| 			}  | ||||
| 		} | ||||
| 		SRAW { | ||||
| 			encoding: b0100000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011; | ||||
| 			args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 			if(rd != 0){ | ||||
|                 val sh_val[32] <= shll(X[rs1]{32}, count); | ||||
|                 X[rd] <= sext(sh_val); | ||||
|             }  | ||||
|         } | ||||
|         SRLW { | ||||
|             encoding: b0000000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0){ | ||||
|                 val mask[32] <= 0x1f; | ||||
|                 val count[32] <= X[rs2]{32} & mask; | ||||
| 				val sh_val[32] <= shra(X[rs1]{32}, count); | ||||
| 				X[rd] <= sext(sh_val); | ||||
| 			}  | ||||
| 		} | ||||
| 	}	 | ||||
|                 val sh_val[32] <= shrl(X[rs1]{32}, count); | ||||
|                 X[rd] <= sext(sh_val); | ||||
|             }  | ||||
|         } | ||||
|         SRAW { | ||||
|             encoding: b0100000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0){ | ||||
|                 val mask[32] <= 0x1f; | ||||
|                 val count[32] <= X[rs2]{32} & mask; | ||||
|                 val sh_val[32] <= shra(X[rs1]{32}, count); | ||||
|                 X[rd] <= sext(sh_val); | ||||
|             }  | ||||
|         } | ||||
|     }     | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,41 +1,41 @@ | ||||
| import "RV64IBase.core_desc" | ||||
|  | ||||
| InsructionSet RV64M extends RV64IBase { | ||||
| 	instructions{        | ||||
| 		MULW{ | ||||
| 			encoding: b0000001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0111011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 		    if(rd != 0){ | ||||
| 		    	X[rd]<= X[rs1] * X[rs2]; | ||||
| 		    } | ||||
| 		} | ||||
| 		DIVW { | ||||
| 			encoding: b0000001 | rs2[4:0] | rs1[4:0] | b100 | rd[4:0] | b0111011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 		    if(rd != 0){ | ||||
| 		    	X[rd] <= X[rs1]s / X[rs2]s; | ||||
| 		    } | ||||
| 		} | ||||
| 		DIVUW { | ||||
| 			encoding: b0000001 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 		    if(rd != 0){ | ||||
| 		    	X[rd] <= X[rs1] / X[rs2]; | ||||
| 		    } | ||||
| 		} | ||||
| 		REMW { | ||||
| 			encoding: b0000001 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0111011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 		    if(rd != 0){ | ||||
| 		    	X[rd] <= X[rs1]s % X[rs2]s; | ||||
| 		    } | ||||
| 		} | ||||
| 		REMUW { | ||||
| 			encoding: b0000001 | rs2[4:0] | rs1[4:0] | b111 | rd[4:0] | b0111011; | ||||
| 		    args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
| 		    if(rd != 0){ | ||||
| 		    	X[rd] <= X[rs1] % X[rs2]; | ||||
| 		    } | ||||
| 		} | ||||
| 	} | ||||
|     instructions{        | ||||
|         MULW{ | ||||
|             encoding: b0000001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0111011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0){ | ||||
|                 X[rd]<= X[rs1] * X[rs2]; | ||||
|             } | ||||
|         } | ||||
|         DIVW { | ||||
|             encoding: b0000001 | rs2[4:0] | rs1[4:0] | b100 | rd[4:0] | b0111011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0){ | ||||
|                 X[rd] <= X[rs1]s / X[rs2]s; | ||||
|             } | ||||
|         } | ||||
|         DIVUW { | ||||
|             encoding: b0000001 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0){ | ||||
|                 X[rd] <= X[rs1] / X[rs2]; | ||||
|             } | ||||
|         } | ||||
|         REMW { | ||||
|             encoding: b0000001 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0111011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0){ | ||||
|                 X[rd] <= X[rs1]s % X[rs2]s; | ||||
|             } | ||||
|         } | ||||
|         REMUW { | ||||
|             encoding: b0000001 | rs2[4:0] | rs1[4:0] | b111 | rd[4:0] | b0111011; | ||||
|             args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; | ||||
|             if(rd != 0){ | ||||
|                 X[rd] <= X[rs1] % X[rs2]; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -8,7 +8,6 @@ import "RV64IBase.core_desc" | ||||
| //import "RV64M.core_desc" | ||||
| import "RV64A.core_desc" | ||||
|  | ||||
|  | ||||
| Core RV32IMAC provides RV32IBase, RV32M, RV32A, RV32IC { | ||||
|     template:"vm_riscv.in.cpp"; | ||||
|     constants { | ||||
| @@ -17,8 +16,8 @@ Core RV32IMAC provides RV32IBase, RV32M, RV32A, RV32IC { | ||||
|         // definitions for the architecture wrapper | ||||
|         //          XL    ZYXWVUTSRQPONMLKJIHGFEDCBA | ||||
|         MISA_VAL:=0b01000000000101000001000100000101; | ||||
|         PGSIZE := 4096; //1 << 12; | ||||
|         PGMASK := 4095; //PGSIZE-1 | ||||
|         PGSIZE := 0x1000; //1 << 12; | ||||
|         PGMASK := 0xfff; //PGSIZE-1 | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -30,8 +29,8 @@ Core RV32GC provides RV32IBase, RV32M, RV32A, RV32IC, RV32F, RV32FC, RV32D, RV32 | ||||
|         // definitions for the architecture wrapper | ||||
|         //          XL    ZYXWVUTSRQPONMLKJIHGFEDCBA | ||||
|         MISA_VAL:=0b01000000000101000001000100101101; | ||||
|         PGSIZE := 4096; //1 << 12; | ||||
|         PGMASK := 4095; //PGSIZE-1 | ||||
|         PGSIZE := 0x1000; //1 << 12; | ||||
|         PGMASK := 0xfff; //PGSIZE-1 | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -44,7 +43,7 @@ Core RV64IA provides RV64IBase, RV64A, RV32A { | ||||
|         // definitions for the architecture wrapper | ||||
|         //          XL    ZYXWVUTSRQPONMLKJIHGFEDCBA | ||||
|         MISA_VAL:=0b10000000000001000000000100000001; | ||||
|         PGSIZE := 4096; //1 << 12; | ||||
|         PGMASK := 4095; //PGSIZE-1 | ||||
|         PGSIZE := 0x1000; //1 << 12; | ||||
|         PGMASK := 0xfff; //PGSIZE-1 | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -80,6 +80,8 @@ struct traits<${coreDef.name.toLowerCase()}> { | ||||
|  | ||||
|     using addr_t = uint${addrDataWidth}_t; | ||||
|  | ||||
|     using code_word_t = uint${addrDataWidth}_t; //TODO: check removal | ||||
|  | ||||
|     using virt_addr_t = iss::typed_addr_t<iss::address_type::VIRTUAL>; | ||||
|  | ||||
|     using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>; | ||||
|   | ||||
| @@ -320,6 +320,8 @@ template <typename ARCH> inline void vm_impl<ARCH>::gen_trap_check(llvm::BasicBl | ||||
|                           bb, this->trap_blk, 1); | ||||
| } | ||||
|  | ||||
| } // namespace ${coreDef.name.toLowerCase()} | ||||
|  | ||||
| template <> | ||||
| std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreDef.name.toLowerCase()} *core, unsigned short port, bool dump) { | ||||
|     std::unique_ptr<${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>> ret = | ||||
|   | ||||
| @@ -48,7 +48,7 @@ struct traits<rv32gc> { | ||||
|  | ||||
| 	constexpr static char const* const core_type = "RV32GC"; | ||||
|      | ||||
|     enum constants {XLEN=32, FLEN=64, PCLEN=32, MISA_VAL=1075056941, PGSIZE=4096, PGMASK=4095}; | ||||
|     enum constants {XLEN=32, FLEN=64, PCLEN=32, MISA_VAL=0b1000000000101000001000100101101, PGSIZE=0x1000, PGMASK=0xfff}; | ||||
|  | ||||
|     constexpr static unsigned FP_REGS_SIZE = 64; | ||||
|  | ||||
|   | ||||
| @@ -48,7 +48,7 @@ struct traits<rv32imac> { | ||||
|  | ||||
| 	constexpr static char const* const core_type = "RV32IMAC"; | ||||
|      | ||||
|     enum constants {XLEN=32, PCLEN=32, MISA_VAL=1075056901, PGSIZE=4096, PGMASK=4095}; | ||||
|     enum constants {XLEN=32, PCLEN=32, MISA_VAL=0b1000000000101000001000100000101, PGSIZE=0x1000, PGMASK=0xfff}; | ||||
|  | ||||
|     constexpr static unsigned FP_REGS_SIZE = 0; | ||||
|  | ||||
|   | ||||
| @@ -48,7 +48,7 @@ struct traits<rv64ia> { | ||||
|  | ||||
| 	constexpr static char const* const core_type = "RV64IA"; | ||||
|      | ||||
|     enum constants {XLEN=64, PCLEN=64, MISA_VAL=2147746049, PGSIZE=4096, PGMASK=4095}; | ||||
|     enum constants {XLEN=64, PCLEN=64, MISA_VAL=0b10000000000001000000000100000001, PGSIZE=0x1000, PGMASK=0xfff}; | ||||
|  | ||||
|     constexpr static unsigned FP_REGS_SIZE = 0; | ||||
|  | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user