data/full_repos/permissive/202328805/simplerv32i.v
1: b'%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:143: Operator ASSIGN expects 14 bits on the Assign RHS, but Assign RHS\'s VARREF \'reg_pc_current\' generates 32 bits.\n                                                                      : ... In instance SimpleRV32I\n      mem_addr    = (reg_pc_current);\n                  ^\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:168: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS\'s SIGNED generates 12 bits.\n                                                                      : ... In instance SimpleRV32I\n      reg_op2_next = $signed(mem_rdata_q_current[31:20]);\n                   ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:172: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS\'s SEL generates 12 bits.\n                                                                      : ... In instance SimpleRV32I\n      reg_op2_next = mem_rdata_q_current[31:20];\n                   ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:176: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS\'s SEL generates 12 bits.\n                                                                      : ... In instance SimpleRV32I\n      reg_op2_next = mem_rdata_q_current[31:20];\n                   ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:180: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS\'s SEL generates 12 bits.\n                                                                      : ... In instance SimpleRV32I\n      reg_op2_next = mem_rdata_q_current[31:20];\n                   ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:184: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS\'s SEL generates 12 bits.\n                                                                      : ... In instance SimpleRV32I\n      reg_op2_next = mem_rdata_q_current[31:20];\n                   ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:188: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS\'s SEL generates 12 bits.\n                                                                      : ... In instance SimpleRV32I\n      reg_op2_next = mem_rdata_q_current[31:20];\n                   ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:192: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS\'s SEL generates 5 bits.\n                                                                      : ... In instance SimpleRV32I\n      reg_op2_next = mem_rdata_q_current[24:20];\n                   ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:196: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS\'s SEL generates 5 bits.\n                                                                      : ... In instance SimpleRV32I\n      reg_op2_next = mem_rdata_q_current[24:20];\n                   ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:200: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS\'s SEL generates 5 bits.\n                                                                      : ... In instance SimpleRV32I\n      reg_op2_next = mem_rdata_q_current[24:20];\n                   ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:222: Operator ADD expects 32 bits on the LHS, but LHS\'s SIGNED generates 12 bits.\n                                                                      : ... In instance SimpleRV32I\n       mem_addr = $signed(mem_rdata_q_current[31:20]) + $signed(cpu_regs_current[mem_rdata_q_current[19:15]]);\n                                                      ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:222: Operator ASSIGN expects 14 bits on the Assign RHS, but Assign RHS\'s ADD generates 32 bits.\n                                                                      : ... In instance SimpleRV32I\n       mem_addr = $signed(mem_rdata_q_current[31:20]) + $signed(cpu_regs_current[mem_rdata_q_current[19:15]]);\n                ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:225: Operator ADD expects 32 bits on the LHS, but LHS\'s SEL generates 12 bits.\n                                                                      : ... In instance SimpleRV32I\n       mem_addr = mem_rdata_q_current[31:20] + cpu_regs_current[mem_rdata_q_current[19:15]];\n                                             ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:225: Operator ASSIGN expects 14 bits on the Assign RHS, but Assign RHS\'s ADD generates 32 bits.\n                                                                      : ... In instance SimpleRV32I\n       mem_addr = mem_rdata_q_current[31:20] + cpu_regs_current[mem_rdata_q_current[19:15]];\n                ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:228: Operator ADD expects 32 bits on the LHS, but LHS\'s SEL generates 12 bits.\n                                                                      : ... In instance SimpleRV32I\n       mem_addr = mem_rdata_q_current[31:20] + cpu_regs_current[mem_rdata_q_current[19:15]];\n                                             ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:228: Operator ASSIGN expects 14 bits on the Assign RHS, but Assign RHS\'s ADD generates 32 bits.\n                                                                      : ... In instance SimpleRV32I\n       mem_addr = mem_rdata_q_current[31:20] + cpu_regs_current[mem_rdata_q_current[19:15]];\n                ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:231: Operator ADD expects 32 bits on the LHS, but LHS\'s SEL generates 12 bits.\n                                                                      : ... In instance SimpleRV32I\n       mem_addr = mem_rdata_q_current[31:20] + cpu_regs_current[mem_rdata_q_current[19:15]];\n                                             ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:231: Operator ASSIGN expects 14 bits on the Assign RHS, but Assign RHS\'s ADD generates 32 bits.\n                                                                      : ... In instance SimpleRV32I\n       mem_addr = mem_rdata_q_current[31:20] + cpu_regs_current[mem_rdata_q_current[19:15]];\n                ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:234: Operator ADD expects 32 bits on the LHS, but LHS\'s SEL generates 12 bits.\n                                                                      : ... In instance SimpleRV32I\n       mem_addr = mem_rdata_q_current[31:20] + cpu_regs_current[mem_rdata_q_current[19:15]];\n                                             ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:234: Operator ASSIGN expects 14 bits on the Assign RHS, but Assign RHS\'s ADD generates 32 bits.\n                                                                      : ... In instance SimpleRV32I\n       mem_addr = mem_rdata_q_current[31:20] + cpu_regs_current[mem_rdata_q_current[19:15]];\n                ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:245: Operator ASSIGN expects 1 bits on the Assign RHS, but Assign RHS\'s CONST \'4\'hf\' generates 4 bits.\n                                                                      : ... In instance SimpleRV32I\n       mem_wstrb = 4\'b1111;\n                 ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:246: Operator ADD expects 32 bits on the LHS, but LHS\'s SIGNED generates 12 bits.\n                                                                      : ... In instance SimpleRV32I\n       mem_addr  = $signed({mem_rdata_q_current[31:25],mem_rdata_q_current[11:7]}) + $signed(cpu_regs_current[mem_rdata_q_current[19:15]]); \n                                                                                   ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:246: Operator ASSIGN expects 14 bits on the Assign RHS, but Assign RHS\'s ADD generates 32 bits.\n                                                                      : ... In instance SimpleRV32I\n       mem_addr  = $signed({mem_rdata_q_current[31:25],mem_rdata_q_current[11:7]}) + $signed(cpu_regs_current[mem_rdata_q_current[19:15]]); \n                 ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:249: Operator ASSIGN expects 1 bits on the Assign RHS, but Assign RHS\'s CONST \'4\'h3\' generates 4 bits.\n                                                                      : ... In instance SimpleRV32I\n       mem_wstrb  = 4\'b0011;\n                  ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:250: Operator ADD expects 32 bits on the LHS, but LHS\'s REPLICATE generates 12 bits.\n                                                                      : ... In instance SimpleRV32I\n       mem_addr  = {mem_rdata_q_current[31:25],mem_rdata_q_current[11:7]} + cpu_regs_current[mem_rdata_q_current[19:15]];\n                                                                          ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:250: Operator ASSIGN expects 14 bits on the Assign RHS, but Assign RHS\'s ADD generates 32 bits.\n                                                                      : ... In instance SimpleRV32I\n       mem_addr  = {mem_rdata_q_current[31:25],mem_rdata_q_current[11:7]} + cpu_regs_current[mem_rdata_q_current[19:15]];\n                 ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:253: Operator ASSIGN expects 1 bits on the Assign RHS, but Assign RHS\'s CONST \'4\'h1\' generates 4 bits.\n                                                                      : ... In instance SimpleRV32I\n       mem_wstrb  = 4\'b0001;\n                  ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:254: Operator ADD expects 32 bits on the LHS, but LHS\'s REPLICATE generates 12 bits.\n                                                                      : ... In instance SimpleRV32I\n       mem_addr  = {mem_rdata_q_current[31:25],mem_rdata_q_current[11:7]} + cpu_regs_current[mem_rdata_q_current[19:15]];\n                                                                          ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:254: Operator ASSIGN expects 14 bits on the Assign RHS, but Assign RHS\'s ADD generates 32 bits.\n                                                                      : ... In instance SimpleRV32I\n       mem_addr  = {mem_rdata_q_current[31:25],mem_rdata_q_current[11:7]} + cpu_regs_current[mem_rdata_q_current[19:15]];\n                 ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:350: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS\'s LTS generates 1 bits.\n                                                                      : ... In instance SimpleRV32I\n       cpu_regs_next[mem_rdata_q_current[11:7]] = $signed(reg_op1_current) < $signed(reg_op2_current);\n                                                ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:353: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS\'s LT generates 1 bits.\n                                                                      : ... In instance SimpleRV32I\n       cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current < reg_op2_current;\n                                                ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:377: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS\'s LTS generates 1 bits.\n                                                                      : ... In instance SimpleRV32I\n       cpu_regs_next[mem_rdata_q_current[11:7]] = $signed(reg_op1_current) < $signed(reg_op2_current);\n                                                ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:380: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS\'s LT generates 1 bits.\n                                                                      : ... In instance SimpleRV32I\n       cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current < reg_op2_current;\n                                                ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:408: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS\'s SIGNED generates 8 bits.\n                                                                      : ... In instance SimpleRV32I\n        cpu_regs_next[mem_rdata_q_current[11:7]] = $signed(mem_rdata[7:0]);\n                                                 ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:411: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS\'s SIGNED generates 16 bits.\n                                                                      : ... In instance SimpleRV32I\n        cpu_regs_next[mem_rdata_q_current[11:7]] = $signed(mem_rdata[15:0]);\n                                                 ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:414: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS\'s SIGNED generates 8 bits.\n                                                                      : ... In instance SimpleRV32I\n        cpu_regs_next[mem_rdata_q_current[11:7]] = $signed(mem_rdata[7:0]);\n                                                 ^\n%Warning-WIDTH: data/full_repos/permissive/202328805/simplerv32i.v:417: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS\'s SIGNED generates 16 bits.\n                                                                      : ... In instance SimpleRV32I\n        cpu_regs_next[mem_rdata_q_current[11:7]] = $signed(mem_rdata[15:0]);\n                                                 ^\n%Error: Exiting due to 37 warning(s)\n'
module SimpleRV32I
(

	input 				clk, reset,
	
	input 				debug_en,
	output [31:0] 		debug_pc_out,



	input 				mem_ready,

	output reg [13:0] mem_addr,
	output reg [31:0] mem_wdata,
	output reg [ 0:0] mem_wstrb,
	input      [31:0] mem_rdata,
	
	input 				mem_vld,
	output reg 			mem_req

);



	localparam integer regfile_size = 32;
	localparam integer regindex_bits = 5;

	reg [31:0] reg_pc_current, reg_pc_next;
	reg [31:0] reg_op1_current, reg_op1_next;
	reg [31:0] reg_op2_current, reg_op2_next, reg_out;
	reg [31:0] cpu_regs_current [0:regfile_size-1];
	reg [31:0] cpu_regs_next [0:regfile_size-1];
	reg [31:0] mem_rdata_q_current, mem_rdata_q_next;

	integer i;

	localparam cpu_state_alu_exec = 8'b00010000;
	localparam cpu_state_decode   = 8'b00001000;
	localparam cpu_state_fetch  	= 8'b00000100;
	localparam cpu_state_start    = 8'b00000010;
	localparam cpu_state_init	   = 8'b00000001;

	reg [7:0] cpu_state_current, cpu_state_next;

	always@(posedge clk) begin
		if(reset) begin
			cpu_state_current 			<= cpu_state_init;
			reg_pc_current 				<= 0;
			reg_op1_current 				<= 0;
			reg_op2_current 				<= 0;
			mem_rdata_q_current 			<= 0;
			for (i = 0; i < regfile_size; i = i+1) begin
				cpu_regs_current[i] 	<= 0;
			end
		end
		else begin
			cpu_state_current 			<= cpu_state_next;
			reg_pc_current 				<= reg_pc_next;
			reg_op1_current 				<= reg_op1_next;
			reg_op2_current 				<= reg_op2_next;
			mem_rdata_q_current 			<= mem_rdata_q_next;
			for (i = 0; i < regfile_size; i = i+1) begin
					cpu_regs_current[i] 	<= cpu_regs_next[i];
			end
		end
	end


	always @(	cpu_regs_current[0], cpu_regs_current[1], cpu_regs_current[2], cpu_regs_current[3],
				cpu_regs_current[4], cpu_regs_current[5], cpu_regs_current[6], cpu_regs_current[7],
				cpu_regs_current[8], cpu_regs_current[9], cpu_regs_current[10], cpu_regs_current[11],
				cpu_regs_current[12], cpu_regs_current[13], cpu_regs_current[14], cpu_regs_current[15],
				cpu_regs_current[16], cpu_regs_current[17], cpu_regs_current[18], cpu_regs_current[19],
				cpu_regs_current[20], cpu_regs_current[21], cpu_regs_current[22], cpu_regs_current[23],
				cpu_regs_current[24], cpu_regs_current[25], cpu_regs_current[26], cpu_regs_current[27],
				cpu_regs_current[28], cpu_regs_current[29], cpu_regs_current[30], cpu_regs_current[31],
				debug_en, mem_ready, mem_rdata, mem_vld,
				reg_pc_current, reg_op1_current, reg_op2_current,
				mem_rdata_q_current, cpu_state_current) begin
		cpu_state_next 		= cpu_state_current;
		reg_pc_next 			= reg_pc_current;
		reg_op1_next 			= reg_op1_current;
		reg_op2_next 			= reg_op2_current;
		mem_rdata_q_next 		= mem_rdata_q_current;


		mem_addr					= 0;
		mem_wdata 				= 0;
		mem_wstrb 				= 0;
		mem_req = 0;
		for (i = 0; i < regfile_size; i = i+1) begin
			cpu_regs_next[i] 	= cpu_regs_current[i];
		end
		
		case(cpu_state_current)
			cpu_state_init: begin
				reg_pc_next 			= 0;
				reg_op1_next 			= 0;
				reg_op2_next 			= 0;
				cpu_state_next 		= cpu_state_start;
				
				for (i = 0; i < regfile_size; i = i+1)
					cpu_regs_next[i] 	= 0;

				cpu_regs_next[2] 		= 4096;
			end
			cpu_state_start: begin
				if(mem_vld) begin

						mem_req = 1'b1;
						mem_addr  		= (reg_pc_current);
						cpu_state_next = cpu_state_fetch;

				end
			end
			cpu_state_fetch: begin
				if(mem_vld) begin
					mem_rdata_q_next 	= mem_rdata;

					cpu_state_next 	= cpu_state_decode;
				end
			end
			cpu_state_decode: begin
				if(mem_rdata_q_current[6:5] == 2'b01 && mem_rdata_q_current[4:2] == 3'b100) begin

					reg_op1_next 	= cpu_regs_current[mem_rdata_q_current[19:15]];
					reg_op2_next 	= cpu_regs_current[mem_rdata_q_current[24:20]];
					cpu_state_next = cpu_state_alu_exec;
				end
				else if(mem_rdata_q_current[6:5] == 2'b00 && mem_rdata_q_current[4:2] == 3'b100) begin

					cpu_state_next = cpu_state_alu_exec;
					if(mem_rdata_q_current[14:12] == 3'b000) begin

						reg_op1_next = cpu_regs_current[mem_rdata_q_current[19:15]];
						reg_op2_next = $signed(mem_rdata_q_current[31:20]);
					end
					else if(mem_rdata_q_current[14:12] == 3'b010) begin
						reg_op1_next = cpu_regs_current[mem_rdata_q_current[19:15]];
						reg_op2_next = mem_rdata_q_current[31:20];
					end
					else if(mem_rdata_q_current[14:12] == 3'b011) begin
						reg_op1_next = cpu_regs_current[mem_rdata_q_current[19:15]];
						reg_op2_next = mem_rdata_q_current[31:20];
					end
					else if(mem_rdata_q_current[14:12] == 3'b100) begin
						reg_op1_next = cpu_regs_current[mem_rdata_q_current[19:15]];
						reg_op2_next = mem_rdata_q_current[31:20];
					end
					else if(mem_rdata_q_current[14:12] == 3'b110) begin
						reg_op1_next = cpu_regs_current[mem_rdata_q_current[19:15]];
						reg_op2_next = mem_rdata_q_current[31:20];
					end
					else if(mem_rdata_q_current[14:12] == 3'b111) begin
						reg_op1_next = cpu_regs_current[mem_rdata_q_current[19:15]];
						reg_op2_next = mem_rdata_q_current[31:20];
					end
					else if(mem_rdata_q_current[14:12] == 3'b001) begin
						reg_op1_next = cpu_regs_current[mem_rdata_q_current[19:15]];
						reg_op2_next = mem_rdata_q_current[24:20];
					end
					else if(mem_rdata_q_current[31:25] == 7'b0000000 && mem_rdata_q_current[14:12] == 3'b101) begin
						reg_op1_next = cpu_regs_current[mem_rdata_q_current[19:15]];
						reg_op2_next = mem_rdata_q_current[24:20];
					end
					else if(mem_rdata_q_current[31:25] == 7'b0100000 && mem_rdata_q_current[14:12] == 3'b101) begin
						reg_op1_next = cpu_regs_current[mem_rdata_q_current[19:15]];
						reg_op2_next = mem_rdata_q_current[24:20];
					end
				end
				else if(mem_rdata_q_current[6:5] == 2'b01 && mem_rdata_q_current[4:2] == 3'b101) begin
					if(mem_rdata_q_current[11:7] != 0) begin					
						cpu_regs_next[mem_rdata_q_current[11:7]] = {mem_rdata_q_current[31:12], 12'b000000000000};
					end					
					reg_pc_next = reg_pc_current + 4;
					cpu_state_next = cpu_state_start;
				end
				else if(mem_rdata_q_current[6:5] == 2'b00 && mem_rdata_q_current[4:2] == 3'b101) begin
					if(mem_rdata_q_current[11:7] != 0) begin					
						cpu_regs_next[mem_rdata_q_current[11:7]] = reg_pc_current + {mem_rdata_q_current[31:12], 12'b000000000000};
					end
					reg_pc_next 										= reg_pc_current + 4;
					cpu_state_next 									= cpu_state_start;
				end
				else if(mem_rdata_q_current[6:5] == 2'b00 && mem_rdata_q_current[4:2] == 3'b000) begin
					if(mem_vld) begin
						cpu_state_next = cpu_state_alu_exec;
						mem_req = 1;
						if(mem_rdata_q_current[14:12] == 3'b010) begin
							mem_addr	= $signed(mem_rdata_q_current[31:20]) + $signed(cpu_regs_current[mem_rdata_q_current[19:15]]);
						end
						else if(mem_rdata_q_current[14:12] == 3'b000) begin
							mem_addr	= mem_rdata_q_current[31:20] + cpu_regs_current[mem_rdata_q_current[19:15]];
						end
						else if(mem_rdata_q_current[14:12] == 3'b001) begin
							mem_addr	= mem_rdata_q_current[31:20] + cpu_regs_current[mem_rdata_q_current[19:15]];
						end
						else if(mem_rdata_q_current[14:12] == 3'b100) begin
							mem_addr	= mem_rdata_q_current[31:20] + cpu_regs_current[mem_rdata_q_current[19:15]];
						end
						else if(mem_rdata_q_current[14:12] == 3'b101) begin
							mem_addr	= mem_rdata_q_current[31:20] + cpu_regs_current[mem_rdata_q_current[19:15]];
						end
					end
				end
				else if(mem_rdata_q_current[6:5] == 2'b01 && mem_rdata_q_current[4:2] == 3'b000) begin
					if(mem_vld) begin
						mem_wdata 		= cpu_regs_current[mem_rdata_q_current[24:20]];
						reg_pc_next 	= reg_pc_current + 4;
						cpu_state_next = cpu_state_start;
						mem_req = 1;
						if(mem_rdata_q_current[14:12] == 3'b010) begin
							mem_wstrb	= 4'b1111;
							mem_addr		= $signed({mem_rdata_q_current[31:25],mem_rdata_q_current[11:7]}) + $signed(cpu_regs_current[mem_rdata_q_current[19:15]]);	
						end
						else if(mem_rdata_q_current[14:12] == 3'b001) begin
							mem_wstrb 	= 4'b0011;
							mem_addr		= {mem_rdata_q_current[31:25],mem_rdata_q_current[11:7]} + cpu_regs_current[mem_rdata_q_current[19:15]];
						end
						else if(mem_rdata_q_current[14:12] == 3'b000) begin
							mem_wstrb 	= 4'b0001;
							mem_addr		= {mem_rdata_q_current[31:25],mem_rdata_q_current[11:7]} + cpu_regs_current[mem_rdata_q_current[19:15]];
						end
					end
				end
				else if(mem_rdata_q_current[6:5] == 2'b11 && mem_rdata_q_current[4:2] == 3'b011) begin
					cpu_state_next = cpu_state_start;
					reg_pc_next =  $signed(reg_pc_current) + {{12{mem_rdata_q_current[31]}},mem_rdata_q_current[19:12],mem_rdata_q_current[20],mem_rdata_q_current[30:21],1'b0};
					if(mem_rdata_q_current[11:7] != 0) begin
						cpu_regs_next[mem_rdata_q_current[11:7]] = reg_pc_current + 4;
					end
				end
				else if(mem_rdata_q_current[6:5] == 2'b11 && mem_rdata_q_current[4:2] == 3'b001) begin
					cpu_state_next	= cpu_state_start;		
					reg_pc_next 	=  $signed(cpu_regs_current[mem_rdata_q_current[19:15]]) + {{21{mem_rdata_q_current[31]}},mem_rdata_q_current[30:20]};				
					if(mem_rdata_q_current[11:7] != 0) begin
						cpu_regs_next[mem_rdata_q_current[11:7]] = reg_pc_current + 4;
					end
				end
				else if(mem_rdata_q_current[6:5] == 2'b11 && mem_rdata_q_current[4:2] == 3'b000) begin
					cpu_state_next = cpu_state_start;
					if(mem_rdata_q_current[14:12] == 3'b000) begin

						if(cpu_regs_current[mem_rdata_q_current[24:20]] == cpu_regs_current[mem_rdata_q_current[19:15]]) begin
							reg_pc_next = reg_pc_current + {{20{mem_rdata_q_current[31]}},mem_rdata_q_current[7],mem_rdata_q_current[30:25],mem_rdata_q_current[11:8],1'b0};
						end
						else begin
							reg_pc_next = reg_pc_current + 4;							
						end
					end
					else if(mem_rdata_q_current[14:12] == 3'b001) begin
						if(cpu_regs_current[mem_rdata_q_current[24:20]] != cpu_regs_current[mem_rdata_q_current[19:15]]) begin

							reg_pc_next = reg_pc_current + {{20{mem_rdata_q_current[31]}},mem_rdata_q_current[7],mem_rdata_q_current[30:25],mem_rdata_q_current[11:8],1'b0};
						end
						else begin
							reg_pc_next = reg_pc_current + 4;							
						end
					end
					else if(mem_rdata_q_current[14:12] == 3'b100) begin
						if($signed(cpu_regs_current[mem_rdata_q_current[19:15]]) < $signed(cpu_regs_current[mem_rdata_q_current[24:20]])) begin
							reg_pc_next = reg_pc_current + {{20{mem_rdata_q_current[31]}},mem_rdata_q_current[7],mem_rdata_q_current[30:25],mem_rdata_q_current[11:8],1'b0};

						end
						else begin
							reg_pc_next = reg_pc_current + 4;							
						end	
					end					
					else if(mem_rdata_q_current[14:12] == 3'b110) begin
						if(cpu_regs_current[mem_rdata_q_current[19:15]] < cpu_regs_current[mem_rdata_q_current[24:20]]) begin
							reg_pc_next = reg_pc_current + {{20{mem_rdata_q_current[31]}},mem_rdata_q_current[7],mem_rdata_q_current[30:25],mem_rdata_q_current[11:8],1'b0};
						end
						else begin
							reg_pc_next = reg_pc_current + 4;							
						end	
					end
					else if(mem_rdata_q_current[14:12] == 3'b101) begin
						if($signed(cpu_regs_current[mem_rdata_q_current[19:15]]) >= $signed(cpu_regs_current[mem_rdata_q_current[24:20]])) begin
							reg_pc_next = reg_pc_current + {{20{mem_rdata_q_current[31]}},mem_rdata_q_current[7],mem_rdata_q_current[30:25],mem_rdata_q_current[11:8],1'b0};
						end
						else begin
							reg_pc_next = reg_pc_current + 4;							
						end
					end
					else if(mem_rdata_q_current[14:12] == 3'b111) begin
						if(cpu_regs_current[mem_rdata_q_current[19:15]] >= cpu_regs_current[mem_rdata_q_current[24:20]]) begin
							reg_pc_next = reg_pc_current + {{20{mem_rdata_q_current[31]}},mem_rdata_q_current[7],mem_rdata_q_current[30:25],mem_rdata_q_current[11:8],1'b0};
						end
						else begin
							reg_pc_next = reg_pc_current + 4;							
						end
					end
					else begin
						$display("unknown instruction");

					end
				end
				else begin
					$display("Undefined Instruction");

				end
			end
			cpu_state_alu_exec: begin
				cpu_state_next = cpu_state_start;
				reg_pc_next 	= reg_pc_current + 4;
				if(mem_rdata_q_current[11:7] != 0) begin
					if(mem_rdata_q_current[6:5] == 2'b01 && mem_rdata_q_current[4:2] == 3'b100) begin
						if(mem_rdata_q_current[31:25] == 7'b0000000 && mem_rdata_q_current[14:12] == 3'b000) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current + reg_op2_current;
						end
						else if(mem_rdata_q_current[31:25] == 7'b0100000 && mem_rdata_q_current[14:12] == 3'b000) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current - reg_op2_current;
						end
						else if(mem_rdata_q_current[14:12] == 3'b001) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current << reg_op2_current[4:0];
						end
						else if(mem_rdata_q_current[14:12] == 3'b010) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = $signed(reg_op1_current) < $signed(reg_op2_current);
						end
						else if(mem_rdata_q_current[14:12] == 3'b011) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current < reg_op2_current;
						end
						else if(mem_rdata_q_current[14:12] == 3'b100) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current ^ reg_op2_current;
						end
						else if(mem_rdata_q_current[31:25] == 7'b0000000 && mem_rdata_q_current[14:12] == 3'b101) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current >> reg_op2_current[4:0];
						end
						else if(mem_rdata_q_current[31:25] == 7'b0100000 && mem_rdata_q_current[14:12] == 3'b101) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current >>> reg_op2_current[4:0];
						end
						else if(mem_rdata_q_current[14:12] == 3'b110) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current | reg_op2_current;
						end
						else if(mem_rdata_q_current[14:12] == 3'b111) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current & reg_op2_current;
						end
					end
					else if(mem_rdata_q_current[6:5] == 2'b00 && mem_rdata_q_current[4:2] == 3'b100) begin
						if(mem_rdata_q_current[14:12] == 3'b000) begin

							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current + reg_op2_current;
						end
						else if(mem_rdata_q_current[14:12] == 3'b010) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = $signed(reg_op1_current) < $signed(reg_op2_current);
						end
						else if(mem_rdata_q_current[14:12] == 3'b011) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current < reg_op2_current;
						end
						else if(mem_rdata_q_current[14:12] == 3'b100) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current ^ reg_op2_current;
						end
						else if(mem_rdata_q_current[14:12] == 3'b110) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current | reg_op2_current;
						end
						else if(mem_rdata_q_current[14:12] == 3'b111) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current & reg_op2_current;
						end
						else if(mem_rdata_q_current[14:12] == 3'b001) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current << reg_op2_current;
						end
						else if(mem_rdata_q_current[31:25] == 7'b0000000 && mem_rdata_q_current[14:12] == 3'b101) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current >> reg_op2_current;
						end
						else if(mem_rdata_q_current[31:25] == 7'b0100000 && mem_rdata_q_current[14:12] == 3'b101) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current >>> reg_op2_current;
						end
					end
					else if(mem_rdata_q_current[6:5] == 2'b00 && mem_rdata_q_current[4:2] == 3'b000) begin
						if(mem_vld) begin

							if(mem_rdata_q_current[14:12] == 3'b010) begin
								cpu_regs_next[mem_rdata_q_current[11:7]]	= mem_rdata;
							end
							else if(mem_rdata_q_current[14:12] == 3'b000) begin
								cpu_regs_next[mem_rdata_q_current[11:7]]	= $signed(mem_rdata[7:0]);
							end
							else if(mem_rdata_q_current[14:12] == 3'b001) begin
								cpu_regs_next[mem_rdata_q_current[11:7]]	= $signed(mem_rdata[15:0]);
							end
							else if(mem_rdata_q_current[14:12] == 3'b100) begin
								cpu_regs_next[mem_rdata_q_current[11:7]]	= $signed(mem_rdata[7:0]);
							end
							else if(mem_rdata_q_current[14:12] == 3'b101) begin
								cpu_regs_next[mem_rdata_q_current[11:7]]	= $signed(mem_rdata[15:0]);
							end
						end
						else begin
							cpu_state_next = cpu_state_alu_exec;
							reg_pc_next 	= reg_pc_current;
						end
					end
				end
			end
		endcase
	end
	
	assign debug_pc_out = reg_pc_current;

endmodule
module SimpleRV32I
(

	input 				clk, reset,
	
	input 				debug_en,
	output [31:0] 		debug_pc_out,



	input 				mem_ready,

	output reg [13:0] mem_addr,
	output reg [31:0] mem_wdata,
	output reg [ 0:0] mem_wstrb,
	input      [31:0] mem_rdata,
	
	input 				mem_vld,
	output reg 			mem_req

);




	localparam integer regfile_size = 32;
	localparam integer regindex_bits = 5;

	reg [31:0] reg_pc_current, reg_pc_next;
	reg [31:0] reg_op1_current, reg_op1_next;
	reg [31:0] reg_op2_current, reg_op2_next, reg_out;
	reg [31:0] cpu_regs_current [0:regfile_size-1];
	reg [31:0] cpu_regs_next [0:regfile_size-1];
	reg [31:0] mem_rdata_q_current, mem_rdata_q_next;

	integer i;

	localparam cpu_state_alu_exec = 8'b00010000;
	localparam cpu_state_decode   = 8'b00001000;
	localparam cpu_state_fetch  	= 8'b00000100;
	localparam cpu_state_start    = 8'b00000010;
	localparam cpu_state_init	   = 8'b00000001;

	reg [7:0] cpu_state_current, cpu_state_next;

	always@(posedge clk) begin
		if(reset) begin
			cpu_state_current 			<= cpu_state_init;
			reg_pc_current 				<= 0;
			reg_op1_current 				<= 0;
			reg_op2_current 				<= 0;
			mem_rdata_q_current 			<= 0;
			for (i = 0; i < regfile_size; i = i+1) begin
				cpu_regs_current[i] 	<= 0;
			end
		end
		else begin
			cpu_state_current 			<= cpu_state_next;
			reg_pc_current 				<= reg_pc_next;
			reg_op1_current 				<= reg_op1_next;
			reg_op2_current 				<= reg_op2_next;
			mem_rdata_q_current 			<= mem_rdata_q_next;
			for (i = 0; i < regfile_size; i = i+1) begin
					cpu_regs_current[i] 	<= cpu_regs_next[i];
			end
		end
	end


	always @(	cpu_regs_current[0], cpu_regs_current[1], cpu_regs_current[2], cpu_regs_current[3],
				cpu_regs_current[4], cpu_regs_current[5], cpu_regs_current[6], cpu_regs_current[7],
				cpu_regs_current[8], cpu_regs_current[9], cpu_regs_current[10], cpu_regs_current[11],
				cpu_regs_current[12], cpu_regs_current[13], cpu_regs_current[14], cpu_regs_current[15],
				cpu_regs_current[16], cpu_regs_current[17], cpu_regs_current[18], cpu_regs_current[19],
				cpu_regs_current[20], cpu_regs_current[21], cpu_regs_current[22], cpu_regs_current[23],
				cpu_regs_current[24], cpu_regs_current[25], cpu_regs_current[26], cpu_regs_current[27],
				cpu_regs_current[28], cpu_regs_current[29], cpu_regs_current[30], cpu_regs_current[31],
				debug_en, mem_ready, mem_rdata, mem_vld,
				reg_pc_current, reg_op1_current, reg_op2_current,
				mem_rdata_q_current, cpu_state_current) begin
		cpu_state_next 		= cpu_state_current;
		reg_pc_next 			= reg_pc_current;
		reg_op1_next 			= reg_op1_current;
		reg_op2_next 			= reg_op2_current;
		mem_rdata_q_next 		= mem_rdata_q_current;


		mem_addr					= 0;
		mem_wdata 				= 0;
		mem_wstrb 				= 0;
		mem_req = 0;
		for (i = 0; i < regfile_size; i = i+1) begin
			cpu_regs_next[i] 	= cpu_regs_current[i];
		end
		
		case(cpu_state_current)
			cpu_state_init: begin
				reg_pc_next 			= 0;
				reg_op1_next 			= 0;
				reg_op2_next 			= 0;
				cpu_state_next 		= cpu_state_start;
				
				for (i = 0; i < regfile_size; i = i+1)
					cpu_regs_next[i] 	= 0;

				cpu_regs_next[2] 		= 4096;
			end
			cpu_state_start: begin
				if(mem_vld) begin

						mem_req = 1'b1;
						mem_addr  		= (reg_pc_current);
						cpu_state_next = cpu_state_fetch;

				end
			end
			cpu_state_fetch: begin
				if(mem_vld) begin
					mem_rdata_q_next 	= mem_rdata;

					cpu_state_next 	= cpu_state_decode;
				end
			end
			cpu_state_decode: begin
				if(mem_rdata_q_current[6:5] == 2'b01 && mem_rdata_q_current[4:2] == 3'b100) begin

					reg_op1_next 	= cpu_regs_current[mem_rdata_q_current[19:15]];
					reg_op2_next 	= cpu_regs_current[mem_rdata_q_current[24:20]];
					cpu_state_next = cpu_state_alu_exec;
				end
				else if(mem_rdata_q_current[6:5] == 2'b00 && mem_rdata_q_current[4:2] == 3'b100) begin

					cpu_state_next = cpu_state_alu_exec;
					if(mem_rdata_q_current[14:12] == 3'b000) begin

						reg_op1_next = cpu_regs_current[mem_rdata_q_current[19:15]];
						reg_op2_next = $signed(mem_rdata_q_current[31:20]);
					end
					else if(mem_rdata_q_current[14:12] == 3'b010) begin
						reg_op1_next = cpu_regs_current[mem_rdata_q_current[19:15]];
						reg_op2_next = mem_rdata_q_current[31:20];
					end
					else if(mem_rdata_q_current[14:12] == 3'b011) begin
						reg_op1_next = cpu_regs_current[mem_rdata_q_current[19:15]];
						reg_op2_next = mem_rdata_q_current[31:20];
					end
					else if(mem_rdata_q_current[14:12] == 3'b100) begin
						reg_op1_next = cpu_regs_current[mem_rdata_q_current[19:15]];
						reg_op2_next = mem_rdata_q_current[31:20];
					end
					else if(mem_rdata_q_current[14:12] == 3'b110) begin
						reg_op1_next = cpu_regs_current[mem_rdata_q_current[19:15]];
						reg_op2_next = mem_rdata_q_current[31:20];
					end
					else if(mem_rdata_q_current[14:12] == 3'b111) begin
						reg_op1_next = cpu_regs_current[mem_rdata_q_current[19:15]];
						reg_op2_next = mem_rdata_q_current[31:20];
					end
					else if(mem_rdata_q_current[14:12] == 3'b001) begin
						reg_op1_next = cpu_regs_current[mem_rdata_q_current[19:15]];
						reg_op2_next = mem_rdata_q_current[24:20];
					end
					else if(mem_rdata_q_current[31:25] == 7'b0000000 && mem_rdata_q_current[14:12] == 3'b101) begin
						reg_op1_next = cpu_regs_current[mem_rdata_q_current[19:15]];
						reg_op2_next = mem_rdata_q_current[24:20];
					end
					else if(mem_rdata_q_current[31:25] == 7'b0100000 && mem_rdata_q_current[14:12] == 3'b101) begin
						reg_op1_next = cpu_regs_current[mem_rdata_q_current[19:15]];
						reg_op2_next = mem_rdata_q_current[24:20];
					end
				end
				else if(mem_rdata_q_current[6:5] == 2'b01 && mem_rdata_q_current[4:2] == 3'b101) begin
					if(mem_rdata_q_current[11:7] != 0) begin					
						cpu_regs_next[mem_rdata_q_current[11:7]] = {mem_rdata_q_current[31:12], 12'b000000000000};
					end					
					reg_pc_next = reg_pc_current + 4;
					cpu_state_next = cpu_state_start;
				end
				else if(mem_rdata_q_current[6:5] == 2'b00 && mem_rdata_q_current[4:2] == 3'b101) begin
					if(mem_rdata_q_current[11:7] != 0) begin					
						cpu_regs_next[mem_rdata_q_current[11:7]] = reg_pc_current + {mem_rdata_q_current[31:12], 12'b000000000000};
					end
					reg_pc_next 										= reg_pc_current + 4;
					cpu_state_next 									= cpu_state_start;
				end
				else if(mem_rdata_q_current[6:5] == 2'b00 && mem_rdata_q_current[4:2] == 3'b000) begin
					if(mem_vld) begin
						cpu_state_next = cpu_state_alu_exec;
						mem_req = 1;
						if(mem_rdata_q_current[14:12] == 3'b010) begin
							mem_addr	= $signed(mem_rdata_q_current[31:20]) + $signed(cpu_regs_current[mem_rdata_q_current[19:15]]);
						end
						else if(mem_rdata_q_current[14:12] == 3'b000) begin
							mem_addr	= mem_rdata_q_current[31:20] + cpu_regs_current[mem_rdata_q_current[19:15]];
						end
						else if(mem_rdata_q_current[14:12] == 3'b001) begin
							mem_addr	= mem_rdata_q_current[31:20] + cpu_regs_current[mem_rdata_q_current[19:15]];
						end
						else if(mem_rdata_q_current[14:12] == 3'b100) begin
							mem_addr	= mem_rdata_q_current[31:20] + cpu_regs_current[mem_rdata_q_current[19:15]];
						end
						else if(mem_rdata_q_current[14:12] == 3'b101) begin
							mem_addr	= mem_rdata_q_current[31:20] + cpu_regs_current[mem_rdata_q_current[19:15]];
						end
					end
				end
				else if(mem_rdata_q_current[6:5] == 2'b01 && mem_rdata_q_current[4:2] == 3'b000) begin
					if(mem_vld) begin
						mem_wdata 		= cpu_regs_current[mem_rdata_q_current[24:20]];
						reg_pc_next 	= reg_pc_current + 4;
						cpu_state_next = cpu_state_start;
						mem_req = 1;
						if(mem_rdata_q_current[14:12] == 3'b010) begin
							mem_wstrb	= 4'b1111;
							mem_addr		= $signed({mem_rdata_q_current[31:25],mem_rdata_q_current[11:7]}) + $signed(cpu_regs_current[mem_rdata_q_current[19:15]]);	
						end
						else if(mem_rdata_q_current[14:12] == 3'b001) begin
							mem_wstrb 	= 4'b0011;
							mem_addr		= {mem_rdata_q_current[31:25],mem_rdata_q_current[11:7]} + cpu_regs_current[mem_rdata_q_current[19:15]];
						end
						else if(mem_rdata_q_current[14:12] == 3'b000) begin
							mem_wstrb 	= 4'b0001;
							mem_addr		= {mem_rdata_q_current[31:25],mem_rdata_q_current[11:7]} + cpu_regs_current[mem_rdata_q_current[19:15]];
						end
					end
				end
				else if(mem_rdata_q_current[6:5] == 2'b11 && mem_rdata_q_current[4:2] == 3'b011) begin
					cpu_state_next = cpu_state_start;
					reg_pc_next =  $signed(reg_pc_current) + {{12{mem_rdata_q_current[31]}},mem_rdata_q_current[19:12],mem_rdata_q_current[20],mem_rdata_q_current[30:21],1'b0};
					if(mem_rdata_q_current[11:7] != 0) begin
						cpu_regs_next[mem_rdata_q_current[11:7]] = reg_pc_current + 4;
					end
				end
				else if(mem_rdata_q_current[6:5] == 2'b11 && mem_rdata_q_current[4:2] == 3'b001) begin
					cpu_state_next	= cpu_state_start;		
					reg_pc_next 	=  $signed(cpu_regs_current[mem_rdata_q_current[19:15]]) + {{21{mem_rdata_q_current[31]}},mem_rdata_q_current[30:20]};				
					if(mem_rdata_q_current[11:7] != 0) begin
						cpu_regs_next[mem_rdata_q_current[11:7]] = reg_pc_current + 4;
					end
				end
				else if(mem_rdata_q_current[6:5] == 2'b11 && mem_rdata_q_current[4:2] == 3'b000) begin
					cpu_state_next = cpu_state_start;
					if(mem_rdata_q_current[14:12] == 3'b000) begin

						if(cpu_regs_current[mem_rdata_q_current[24:20]] == cpu_regs_current[mem_rdata_q_current[19:15]]) begin
							reg_pc_next = reg_pc_current + {{20{mem_rdata_q_current[31]}},mem_rdata_q_current[7],mem_rdata_q_current[30:25],mem_rdata_q_current[11:8],1'b0};
						end
						else begin
							reg_pc_next = reg_pc_current + 4;							
						end
					end
					else if(mem_rdata_q_current[14:12] == 3'b001) begin
						if(cpu_regs_current[mem_rdata_q_current[24:20]] != cpu_regs_current[mem_rdata_q_current[19:15]]) begin

							reg_pc_next = reg_pc_current + {{20{mem_rdata_q_current[31]}},mem_rdata_q_current[7],mem_rdata_q_current[30:25],mem_rdata_q_current[11:8],1'b0};
						end
						else begin
							reg_pc_next = reg_pc_current + 4;							
						end
					end
					else if(mem_rdata_q_current[14:12] == 3'b100) begin
						if($signed(cpu_regs_current[mem_rdata_q_current[19:15]]) < $signed(cpu_regs_current[mem_rdata_q_current[24:20]])) begin
							reg_pc_next = reg_pc_current + {{20{mem_rdata_q_current[31]}},mem_rdata_q_current[7],mem_rdata_q_current[30:25],mem_rdata_q_current[11:8],1'b0};

						end
						else begin
							reg_pc_next = reg_pc_current + 4;							
						end	
					end					
					else if(mem_rdata_q_current[14:12] == 3'b110) begin
						if(cpu_regs_current[mem_rdata_q_current[19:15]] < cpu_regs_current[mem_rdata_q_current[24:20]]) begin
							reg_pc_next = reg_pc_current + {{20{mem_rdata_q_current[31]}},mem_rdata_q_current[7],mem_rdata_q_current[30:25],mem_rdata_q_current[11:8],1'b0};
						end
						else begin
							reg_pc_next = reg_pc_current + 4;							
						end	
					end
					else if(mem_rdata_q_current[14:12] == 3'b101) begin
						if($signed(cpu_regs_current[mem_rdata_q_current[19:15]]) >= $signed(cpu_regs_current[mem_rdata_q_current[24:20]])) begin
							reg_pc_next = reg_pc_current + {{20{mem_rdata_q_current[31]}},mem_rdata_q_current[7],mem_rdata_q_current[30:25],mem_rdata_q_current[11:8],1'b0};
						end
						else begin
							reg_pc_next = reg_pc_current + 4;							
						end
					end
					else if(mem_rdata_q_current[14:12] == 3'b111) begin
						if(cpu_regs_current[mem_rdata_q_current[19:15]] >= cpu_regs_current[mem_rdata_q_current[24:20]]) begin
							reg_pc_next = reg_pc_current + {{20{mem_rdata_q_current[31]}},mem_rdata_q_current[7],mem_rdata_q_current[30:25],mem_rdata_q_current[11:8],1'b0};
						end
						else begin
							reg_pc_next = reg_pc_current + 4;							
						end
					end
					else begin
						$display("unknown instruction");

					end
				end
				else begin
					$display("Undefined Instruction");

				end
			end
			cpu_state_alu_exec: begin
				cpu_state_next = cpu_state_start;
				reg_pc_next 	= reg_pc_current + 4;
				if(mem_rdata_q_current[11:7] != 0) begin
					if(mem_rdata_q_current[6:5] == 2'b01 && mem_rdata_q_current[4:2] == 3'b100) begin
						if(mem_rdata_q_current[31:25] == 7'b0000000 && mem_rdata_q_current[14:12] == 3'b000) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current + reg_op2_current;
						end
						else if(mem_rdata_q_current[31:25] == 7'b0100000 && mem_rdata_q_current[14:12] == 3'b000) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current - reg_op2_current;
						end
						else if(mem_rdata_q_current[14:12] == 3'b001) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current << reg_op2_current[4:0];
						end
						else if(mem_rdata_q_current[14:12] == 3'b010) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = $signed(reg_op1_current) < $signed(reg_op2_current);
						end
						else if(mem_rdata_q_current[14:12] == 3'b011) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current < reg_op2_current;
						end
						else if(mem_rdata_q_current[14:12] == 3'b100) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current ^ reg_op2_current;
						end
						else if(mem_rdata_q_current[31:25] == 7'b0000000 && mem_rdata_q_current[14:12] == 3'b101) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current >> reg_op2_current[4:0];
						end
						else if(mem_rdata_q_current[31:25] == 7'b0100000 && mem_rdata_q_current[14:12] == 3'b101) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current >>> reg_op2_current[4:0];
						end
						else if(mem_rdata_q_current[14:12] == 3'b110) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current | reg_op2_current;
						end
						else if(mem_rdata_q_current[14:12] == 3'b111) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current & reg_op2_current;
						end
					end
					else if(mem_rdata_q_current[6:5] == 2'b00 && mem_rdata_q_current[4:2] == 3'b100) begin
						if(mem_rdata_q_current[14:12] == 3'b000) begin

							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current + reg_op2_current;
						end
						else if(mem_rdata_q_current[14:12] == 3'b010) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = $signed(reg_op1_current) < $signed(reg_op2_current);
						end
						else if(mem_rdata_q_current[14:12] == 3'b011) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current < reg_op2_current;
						end
						else if(mem_rdata_q_current[14:12] == 3'b100) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current ^ reg_op2_current;
						end
						else if(mem_rdata_q_current[14:12] == 3'b110) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current | reg_op2_current;
						end
						else if(mem_rdata_q_current[14:12] == 3'b111) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current & reg_op2_current;
						end
						else if(mem_rdata_q_current[14:12] == 3'b001) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current << reg_op2_current;
						end
						else if(mem_rdata_q_current[31:25] == 7'b0000000 && mem_rdata_q_current[14:12] == 3'b101) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current >> reg_op2_current;
						end
						else if(mem_rdata_q_current[31:25] == 7'b0100000 && mem_rdata_q_current[14:12] == 3'b101) begin
							cpu_regs_next[mem_rdata_q_current[11:7]] = reg_op1_current >>> reg_op2_current;
						end
					end
					else if(mem_rdata_q_current[6:5] == 2'b00 && mem_rdata_q_current[4:2] == 3'b000) begin
						if(mem_vld) begin

							if(mem_rdata_q_current[14:12] == 3'b010) begin
								cpu_regs_next[mem_rdata_q_current[11:7]]	= mem_rdata;
							end
							else if(mem_rdata_q_current[14:12] == 3'b000) begin
								cpu_regs_next[mem_rdata_q_current[11:7]]	= $signed(mem_rdata[7:0]);
							end
							else if(mem_rdata_q_current[14:12] == 3'b001) begin
								cpu_regs_next[mem_rdata_q_current[11:7]]	= $signed(mem_rdata[15:0]);
							end
							else if(mem_rdata_q_current[14:12] == 3'b100) begin
								cpu_regs_next[mem_rdata_q_current[11:7]]	= $signed(mem_rdata[7:0]);
							end
							else if(mem_rdata_q_current[14:12] == 3'b101) begin
								cpu_regs_next[mem_rdata_q_current[11:7]]	= $signed(mem_rdata[15:0]);
							end
						end
						else begin
							cpu_state_next = cpu_state_alu_exec;
							reg_pc_next 	= reg_pc_current;
						end
					end
				end
			end
		endcase
	end
	
	assign debug_pc_out = reg_pc_current;

endmodule