data/full_repos/permissive/447223480/06_32bit/cpu.v
data/verilator_xmls/67e86d8d-a629-410a-ab5d-01394fc6dc49.xml
module decoder(
	inst,
	Rm, Rs, Rd, immediate,
	pc_as_Rm, is_immediate, alu_op,
	dread_req, dwrite_req, dsize, dread_se,
	is_32bit, is_jmp, jmp_if_zero, jmp_absolute
);
	input [31:0] inst;
	output [4:0] Rm, Rs, Rd;
	output [31:0] immediate;
	output pc_as_Rm, is_immediate;
	output [9:0] alu_op;
	output dread_req, dwrite_req;
	output [2:0] dsize;
	output dread_se;
	output is_32bit, is_jmp, jmp_if_zero, jmp_absolute;

	wire [4:0] Rd_normal = inst[11:7];
	wire [4:0] Rm_normal = inst[6:2];
	wire [4:0] Rd_prime = {2'b0, inst[9:7]} + 5'd8;
	wire [4:0] Rm_prime = {2'b0, inst[4:2]} + 5'd8;
	wire [4:0] Rm_32 = inst[19:15];
	wire [4:0] Rs_32 = inst[24:20];
	wire [31:0] n6 = {{27{inst[12]}}, inst[6:2]};
	wire [31:0] n18 = {{15{inst[12]}}, inst[6:2], 12'b0};
	wire [31:0] u10 = {22'b0, inst[10:7], inst[12:11], inst[5], inst[6], 2'b0};
	wire [31:0] n10 = {{23{inst[12]}}, inst[4:3], inst[5], inst[2], inst[6], 4'b0};
	wire [31:0] n9 = {{24{inst[12]}}, inst[6:5], inst[2], inst[11:10], inst[4:3], 1'b0};
	wire [31:0] n12_c = {{21{inst[12]}}, inst[8], inst[10:9], inst[6], inst[7], inst[2], inst[11], inst[5:3], 1'b0};
	wire [31:0] u7 = {25'b0, inst[5], inst[12:10], inst[6], 2'b0};
	wire [31:0] u8_swsp = {24'b0, inst[8:7], inst[12:9], 2'b0};
	wire [31:0] u8_lwsp = {24'b0, inst[3:2], inst[12], inst[6:4], 2'b0};
	wire [31:0] n32  = {inst[31:12], 12'b0};
	wire [31:0] n12 = {{21{inst[31]}}, inst[30:20]};
	wire [31:0] u5 = {27'b0, inst[24:20]};
	wire [31:0] n12_store32 = {{21{inst[31]}}, inst[30:25], inst[11:7]};
	wire [31:0] n21 = {{12{inst[31]}}, inst[19:12], inst[20], inst[30:21], 1'b0};
	wire [31:0] n13 = {{20{inst[31]}}, inst[7], inst[30:25], inst[11:8], 1'b0};

	wire c_li = inst[15:13] == 3'b010 && inst[1:0] == 2'b01;
	wire c_lui = inst[15:13] == 3'b011 && inst[1:0] == 2'b01;
	wire c_mv = inst[15:12] == 4'b1000 && inst[1:0] == 2'b10;
	wire c_addi = inst[15:13] == 3'b000 && inst[1:0] == 2'b01;
	wire c_slli = inst[15:12] == 4'b0000 && inst[1:0] == 2'b10;
	wire c_add = inst[15:12] == 4'b1001 && inst[1:0] == 2'b10;
	wire c_other_calc = inst[15:13] == 3'b100 && inst[1:0] == 2'b01 && (inst[12] == 1'b0 || inst[11:10] == 2'b10);
	wire c_other_calc_use_n6 = c_other_calc && inst[11:10] != 2'b11;
	wire c_other_calc_use_Rm = c_other_calc && inst[11:10] == 2'b11;
	wire c_addi4spn = inst[15:13] == 3'b000 && inst[1:0] == 2'b00;
	wire c_addi16sp = inst[15:13] == 3'b011 && inst[11:7] == 5'b00010 && inst[1:0] == 2'b01;

	wire c_beqz = inst[15:13] == 3'b110 && inst[1:0] == 2'b01;
	wire c_bnez = inst[15:13] == 3'b111 && inst[1:0] == 2'b01;
	wire c_j = inst[15:13] == 3'b101 && inst[1:0] == 2'b01;
	wire c_jr = inst[15:12] == 4'b1000 && inst[6:0] == 7'b0000010;
	wire c_jal = inst[15:13] == 3'b001 && inst[1:0] == 2'b01;
	wire c_jalr = inst[15:12] == 4'b1001 && inst[6:0] == 7'b0000010;

	wire c_lw = inst[15:13] == 3'b010 && inst[1:0] == 2'b00;
	wire c_sw = inst[15:13] == 3'b110 && inst[1:0] == 2'b00;
	wire c_swsp = inst[15:13] == 3'b110 && inst[1:0] == 2'b10;
	wire c_lwsp = inst[15:13] == 3'b010 && inst[1:0] == 2'b10;

	wire lui = inst[6:0] == 7'b0110111;

	wire auipc = inst[6:0] == 7'b0010111;
	wire addi = inst[14:12] == 3'b000 && inst[6:0] == 7'b0010011;
	wire add  = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b000 && inst[6:0] == 7'b0110011;
	wire sub  = inst[31:25] == 7'b0100000 && inst[14:12] == 3'b000 && inst[6:0] == 7'b0110011;
	wire slli = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b001 && inst[6:0] == 7'b0010011;
	wire srli = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b101 && inst[6:0] == 7'b0010011;
	wire srai = inst[31:25] == 7'b0100000 && inst[14:12] == 3'b101 && inst[6:0] == 7'b0010011;
	wire sll  = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b001 && inst[6:0] == 7'b0110011;
	wire srl  = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b101 && inst[6:0] == 7'b0110011;
	wire sra  = inst[31:25] == 7'b0100000 && inst[14:12] == 3'b101 && inst[6:0] == 7'b0110011;
	wire xori = inst[14:12] == 3'b100 && inst[6:0] == 7'b0010011;
	wire ori  = inst[14:12] == 3'b110 && inst[6:0] == 7'b0010011;
	wire andi = inst[14:12] == 3'b111 && inst[6:0] == 7'b0010011;
	wire ins_xor = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b100 && inst[6:0] == 7'b0110011;
	wire ins_or  = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b110 && inst[6:0] == 7'b0110011;
	wire ins_and = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b111 && inst[6:0] == 7'b0110011;

	wire lbu = inst[14:12] == 3'b100 && inst[6:0] == 7'b0000011;
	wire lb  = inst[14:12] == 3'b000 && inst[6:0] == 7'b0000011;
	wire lhu = inst[14:12] == 3'b101 && inst[6:0] == 7'b0000011;
	wire lh  = inst[14:12] == 3'b001 && inst[6:0] == 7'b0000011;
	wire lw  = inst[14:12] == 3'b010 && inst[6:0] == 7'b0000011;
	wire sb  = inst[14:12] == 3'b000 && inst[6:0] == 7'b0100011;
	wire sh  = inst[14:12] == 3'b001 && inst[6:0] == 7'b0100011;
	wire sw  = inst[14:12] == 3'b010 && inst[6:0] == 7'b0100011;

	wire slti  = inst[14:12] == 3'b010 && inst[6:0] == 7'b0010011;
	wire sltiu = inst[14:12] == 3'b011 && inst[6:0] == 7'b0010011;
	wire slt  = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b010 && inst[6:0] == 7'b0110011;
	wire sltu = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b011 && inst[6:0] == 7'b0110011;

	wire jal = inst[6:0] == 7'b1101111;
	wire jalr = inst[14:12] == 3'b000 && inst[6:0] == 7'b1100111;
	wire beq  = inst[14:12] == 3'b000 && inst[6:0] == 7'b1100011;
	wire bne  = inst[14:12] == 3'b001 && inst[6:0] == 7'b1100011;
	wire blt  = inst[14:12] == 3'b100 && inst[6:0] == 7'b1100011;
	wire bge  = inst[14:12] == 3'b101 && inst[6:0] == 7'b1100011;
	wire bltu = inst[14:12] == 3'b110 && inst[6:0] == 7'b1100011;
	wire bgeu = inst[14:12] == 3'b111 && inst[6:0] == 7'b1100011;

	wire [9:0] c_other_calc_op_11 =
		inst[6:5] == 2'b00 ? 10'b0000000010 :
		inst[6:5] == 2'b01 ? 10'b0000010000 :
		inst[6:5] == 2'b10 ? 10'b0000001000 :
		10'b0000000100;

	wire [9:0] c_other_calc_op =
		inst[11:10] == 2'b00 ? 10'b0001000000 :
		inst[11:10] == 2'b01 ? 10'b0010000000 :
		inst[11:10] == 2'b10 ? 10'b0000000100 :
		c_other_calc_op_11;

	wire arith_reg_reg_32 = add || sub || sll || srl || sra || ins_xor || ins_or || ins_and || slt || sltu;
	wire arith_reg_imm_32 = addi || slli || srli || srai || xori || ori || andi || slti || sltiu;

	wire [9:0] arith_reg_reg_32_op =
		add     ? 10'b0000000001 :
		sub     ? 10'b0000000010 :
		sll     ? 10'b0000100000 :
		srl     ? 10'b0001000000 :
		sra     ? 10'b0010000000 :
		ins_xor ? 10'b0000010000 :
		ins_or  ? 10'b0000001000 :
		ins_and ? 10'b0000000100 :
		slt     ? 10'b0100000000 :
		sltu    ? 10'b1000000000 :
		10'b0;

	wire [9:0] arith_reg_imm_32_op =
		addi  ? 10'b0000000001 :
		slli  ? 10'b0000100000 :
		srli  ? 10'b0001000000 :
		srai  ? 10'b0010000000 :
		xori  ? 10'b0000010000 :
		ori   ? 10'b0000001000 :
		andi  ? 10'b0000000100 :
		slti  ? 10'b0100000000 :
		sltiu ? 10'b1000000000 :
		10'b0;

	wire load32 = lbu || lb || lhu || lh || lw;
	wire store32 = sb || sh || sw;

	wire cond_branch32 = beq || bne || blt || bge || bltu || bgeu;

	wire [9:0] cond_branch32_op =
		beq  || bne  ? 10'b0000000010 :
		blt  || bge  ? 10'b0100000000 :
		bltu || bgeu ? 10'b1000000000 :
		10'b0;

	wire use_Rd_32 = lui || auipc || arith_reg_reg_32 || arith_reg_imm_32 || load32 || jal || jalr;
	wire use_Rm_32 = arith_reg_reg_32 || arith_reg_imm_32 || load32 || store32 || jalr || cond_branch32;

	assign Rm =
		c_addi4spn || c_addi16sp ? 5'd2 :
		c_li || c_lui ? 5'd0 :
		c_beqz || c_bnez ? Rd_prime :
		c_j || c_jal ? 5'd0 :
		c_jr || c_jalr ? Rd_normal :
		c_mv ? Rm_normal :
		c_addi || c_slli || c_add ? Rd_normal :
		c_other_calc ? Rd_prime :
		c_lw || c_sw ? Rd_prime :
		c_swsp || c_lwsp ? 5'd2 :
		lui || auipc ? 5'd0 :
		use_Rm_32 ? Rm_32 :
		jal ? 5'd0 :
		5'd0;

	assign Rs =
		c_beqz || c_bnez ? 5'd0 :
		c_mv ? 5'd0 :
		c_add ? Rm_normal :
		c_other_calc_use_Rm ? Rm_prime :
		c_sw ? Rm_prime :
		c_swsp ? Rm_normal :
		lui || auipc || arith_reg_imm_32 ? 5'd0 :
		arith_reg_reg_32 ? Rs_32 :
		load32 || store32 ? 5'd0 :
		jal || jalr ? 5'd0 :
		cond_branch32 ? Rs_32 :
		5'd0;

	assign Rd =
		c_addi4spn ? Rm_prime :
		c_addi16sp ? 5'd2 :
		c_beqz || c_bnez || c_j || c_jr ? 5'd0 :
		c_jal || c_jalr ? 5'd1 :
		c_li || c_lui || c_mv || c_addi || c_slli || c_add ? Rd_normal :
		c_other_calc ? Rd_prime :
		c_lw ? Rm_prime :
		c_lwsp ? Rd_normal :
		c_sw || c_swsp ? 5'd0 :
		use_Rd_32 ? Rd_normal :
		store32 ? 5'd0 :
		cond_branch32 ? 5'd0 :
		5'd0;

	assign immediate =
		c_addi4spn ? u10 :
		c_addi16sp ? n10 :
		c_beqz || c_bnez ? n9 :
		c_j || c_jal ? n12_c :
		c_jr || c_jalr ? 32'd0 :
		c_li || c_addi || c_slli || c_other_calc_use_n6 ? n6 :
		c_lui ? n18 :
		c_lw || c_sw ? u7 :
		c_swsp ? u8_swsp :
		c_lwsp ? u8_lwsp :
		lui || auipc ? n32 :
		addi || xori || ori || andi || slti || sltiu ? n12 :
		slli || srli || srai ? u5 :
		load32 ? n12 :
		store32 ? n12_store32 :
		jal ? n21 :
		jalr ? n12 :
		cond_branch32 ? n13 :
		32'd0;

	assign pc_as_Rm = auipc;

	assign is_immediate =
		c_li || c_lui || c_addi || c_slli || c_other_calc_use_n6 || c_addi4spn || c_addi16sp ||
		c_lw || c_sw || c_swsp || c_lwsp ||
		lui || auipc || arith_reg_imm_32 || load32 || store32;

	assign alu_op =
		c_beqz || c_bnez ? 10'b0000000001 :
		c_j || c_jal || c_jr || c_jalr ? 10'b0000000000 :
		c_li || c_lui || c_mv || c_addi || c_add || c_addi4spn || c_addi16sp ? 10'b0000000001 :
		c_slli ? 10'b0000100000 :
		c_other_calc ? c_other_calc_op :
		c_lw || c_sw || c_swsp || c_lwsp ? 10'b0000000001 :
		lui || auipc ? 10'b0000000001 :
		arith_reg_reg_32 ? arith_reg_reg_32_op :
		arith_reg_imm_32 ? arith_reg_imm_32_op :
		load32 || store32 ? 10'b0000000001 :
		jal || jalr ? 10'b0000000000 :
		cond_branch32 ? cond_branch32_op :
		10'd0;

	assign dread_req =
		c_lw || c_lwsp || load32;

	assign dwrite_req =
		c_sw || c_swsp || store32;

	assign dsize =
		lbu || lb || sb ? 3'b001 :
		lhu || lh || sh ? 3'b010 :
		3'b100;

	assign dread_se = lb || lh;

	assign is_32bit = inst[1:0] == 2'b11;

	assign is_jmp =
		c_beqz || c_bnez || c_j || c_jr || c_jal || c_jalr || jal || jalr || cond_branch32;

	assign jmp_if_zero =
		c_beqz || c_j || c_jr || c_jal || c_jalr || jal || jalr || beq|| bge || bgeu;

	assign jmp_absolute =
		c_jr || c_jalr || jalr;

endmodule
module decoder(
	inst,
	Rm, Rs, Rd, immediate,
	pc_as_Rm, is_immediate, alu_op,
	dread_req, dwrite_req, dsize, dread_se,
	is_32bit, is_jmp, jmp_if_zero, jmp_absolute
);

	input [31:0] inst;
	output [4:0] Rm, Rs, Rd;
	output [31:0] immediate;
	output pc_as_Rm, is_immediate;
	output [9:0] alu_op;
	output dread_req, dwrite_req;
	output [2:0] dsize;
	output dread_se;
	output is_32bit, is_jmp, jmp_if_zero, jmp_absolute;

	wire [4:0] Rd_normal = inst[11:7];
	wire [4:0] Rm_normal = inst[6:2];
	wire [4:0] Rd_prime = {2'b0, inst[9:7]} + 5'd8;
	wire [4:0] Rm_prime = {2'b0, inst[4:2]} + 5'd8;
	wire [4:0] Rm_32 = inst[19:15];
	wire [4:0] Rs_32 = inst[24:20];
	wire [31:0] n6 = {{27{inst[12]}}, inst[6:2]};
	wire [31:0] n18 = {{15{inst[12]}}, inst[6:2], 12'b0};
	wire [31:0] u10 = {22'b0, inst[10:7], inst[12:11], inst[5], inst[6], 2'b0};
	wire [31:0] n10 = {{23{inst[12]}}, inst[4:3], inst[5], inst[2], inst[6], 4'b0};
	wire [31:0] n9 = {{24{inst[12]}}, inst[6:5], inst[2], inst[11:10], inst[4:3], 1'b0};
	wire [31:0] n12_c = {{21{inst[12]}}, inst[8], inst[10:9], inst[6], inst[7], inst[2], inst[11], inst[5:3], 1'b0};
	wire [31:0] u7 = {25'b0, inst[5], inst[12:10], inst[6], 2'b0};
	wire [31:0] u8_swsp = {24'b0, inst[8:7], inst[12:9], 2'b0};
	wire [31:0] u8_lwsp = {24'b0, inst[3:2], inst[12], inst[6:4], 2'b0};
	wire [31:0] n32  = {inst[31:12], 12'b0};
	wire [31:0] n12 = {{21{inst[31]}}, inst[30:20]};
	wire [31:0] u5 = {27'b0, inst[24:20]};
	wire [31:0] n12_store32 = {{21{inst[31]}}, inst[30:25], inst[11:7]};
	wire [31:0] n21 = {{12{inst[31]}}, inst[19:12], inst[20], inst[30:21], 1'b0};
	wire [31:0] n13 = {{20{inst[31]}}, inst[7], inst[30:25], inst[11:8], 1'b0};

	wire c_li = inst[15:13] == 3'b010 && inst[1:0] == 2'b01;
	wire c_lui = inst[15:13] == 3'b011 && inst[1:0] == 2'b01;
	wire c_mv = inst[15:12] == 4'b1000 && inst[1:0] == 2'b10;
	wire c_addi = inst[15:13] == 3'b000 && inst[1:0] == 2'b01;
	wire c_slli = inst[15:12] == 4'b0000 && inst[1:0] == 2'b10;
	wire c_add = inst[15:12] == 4'b1001 && inst[1:0] == 2'b10;
	wire c_other_calc = inst[15:13] == 3'b100 && inst[1:0] == 2'b01 && (inst[12] == 1'b0 || inst[11:10] == 2'b10);
	wire c_other_calc_use_n6 = c_other_calc && inst[11:10] != 2'b11;
	wire c_other_calc_use_Rm = c_other_calc && inst[11:10] == 2'b11;
	wire c_addi4spn = inst[15:13] == 3'b000 && inst[1:0] == 2'b00;
	wire c_addi16sp = inst[15:13] == 3'b011 && inst[11:7] == 5'b00010 && inst[1:0] == 2'b01;

	wire c_beqz = inst[15:13] == 3'b110 && inst[1:0] == 2'b01;
	wire c_bnez = inst[15:13] == 3'b111 && inst[1:0] == 2'b01;
	wire c_j = inst[15:13] == 3'b101 && inst[1:0] == 2'b01;
	wire c_jr = inst[15:12] == 4'b1000 && inst[6:0] == 7'b0000010;
	wire c_jal = inst[15:13] == 3'b001 && inst[1:0] == 2'b01;
	wire c_jalr = inst[15:12] == 4'b1001 && inst[6:0] == 7'b0000010;

	wire c_lw = inst[15:13] == 3'b010 && inst[1:0] == 2'b00;
	wire c_sw = inst[15:13] == 3'b110 && inst[1:0] == 2'b00;
	wire c_swsp = inst[15:13] == 3'b110 && inst[1:0] == 2'b10;
	wire c_lwsp = inst[15:13] == 3'b010 && inst[1:0] == 2'b10;

	wire lui = inst[6:0] == 7'b0110111;

	wire auipc = inst[6:0] == 7'b0010111;
	wire addi = inst[14:12] == 3'b000 && inst[6:0] == 7'b0010011;
	wire add  = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b000 && inst[6:0] == 7'b0110011;
	wire sub  = inst[31:25] == 7'b0100000 && inst[14:12] == 3'b000 && inst[6:0] == 7'b0110011;
	wire slli = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b001 && inst[6:0] == 7'b0010011;
	wire srli = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b101 && inst[6:0] == 7'b0010011;
	wire srai = inst[31:25] == 7'b0100000 && inst[14:12] == 3'b101 && inst[6:0] == 7'b0010011;
	wire sll  = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b001 && inst[6:0] == 7'b0110011;
	wire srl  = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b101 && inst[6:0] == 7'b0110011;
	wire sra  = inst[31:25] == 7'b0100000 && inst[14:12] == 3'b101 && inst[6:0] == 7'b0110011;
	wire xori = inst[14:12] == 3'b100 && inst[6:0] == 7'b0010011;
	wire ori  = inst[14:12] == 3'b110 && inst[6:0] == 7'b0010011;
	wire andi = inst[14:12] == 3'b111 && inst[6:0] == 7'b0010011;
	wire ins_xor = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b100 && inst[6:0] == 7'b0110011;
	wire ins_or  = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b110 && inst[6:0] == 7'b0110011;
	wire ins_and = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b111 && inst[6:0] == 7'b0110011;

	wire lbu = inst[14:12] == 3'b100 && inst[6:0] == 7'b0000011;
	wire lb  = inst[14:12] == 3'b000 && inst[6:0] == 7'b0000011;
	wire lhu = inst[14:12] == 3'b101 && inst[6:0] == 7'b0000011;
	wire lh  = inst[14:12] == 3'b001 && inst[6:0] == 7'b0000011;
	wire lw  = inst[14:12] == 3'b010 && inst[6:0] == 7'b0000011;
	wire sb  = inst[14:12] == 3'b000 && inst[6:0] == 7'b0100011;
	wire sh  = inst[14:12] == 3'b001 && inst[6:0] == 7'b0100011;
	wire sw  = inst[14:12] == 3'b010 && inst[6:0] == 7'b0100011;

	wire slti  = inst[14:12] == 3'b010 && inst[6:0] == 7'b0010011;
	wire sltiu = inst[14:12] == 3'b011 && inst[6:0] == 7'b0010011;
	wire slt  = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b010 && inst[6:0] == 7'b0110011;
	wire sltu = inst[31:25] == 7'b0000000 && inst[14:12] == 3'b011 && inst[6:0] == 7'b0110011;

	wire jal = inst[6:0] == 7'b1101111;
	wire jalr = inst[14:12] == 3'b000 && inst[6:0] == 7'b1100111;
	wire beq  = inst[14:12] == 3'b000 && inst[6:0] == 7'b1100011;
	wire bne  = inst[14:12] == 3'b001 && inst[6:0] == 7'b1100011;
	wire blt  = inst[14:12] == 3'b100 && inst[6:0] == 7'b1100011;
	wire bge  = inst[14:12] == 3'b101 && inst[6:0] == 7'b1100011;
	wire bltu = inst[14:12] == 3'b110 && inst[6:0] == 7'b1100011;
	wire bgeu = inst[14:12] == 3'b111 && inst[6:0] == 7'b1100011;

	wire [9:0] c_other_calc_op_11 =
		inst[6:5] == 2'b00 ? 10'b0000000010 :
		inst[6:5] == 2'b01 ? 10'b0000010000 :
		inst[6:5] == 2'b10 ? 10'b0000001000 :
		10'b0000000100;

	wire [9:0] c_other_calc_op =
		inst[11:10] == 2'b00 ? 10'b0001000000 :
		inst[11:10] == 2'b01 ? 10'b0010000000 :
		inst[11:10] == 2'b10 ? 10'b0000000100 :
		c_other_calc_op_11;

	wire arith_reg_reg_32 = add || sub || sll || srl || sra || ins_xor || ins_or || ins_and || slt || sltu;
	wire arith_reg_imm_32 = addi || slli || srli || srai || xori || ori || andi || slti || sltiu;

	wire [9:0] arith_reg_reg_32_op =
		add     ? 10'b0000000001 :
		sub     ? 10'b0000000010 :
		sll     ? 10'b0000100000 :
		srl     ? 10'b0001000000 :
		sra     ? 10'b0010000000 :
		ins_xor ? 10'b0000010000 :
		ins_or  ? 10'b0000001000 :
		ins_and ? 10'b0000000100 :
		slt     ? 10'b0100000000 :
		sltu    ? 10'b1000000000 :
		10'b0;

	wire [9:0] arith_reg_imm_32_op =
		addi  ? 10'b0000000001 :
		slli  ? 10'b0000100000 :
		srli  ? 10'b0001000000 :
		srai  ? 10'b0010000000 :
		xori  ? 10'b0000010000 :
		ori   ? 10'b0000001000 :
		andi  ? 10'b0000000100 :
		slti  ? 10'b0100000000 :
		sltiu ? 10'b1000000000 :
		10'b0;

	wire load32 = lbu || lb || lhu || lh || lw;
	wire store32 = sb || sh || sw;

	wire cond_branch32 = beq || bne || blt || bge || bltu || bgeu;

	wire [9:0] cond_branch32_op =
		beq  || bne  ? 10'b0000000010 :
		blt  || bge  ? 10'b0100000000 :
		bltu || bgeu ? 10'b1000000000 :
		10'b0;

	wire use_Rd_32 = lui || auipc || arith_reg_reg_32 || arith_reg_imm_32 || load32 || jal || jalr;
	wire use_Rm_32 = arith_reg_reg_32 || arith_reg_imm_32 || load32 || store32 || jalr || cond_branch32;

	assign Rm =
		c_addi4spn || c_addi16sp ? 5'd2 :
		c_li || c_lui ? 5'd0 :
		c_beqz || c_bnez ? Rd_prime :
		c_j || c_jal ? 5'd0 :
		c_jr || c_jalr ? Rd_normal :
		c_mv ? Rm_normal :
		c_addi || c_slli || c_add ? Rd_normal :
		c_other_calc ? Rd_prime :
		c_lw || c_sw ? Rd_prime :
		c_swsp || c_lwsp ? 5'd2 :
		lui || auipc ? 5'd0 :
		use_Rm_32 ? Rm_32 :
		jal ? 5'd0 :
		5'd0;

	assign Rs =
		c_beqz || c_bnez ? 5'd0 :
		c_mv ? 5'd0 :
		c_add ? Rm_normal :
		c_other_calc_use_Rm ? Rm_prime :
		c_sw ? Rm_prime :
		c_swsp ? Rm_normal :
		lui || auipc || arith_reg_imm_32 ? 5'd0 :
		arith_reg_reg_32 ? Rs_32 :
		load32 || store32 ? 5'd0 :
		jal || jalr ? 5'd0 :
		cond_branch32 ? Rs_32 :
		5'd0;

	assign Rd =
		c_addi4spn ? Rm_prime :
		c_addi16sp ? 5'd2 :
		c_beqz || c_bnez || c_j || c_jr ? 5'd0 :
		c_jal || c_jalr ? 5'd1 :
		c_li || c_lui || c_mv || c_addi || c_slli || c_add ? Rd_normal :
		c_other_calc ? Rd_prime :
		c_lw ? Rm_prime :
		c_lwsp ? Rd_normal :
		c_sw || c_swsp ? 5'd0 :
		use_Rd_32 ? Rd_normal :
		store32 ? 5'd0 :
		cond_branch32 ? 5'd0 :
		5'd0;

	assign immediate =
		c_addi4spn ? u10 :
		c_addi16sp ? n10 :
		c_beqz || c_bnez ? n9 :
		c_j || c_jal ? n12_c :
		c_jr || c_jalr ? 32'd0 :
		c_li || c_addi || c_slli || c_other_calc_use_n6 ? n6 :
		c_lui ? n18 :
		c_lw || c_sw ? u7 :
		c_swsp ? u8_swsp :
		c_lwsp ? u8_lwsp :
		lui || auipc ? n32 :
		addi || xori || ori || andi || slti || sltiu ? n12 :
		slli || srli || srai ? u5 :
		load32 ? n12 :
		store32 ? n12_store32 :
		jal ? n21 :
		jalr ? n12 :
		cond_branch32 ? n13 :
		32'd0;

	assign pc_as_Rm = auipc;

	assign is_immediate =
		c_li || c_lui || c_addi || c_slli || c_other_calc_use_n6 || c_addi4spn || c_addi16sp ||
		c_lw || c_sw || c_swsp || c_lwsp ||
		lui || auipc || arith_reg_imm_32 || load32 || store32;

	assign alu_op =
		c_beqz || c_bnez ? 10'b0000000001 :
		c_j || c_jal || c_jr || c_jalr ? 10'b0000000000 :
		c_li || c_lui || c_mv || c_addi || c_add || c_addi4spn || c_addi16sp ? 10'b0000000001 :
		c_slli ? 10'b0000100000 :
		c_other_calc ? c_other_calc_op :
		c_lw || c_sw || c_swsp || c_lwsp ? 10'b0000000001 :
		lui || auipc ? 10'b0000000001 :
		arith_reg_reg_32 ? arith_reg_reg_32_op :
		arith_reg_imm_32 ? arith_reg_imm_32_op :
		load32 || store32 ? 10'b0000000001 :
		jal || jalr ? 10'b0000000000 :
		cond_branch32 ? cond_branch32_op :
		10'd0;

	assign dread_req =
		c_lw || c_lwsp || load32;

	assign dwrite_req =
		c_sw || c_swsp || store32;

	assign dsize =
		lbu || lb || sb ? 3'b001 :
		lhu || lh || sh ? 3'b010 :
		3'b100;

	assign dread_se = lb || lh;

	assign is_32bit = inst[1:0] == 2'b11;

	assign is_jmp =
		c_beqz || c_bnez || c_j || c_jr || c_jal || c_jalr || jal || jalr || cond_branch32;

	assign jmp_if_zero =
		c_beqz || c_j || c_jr || c_jal || c_jalr || jal || jalr || beq|| bge || bgeu;

	assign jmp_absolute =
		c_jr || c_jalr || jalr;

endmodule