data/full_repos/permissive/140999934/CPU/axi_cpu/decode.v
1: b'%Error: data/full_repos/permissive/140999934/CPU/axi_cpu/decode.v:398: syntax error, unexpected break, expecting IDENTIFIER or do or final\n wire break;\n      ^~~~~\n%Error: data/full_repos/permissive/140999934/CPU/axi_cpu/decode.v:407: syntax error, unexpected break, expecting TYPE-IDENTIFIER\n    assign break = inst_BREAK;\n           ^~~~~\n%Error: data/full_repos/permissive/140999934/CPU/axi_cpu/decode.v:414: syntax error, unexpected break, expecting TYPE-IDENTIFIER\n                  | syscall | eret | break);\n                                     ^~~~~\n%Error: data/full_repos/permissive/140999934/CPU/axi_cpu/decode.v:434: syntax error, unexpected break, expecting TYPE-IDENTIFIER\n                         syscall, eret, break, addr_exc, ri_exc,ov_exc_en,  \n                                        ^~~~~\n%Error: Exiting due to 4 error(s)\n'
module decode(
	input wire		ID_valid,
	input wire [65:0]	IF_ID_bus_r,
	input wire [31:0]	rs_value,
	input wire [31:0]	rt_value,
	output wire [ 4:0]	rs,
	output wire [ 4:0]	rt,
	output wire [32:0]	jbr_bus,
	output			    inst_jbr,
	output wire 		ID_over,
	output wire [181:0]	ID_EXE_bus,


	input wire 		IF_over,
	input wire      EXE_over,
	input wire      MEM_over,
	input wire [ 4:0]	EXE_wdest,
	input wire [ 4:0]	MEM_wdest,
	input wire [ 4:0]	WB_wdest,
    input wire [31:0]   EXE_result_quick_get,
    input wire [31:0]   MEM_result_quick_get,
    input wire          EXE_quick_en,
    input wire          MEM_quick_en,


	output wire [31:0]	ID_pc
);


	wire [31:0] pc;
	wire [31:0] inst;
    wire addr_exc;
    wire is_ds;
	assign {pc, inst, addr_exc, is_ds} = IF_ID_bus_r;



    wire [31:0] rs_real_value;
	wire [31:0] rt_real_value;
    wire [5:0] op;
    wire [4:0] rd;
    wire [4:0] sa;
    wire [5:0] funct;
    wire [15:0] imm;
    wire [15:0] offset;
    wire [25:0] target;
    wire [2:0] cp0r_sel;
    
    assign op       = inst[31:26];
    assign rs       = inst[25:21];
    assign rt       = inst[20:16];
    assign rd       = inst[15:11];
    assign sa       = inst[10:6];
    assign funct    = inst[5:0];
    assign imm      = inst[15:0];
    assign offset   = inst[15:0];
    assign target   = inst[25:0];
    assign cp0r_sel = inst[2:0];


    


    wire inst_ADD,	  inst_ADDI,	inst_ADDU,		inst_ADDIU;
    wire inst_SUB,     inst_SUBU,  	inst_SLT,   	inst_SLTI;
    wire inst_SLTU,    inst_SLTIU,  	inst_DIV,    	inst_DIVU;
    wire inst_MULT,    inst_MULTU,  	inst_AND,    	inst_ANDI;
    wire inst_LUI,     inst_NOR,    	inst_OR,     	inst_ORI;
    wire inst_XOR,     inst_XORI,   	inst_SLL,    	inst_SLLV,   inst_SRA;
    wire inst_SRAV,    inst_SRL,    	inst_SRLV,   	inst_BEQ;
    wire inst_BNE,     inst_BGEZ,   	inst_BGTZ,   	inst_BLEZ;
    wire inst_BLTZ,    inst_BLTZAL, 	inst_BGEZAL,	inst_J;
    wire inst_JAL,     inst_JR,     	inst_JALR, 		inst_MFHI;
    wire inst_MFLO,    inst_MTHI,   	inst_MTLO, 		inst_BREAK;
    wire inst_SYSCALL, inst_LB,     	inst_LBU,    	inst_LH;
    wire inst_LHU,     inst_LW,     	inst_LWL,       inst_LWR;
    wire inst_SB,     	inst_SH,        inst_SWL,       inst_SWR;
    wire inst_SW,      inst_ERET,   	inst_MFC0,   	inst_MTC0;

    wire op_zero;
    wire rs_zero;
    wire rt_zero;
    wire rd_zero;
    wire sa_zero;

    assign op_zero = ~(|op);
    assign rs_zero = ~(|rs);
    assign rt_zero = ~(|rt);
    assign rd_zero = ~(|rd);
    assign sa_zero = ~(|sa);
    
    assign inst_ADD = op_zero & sa_zero & (funct == 6'b100000);
    assign inst_ADDI = (op == 6'b001000);
    assign inst_ADDU = op_zero & sa_zero & (funct == 6'b100001);
    assign inst_ADDIU = (op == 6'b001001);
    assign inst_SUB = op_zero & sa_zero & (funct == 6'b100010);
    assign inst_SUBU = op_zero & sa_zero & (funct == 6'b100011);
    assign inst_SLT = op_zero & sa_zero & (funct == 6'b101010);
    assign inst_SLTI = (op == 6'b001010);
    assign inst_SLTU = op_zero & sa_zero & (funct == 6'b101011);
    assign inst_SLTIU = (op == 6'b001011);
    assign inst_DIV = op_zero & rd_zero & sa_zero & (funct == 6'b011010);
    assign inst_DIVU = op_zero & rd_zero & sa_zero & (funct == 6'b011011);
    assign inst_MULT = op_zero & rd_zero & sa_zero & (funct == 6'b011000);
    assign inst_MULTU = op_zero & rd_zero & sa_zero & (funct == 6'b011001);
    assign inst_AND = op_zero & sa_zero & (funct == 6'b100100);
    assign inst_ANDI = (op == 6'b001100);
    assign inst_LUI = (op == 6'b001111) & rs_zero;
    assign inst_NOR = op_zero & sa_zero & (funct == 6'b100111);
    assign inst_OR = op_zero & sa_zero & (funct == 6'b100101);
    assign inst_ORI = (op == 6'b001101);
    assign inst_XOR = op_zero & sa_zero & (funct == 6'b100110);
    assign inst_XORI = (op == 6'b001110);
    assign inst_SLL = op_zero & rs_zero & (funct == 6'b000000);
    assign inst_SLLV = op_zero & sa_zero & (funct == 6'b000100);
    assign inst_SRA = op_zero & rs_zero & (funct == 6'b000011);
    assign inst_SRAV = op_zero & sa_zero & (funct == 6'b0000111);
    assign inst_SRL = op_zero & rs_zero & (funct == 6'b000010);
    assign inst_SRLV = op_zero & sa_zero & (funct == 6'b000110);
    assign inst_BEQ = (op == 6'b000100);
    assign inst_BNE = (op == 6'b000101);
    assign inst_BGEZ = (op == 6'b000001) & (rt == 5'b00001);
    assign inst_BGTZ = (op == 6'b000111) & rt_zero;
    assign inst_BLEZ = (op == 6'b000110) & rt_zero;
    assign inst_BLTZ = (op == 6'b000001) & rt_zero;
    assign inst_BLTZAL = (op == 6'b000001) & (rt == 5'b10000);
    assign inst_BGEZAL = (op == 6'b000001) & (rt == 5'b10001);
    assign inst_J = (op == 6'b000010);
    assign inst_JAL = (op == 6'b000011);
    assign inst_JR = op_zero & rt_zero & rd_zero & (funct == 6'b001000);
    assign inst_JALR = op_zero & rt_zero & (funct == 6'b001001);
    assign inst_MFHI = op_zero & rs_zero & rt_zero & sa_zero & (funct == 6'b010000);
    assign inst_MFLO = op_zero & rs_zero & rt_zero & sa_zero & (funct == 6'b010010);
    assign inst_MTHI = op_zero & rt_zero & rd_zero & sa_zero & (funct == 6'b010001);
    assign inst_MTLO = op_zero & rt_zero & rd_zero & sa_zero & (funct == 6'b010011);
    assign inst_BREAK = op_zero & (funct == 6'b001101);
    assign inst_SYSCALL = op_zero & (funct == 6'b001100);
    assign inst_LB = (op == 6'b100000);
    assign inst_LBU = (op == 6'b100100);
    assign inst_LH = (op == 6'b100001);
    assign inst_LHU = (op == 6'b100101);
    assign inst_LW = (op == 6'b100011);
    assign inst_LWL = (op == 6'b100010);
    assign inst_LWR = (op == 6'b100110);
    assign inst_SB = (op == 6'b101000);
    assign inst_SH = (op == 6'b101001);
    assign inst_SW = (op == 6'b101011);
    assign inst_SWL = (op == 6'b101010);
    assign inst_SWR = (op == 6'b101110);
    assign inst_ERET = (op == 6'b010000) & (rs == 5'b10000) & rt_zero & rd_zero & sa_zero & (funct == 6'b011000);
    assign inst_MFC0 = (op == 6'b010000) & rs_zero & (inst[10:3] == 8'd0);
    assign inst_MTC0 = (op == 6'b010000) & (rs == 5'b00100) & (inst[10:3] == 8'd0);


    wire inst_jr;
    wire inst_j_link;
    assign inst_jr = inst_JALR | inst_JR;
    assign inst_j_link = inst_JAL | inst_JALR | inst_BLTZAL | inst_BGEZAL;
    assign inst_jbr = inst_J 		| inst_JAL 		| inst_jr
    				| inst_BEQ		| inst_BNE		| inst_BGEZ
    				| inst_BGTZ 	| inst_BLEZ		| inst_BLTZ
    				| inst_BLTZAL 	| inst_BGEZAL;


    wire inst_load;
    wire inst_store;
    assign inst_load = inst_LB | inst_LBU | inst_LH | inst_LHU | inst_LW | inst_LWL | inst_LWR;
    assign inst_store = inst_SB | inst_SH | inst_SW | inst_SWL | inst_SWR;
    
   	
    

    wire inst_add, inst_sub, inst_slt, inst_sltu;
    wire inst_div, inst_mul, inst_and, inst_lui;
    wire inst_nor, inst_or, inst_xor;
    wire inst_sll, inst_srl, inst_sra;
    
    assign inst_add = inst_ADD | inst_ADDI | inst_ADDU | inst_ADDIU | inst_load | inst_store | inst_j_link;
    assign inst_sub = inst_SUB | inst_SUBU;
    assign inst_slt = inst_SLT | inst_SLTI;
    assign inst_sltu =  inst_SLTU | inst_SLTIU;
    assign inst_div = inst_DIV | inst_DIVU;
    assign inst_mul = inst_MULT | inst_MULTU;
    assign inst_and = inst_AND | inst_ANDI;
    assign inst_lui = inst_LUI;
    assign inst_nor = inst_NOR;
    assign inst_or = inst_OR | inst_ORI;
    assign inst_xor = inst_XOR | inst_XORI;
    assign inst_sll = inst_SLL | inst_SLLV;
    assign inst_srl = inst_SRL | inst_SRLV;
    assign inst_sra = inst_SRA | inst_SRAV;


    wire inst_signed;
    assign inst_signed = inst_MULT | inst_DIV;

    wire inst_shf_sa;
    assign inst_shf_sa = inst_SLL | inst_SRA | inst_SRL;
    
    wire inst_op1_use_rs_low5;
    assign inst_op1_use_rs_low5 = inst_SLLV | inst_SRAV;


    wire  inst_imm_zero;
    wire inst_imm_sign;
    assign inst_imm_zero = inst_ANDI | inst_LUI | inst_ORI | inst_XORI;
	assign inst_imm_sign = inst_ADDI | inst_ADDIU | inst_SLTI | inst_SLTIU | inst_load | inst_store;


	wire inst_wdest_rt;
	wire inst_wdest_31;
	wire inst_wdest_rd;
	assign inst_wdest_rt = inst_imm_zero | inst_ADDI | inst_ADDIU | inst_SLTI
						 | inst_SLTIU | inst_load | inst_MFC0;
	assign inst_wdest_31 = inst_JAL  | inst_BLTZAL | inst_BGEZAL;
	assign inst_wdest_rd = inst_ADD  | inst_ADDU   | inst_SUB | inst_SUBU
                         | inst_SLT  | inst_SLTU   | inst_AND | inst_NOR
						 | inst_OR   | inst_XOR    | inst_SLL | inst_SLLV 
						 | inst_SRA	 | inst_SRAV   | inst_SRL | inst_SRLV 
						 | inst_JALR | inst_MFHI   | inst_MFLO;


	wire inst_no_rs;
	wire inst_no_rt;
	assign inst_no_rs = inst_MTC0 | inst_BREAK | inst_SYSCALL | inst_ERET;
	assign inst_no_rt = inst_wdest_rt | inst_BGEZ | inst_BLTZAL | inst_BGEZAL
					  | inst_J | inst_JAL;
    

    wire inst_rt_is_rdest;
    wire inst_rs_is_rdest;
    wire inst_rt_is_wdest;
    assign inst_rt_is_rdest = inst_ADD | inst_ADDU | inst_SUB | inst_SUBU
                            | inst_SLT |inst_SLTU | inst_DIV | inst_DIVU 
                            | inst_MULT | inst_MULTU | inst_AND | inst_NOR
                            | inst_OR | inst_XOR | inst_SLLV | inst_SLL
                            | inst_SRAV | inst_SRA | inst_SRLV | inst_SRL
                            | inst_BEQ | inst_BNE | inst_store | inst_LWL
                            | inst_LWR | inst_MTC0;
    assign inst_rs_is_rdest = inst_ADD | inst_ADDI | inst_ADDU | inst_ADDIU | inst_SUB
                            | inst_SUBU | inst_SLT | inst_SLTI | inst_SLTU
                            | inst_SLTIU | inst_DIV | inst_DIVU | inst_MULT
                            | inst_MULTU | inst_AND | inst_ANDI | inst_NOR
                            | inst_OR | inst_ORI | inst_XOR | inst_XORI
                            | inst_SLLV | inst_SRAV | inst_BEQ | inst_BNE
                            | inst_BGEZ | inst_BGTZ | inst_BLEZ | inst_BLTZ
                            | inst_BGEZAL | inst_BLTZAL | inst_JR |inst_JALR
                            | inst_MTHI | inst_MTLO | inst_load | inst_store;





	wire [31:0] bd_pc;
	assign bd_pc = pc + 3'b100;


	wire 		j_taken;
	wire [31:0] j_target;
	assign  j_taken = inst_J | inst_JAL | inst_jr;

	assign j_target = inst_jr ? rs_real_value : {bd_pc[31:28],target,2'b00};


	wire rs_equal_rt;
	wire rs_ez;
	wire rs_ltz;
	assign rs_equal_rt = (rs_real_value == rt_real_value);
	assign rs_ez = ~(|rs_real_value);
	assign rs_ltz = rs_real_value[31];
	wire br_taken;
	wire [31:0] br_target;
	assign br_taken = inst_BEQ & rs_equal_rt
					| inst_BNE & ~rs_equal_rt
					| inst_BGEZ & ~rs_ltz
                    | inst_BGEZAL & ~rs_ltz
					| inst_BGTZ & ~rs_ltz & ~rs_ez
					| inst_BLEZ & (rs_ltz | rs_ez)
					| inst_BLTZ & rs_ltz
					| inst_BLTZAL & rs_ltz;

	assign br_target[31:2] = bd_pc[31:2] + {{14{offset[15]}}, offset};
	assign br_target[1:0] = bd_pc[1:0];


	wire jbr_taken;
	wire [31:0] jbr_target;
	assign jbr_taken = (j_taken | br_taken) & ID_over;
	assign jbr_target = j_taken ? j_target : br_target;


	assign jbr_bus = {jbr_taken, jbr_target};




	wire rs_wait;
	wire rt_wait;
	wire [31:0] rs_quick_get;
	wire [31:0] rt_quick_get;
	
	assign rs_wait = ~inst_no_rs & inst_rs_is_rdest & (rs!=5'd0) & ((rs==EXE_wdest) | (rs==MEM_wdest) | (rs==WB_wdest));
	assign rt_wait = ~inst_no_rt & inst_rt_is_rdest & (rt!=5'd0) & ((rt==EXE_wdest) | (rt==MEM_wdest) | (rt==WB_wdest));
	
	assign rs_quick_get = ((rs==EXE_wdest) & EXE_quick_en & EXE_over) ? EXE_result_quick_get : ((rs==MEM_wdest) & MEM_quick_en & MEM_over) ? MEM_result_quick_get : 32'd0;
	assign rt_quick_get = ((rt==EXE_wdest) & EXE_quick_en & EXE_over) ? EXE_result_quick_get : ((rt==MEM_wdest) & MEM_quick_en & MEM_over) ? MEM_result_quick_get : 32'd0;

    assign rs_real_value = (rs_wait & (((rs==EXE_wdest) & EXE_quick_en & EXE_over) | ((rs==MEM_wdest) & MEM_quick_en & MEM_over))) ? rs_quick_get : rs_value;
    assign rt_real_value = (rt_wait & (((rt==EXE_wdest) & EXE_quick_en & EXE_over) | ((rt==MEM_wdest) & MEM_quick_en & MEM_over))) ? rt_quick_get : rt_value;






	assign ID_over = ID_valid 
	               & (~rs_wait | ((rs==EXE_wdest) & EXE_quick_en & EXE_over) | ((rs==MEM_wdest) & MEM_quick_en & MEM_over)) 
	               & (~rt_wait | ((rt==EXE_wdest) & EXE_quick_en & EXE_over) | ((rt==MEM_wdest) & MEM_quick_en & MEM_over))
	               & (~inst_jbr | IF_over);




	wire [1:0] muldiv;
	wire muldiv_signed;
	wire mthi;
	wire mtlo;
    assign muldiv = inst_mul ? 2'b01 : inst_div ? 2'b10 : 2'b00;
    assign muldiv_signed = inst_signed;
	assign mthi = inst_MTHI;
	assign mtlo = inst_MTLO;

	wire [11:0] alu_control;
	wire [31:0] alu_operand1;
	wire [31:0] alu_operand2;



	assign alu_operand1 = inst_j_link ? pc : inst_shf_sa ? {27'd0,sa} : inst_op1_use_rs_low5 ? {27'd0,rs_real_value[4:0]} : rs_real_value;
	assign alu_operand2 = inst_j_link ? 32'd8 : inst_imm_zero ? {16'd0, imm} : inst_imm_sign ? {{16{imm[15]}},imm} : rt_real_value;
	assign alu_control = {inst_add,
						  inst_sub, 
						  inst_slt, 
						  inst_sltu,  
						  inst_and, 
						  inst_nor, 
						  inst_or, 
						  inst_xor, 
						  inst_sll, 
						  inst_srl, 
						  inst_sra, 
						  inst_lui};

	wire lb_sign;
	wire ls_word;
    wire [1:0] ls_bit;
	wire [5:0] mem_control;
	wire [31:0] store_data;
	assign lb_sign = inst_LB;
	assign ls_word = inst_LW | inst_SW | inst_LWL | inst_LWR | inst_SWL | inst_SWR;
    assign ls_bit[1] = inst_LWL | inst_SWL | inst_LW | inst_SW;
    assign ls_bit[0] = inst_LWR | inst_SWR | inst_LW | inst_SW;
	assign mem_control = {inst_load,
						  inst_store,
						  ls_word,
						  lb_sign,
                          ls_bit};


	wire mfhi;
	wire mflo;
	wire mtc0;
	wire mfc0;
	wire [7:0] cp0r_addr;
	wire syscall;
    wire eret;
	wire break;
    wire ri_exc;
    wire ov_exc_en;
    wire [1:0] halfword;
	wire [3:0] rf_wen;
	wire [4:0] rf_wdest;
	wire       data_related_en;
	assign syscall = inst_SYSCALL;
	assign eret = inst_ERET;
    assign break = inst_BREAK;
    assign ri_exc = ~(inst_add | inst_sub | inst_slt | inst_sltu
                  | inst_and | inst_nor | inst_or  | inst_xor 
                  | inst_sll | inst_srl | inst_sra | inst_lui
                  | inst_mul | inst_div
                  | inst_load | inst_store | inst_jbr 
                  | mthi | mtlo | mfhi | mflo | mtc0 | mfc0 
                  | syscall | eret | break);
    assign ov_exc_en = inst_ADD | inst_ADDI | inst_SUB;
	assign mfhi = inst_MFHI;
	assign mflo = inst_MFLO;
	assign mtc0 = inst_MTC0;
	assign mfc0 = inst_MFC0;
	assign cp0r_addr = {rd,cp0r_sel};
	assign halfword = (inst_LH | inst_SH) ? 2'b10 : inst_LHU ? 2'b01 : 2'b00; 
	assign rf_wen = {4{inst_wdest_rt | inst_wdest_31 | inst_wdest_rd}};
	assign rf_wdest = inst_wdest_rt ? rt :
					  inst_wdest_31 ? 5'd31 :
					  inst_wdest_rd ? rd : 5'd0;
	assign data_related_en = (((alu_control!=12'd0) | (muldiv!=2'd0)) & (!inst_load)) ? 1'b1 : 1'b0;
	assign store_data = rt_real_value;
	assign ID_EXE_bus = {muldiv, muldiv_signed, mthi, mtlo,
						 alu_control, alu_operand1, alu_operand2,
						 data_related_en,
						 mem_control, store_data,
						 mfhi, mflo,
						 mtc0, mfc0, cp0r_addr,
                         syscall, eret, break, addr_exc, ri_exc,ov_exc_en,
						 is_ds,halfword,rf_wen, rf_wdest,
						 pc};



	assign  ID_pc = pc;

endmodule
module decode(
	input wire		ID_valid,
	input wire [65:0]	IF_ID_bus_r,
	input wire [31:0]	rs_value,
	input wire [31:0]	rt_value,
	output wire [ 4:0]	rs,
	output wire [ 4:0]	rt,
	output wire [32:0]	jbr_bus,
	output			    inst_jbr,
	output wire 		ID_over,
	output wire [181:0]	ID_EXE_bus,


	input wire 		IF_over,
	input wire      EXE_over,
	input wire      MEM_over,
	input wire [ 4:0]	EXE_wdest,
	input wire [ 4:0]	MEM_wdest,
	input wire [ 4:0]	WB_wdest,
    input wire [31:0]   EXE_result_quick_get,
    input wire [31:0]   MEM_result_quick_get,
    input wire          EXE_quick_en,
    input wire          MEM_quick_en,


	output wire [31:0]	ID_pc
);



	wire [31:0] pc;
	wire [31:0] inst;
    wire addr_exc;
    wire is_ds;
	assign {pc, inst, addr_exc, is_ds} = IF_ID_bus_r;



    wire [31:0] rs_real_value;
	wire [31:0] rt_real_value;
    wire [5:0] op;
    wire [4:0] rd;
    wire [4:0] sa;
    wire [5:0] funct;
    wire [15:0] imm;
    wire [15:0] offset;
    wire [25:0] target;
    wire [2:0] cp0r_sel;
    
    assign op       = inst[31:26];
    assign rs       = inst[25:21];
    assign rt       = inst[20:16];
    assign rd       = inst[15:11];
    assign sa       = inst[10:6];
    assign funct    = inst[5:0];
    assign imm      = inst[15:0];
    assign offset   = inst[15:0];
    assign target   = inst[25:0];
    assign cp0r_sel = inst[2:0];


    


    wire inst_ADD,	  inst_ADDI,	inst_ADDU,		inst_ADDIU;
    wire inst_SUB,     inst_SUBU,  	inst_SLT,   	inst_SLTI;
    wire inst_SLTU,    inst_SLTIU,  	inst_DIV,    	inst_DIVU;
    wire inst_MULT,    inst_MULTU,  	inst_AND,    	inst_ANDI;
    wire inst_LUI,     inst_NOR,    	inst_OR,     	inst_ORI;
    wire inst_XOR,     inst_XORI,   	inst_SLL,    	inst_SLLV,   inst_SRA;
    wire inst_SRAV,    inst_SRL,    	inst_SRLV,   	inst_BEQ;
    wire inst_BNE,     inst_BGEZ,   	inst_BGTZ,   	inst_BLEZ;
    wire inst_BLTZ,    inst_BLTZAL, 	inst_BGEZAL,	inst_J;
    wire inst_JAL,     inst_JR,     	inst_JALR, 		inst_MFHI;
    wire inst_MFLO,    inst_MTHI,   	inst_MTLO, 		inst_BREAK;
    wire inst_SYSCALL, inst_LB,     	inst_LBU,    	inst_LH;
    wire inst_LHU,     inst_LW,     	inst_LWL,       inst_LWR;
    wire inst_SB,     	inst_SH,        inst_SWL,       inst_SWR;
    wire inst_SW,      inst_ERET,   	inst_MFC0,   	inst_MTC0;

    wire op_zero;
    wire rs_zero;
    wire rt_zero;
    wire rd_zero;
    wire sa_zero;

    assign op_zero = ~(|op);
    assign rs_zero = ~(|rs);
    assign rt_zero = ~(|rt);
    assign rd_zero = ~(|rd);
    assign sa_zero = ~(|sa);
    
    assign inst_ADD = op_zero & sa_zero & (funct == 6'b100000);
    assign inst_ADDI = (op == 6'b001000);
    assign inst_ADDU = op_zero & sa_zero & (funct == 6'b100001);
    assign inst_ADDIU = (op == 6'b001001);
    assign inst_SUB = op_zero & sa_zero & (funct == 6'b100010);
    assign inst_SUBU = op_zero & sa_zero & (funct == 6'b100011);
    assign inst_SLT = op_zero & sa_zero & (funct == 6'b101010);
    assign inst_SLTI = (op == 6'b001010);
    assign inst_SLTU = op_zero & sa_zero & (funct == 6'b101011);
    assign inst_SLTIU = (op == 6'b001011);
    assign inst_DIV = op_zero & rd_zero & sa_zero & (funct == 6'b011010);
    assign inst_DIVU = op_zero & rd_zero & sa_zero & (funct == 6'b011011);
    assign inst_MULT = op_zero & rd_zero & sa_zero & (funct == 6'b011000);
    assign inst_MULTU = op_zero & rd_zero & sa_zero & (funct == 6'b011001);
    assign inst_AND = op_zero & sa_zero & (funct == 6'b100100);
    assign inst_ANDI = (op == 6'b001100);
    assign inst_LUI = (op == 6'b001111) & rs_zero;
    assign inst_NOR = op_zero & sa_zero & (funct == 6'b100111);
    assign inst_OR = op_zero & sa_zero & (funct == 6'b100101);
    assign inst_ORI = (op == 6'b001101);
    assign inst_XOR = op_zero & sa_zero & (funct == 6'b100110);
    assign inst_XORI = (op == 6'b001110);
    assign inst_SLL = op_zero & rs_zero & (funct == 6'b000000);
    assign inst_SLLV = op_zero & sa_zero & (funct == 6'b000100);
    assign inst_SRA = op_zero & rs_zero & (funct == 6'b000011);
    assign inst_SRAV = op_zero & sa_zero & (funct == 6'b0000111);
    assign inst_SRL = op_zero & rs_zero & (funct == 6'b000010);
    assign inst_SRLV = op_zero & sa_zero & (funct == 6'b000110);
    assign inst_BEQ = (op == 6'b000100);
    assign inst_BNE = (op == 6'b000101);
    assign inst_BGEZ = (op == 6'b000001) & (rt == 5'b00001);
    assign inst_BGTZ = (op == 6'b000111) & rt_zero;
    assign inst_BLEZ = (op == 6'b000110) & rt_zero;
    assign inst_BLTZ = (op == 6'b000001) & rt_zero;
    assign inst_BLTZAL = (op == 6'b000001) & (rt == 5'b10000);
    assign inst_BGEZAL = (op == 6'b000001) & (rt == 5'b10001);
    assign inst_J = (op == 6'b000010);
    assign inst_JAL = (op == 6'b000011);
    assign inst_JR = op_zero & rt_zero & rd_zero & (funct == 6'b001000);
    assign inst_JALR = op_zero & rt_zero & (funct == 6'b001001);
    assign inst_MFHI = op_zero & rs_zero & rt_zero & sa_zero & (funct == 6'b010000);
    assign inst_MFLO = op_zero & rs_zero & rt_zero & sa_zero & (funct == 6'b010010);
    assign inst_MTHI = op_zero & rt_zero & rd_zero & sa_zero & (funct == 6'b010001);
    assign inst_MTLO = op_zero & rt_zero & rd_zero & sa_zero & (funct == 6'b010011);
    assign inst_BREAK = op_zero & (funct == 6'b001101);
    assign inst_SYSCALL = op_zero & (funct == 6'b001100);
    assign inst_LB = (op == 6'b100000);
    assign inst_LBU = (op == 6'b100100);
    assign inst_LH = (op == 6'b100001);
    assign inst_LHU = (op == 6'b100101);
    assign inst_LW = (op == 6'b100011);
    assign inst_LWL = (op == 6'b100010);
    assign inst_LWR = (op == 6'b100110);
    assign inst_SB = (op == 6'b101000);
    assign inst_SH = (op == 6'b101001);
    assign inst_SW = (op == 6'b101011);
    assign inst_SWL = (op == 6'b101010);
    assign inst_SWR = (op == 6'b101110);
    assign inst_ERET = (op == 6'b010000) & (rs == 5'b10000) & rt_zero & rd_zero & sa_zero & (funct == 6'b011000);
    assign inst_MFC0 = (op == 6'b010000) & rs_zero & (inst[10:3] == 8'd0);
    assign inst_MTC0 = (op == 6'b010000) & (rs == 5'b00100) & (inst[10:3] == 8'd0);


    wire inst_jr;
    wire inst_j_link;
    assign inst_jr = inst_JALR | inst_JR;
    assign inst_j_link = inst_JAL | inst_JALR | inst_BLTZAL | inst_BGEZAL;
    assign inst_jbr = inst_J 		| inst_JAL 		| inst_jr
    				| inst_BEQ		| inst_BNE		| inst_BGEZ
    				| inst_BGTZ 	| inst_BLEZ		| inst_BLTZ
    				| inst_BLTZAL 	| inst_BGEZAL;


    wire inst_load;
    wire inst_store;
    assign inst_load = inst_LB | inst_LBU | inst_LH | inst_LHU | inst_LW | inst_LWL | inst_LWR;
    assign inst_store = inst_SB | inst_SH | inst_SW | inst_SWL | inst_SWR;
    
   	
    

    wire inst_add, inst_sub, inst_slt, inst_sltu;
    wire inst_div, inst_mul, inst_and, inst_lui;
    wire inst_nor, inst_or, inst_xor;
    wire inst_sll, inst_srl, inst_sra;
    
    assign inst_add = inst_ADD | inst_ADDI | inst_ADDU | inst_ADDIU | inst_load | inst_store | inst_j_link;
    assign inst_sub = inst_SUB | inst_SUBU;
    assign inst_slt = inst_SLT | inst_SLTI;
    assign inst_sltu =  inst_SLTU | inst_SLTIU;
    assign inst_div = inst_DIV | inst_DIVU;
    assign inst_mul = inst_MULT | inst_MULTU;
    assign inst_and = inst_AND | inst_ANDI;
    assign inst_lui = inst_LUI;
    assign inst_nor = inst_NOR;
    assign inst_or = inst_OR | inst_ORI;
    assign inst_xor = inst_XOR | inst_XORI;
    assign inst_sll = inst_SLL | inst_SLLV;
    assign inst_srl = inst_SRL | inst_SRLV;
    assign inst_sra = inst_SRA | inst_SRAV;


    wire inst_signed;
    assign inst_signed = inst_MULT | inst_DIV;

    wire inst_shf_sa;
    assign inst_shf_sa = inst_SLL | inst_SRA | inst_SRL;
    
    wire inst_op1_use_rs_low5;
    assign inst_op1_use_rs_low5 = inst_SLLV | inst_SRAV;


    wire  inst_imm_zero;
    wire inst_imm_sign;
    assign inst_imm_zero = inst_ANDI | inst_LUI | inst_ORI | inst_XORI;
	assign inst_imm_sign = inst_ADDI | inst_ADDIU | inst_SLTI | inst_SLTIU | inst_load | inst_store;


	wire inst_wdest_rt;
	wire inst_wdest_31;
	wire inst_wdest_rd;
	assign inst_wdest_rt = inst_imm_zero | inst_ADDI | inst_ADDIU | inst_SLTI
						 | inst_SLTIU | inst_load | inst_MFC0;
	assign inst_wdest_31 = inst_JAL  | inst_BLTZAL | inst_BGEZAL;
	assign inst_wdest_rd = inst_ADD  | inst_ADDU   | inst_SUB | inst_SUBU
                         | inst_SLT  | inst_SLTU   | inst_AND | inst_NOR
						 | inst_OR   | inst_XOR    | inst_SLL | inst_SLLV 
						 | inst_SRA	 | inst_SRAV   | inst_SRL | inst_SRLV 
						 | inst_JALR | inst_MFHI   | inst_MFLO;


	wire inst_no_rs;
	wire inst_no_rt;
	assign inst_no_rs = inst_MTC0 | inst_BREAK | inst_SYSCALL | inst_ERET;
	assign inst_no_rt = inst_wdest_rt | inst_BGEZ | inst_BLTZAL | inst_BGEZAL
					  | inst_J | inst_JAL;
    

    wire inst_rt_is_rdest;
    wire inst_rs_is_rdest;
    wire inst_rt_is_wdest;
    assign inst_rt_is_rdest = inst_ADD | inst_ADDU | inst_SUB | inst_SUBU
                            | inst_SLT |inst_SLTU | inst_DIV | inst_DIVU 
                            | inst_MULT | inst_MULTU | inst_AND | inst_NOR
                            | inst_OR | inst_XOR | inst_SLLV | inst_SLL
                            | inst_SRAV | inst_SRA | inst_SRLV | inst_SRL
                            | inst_BEQ | inst_BNE | inst_store | inst_LWL
                            | inst_LWR | inst_MTC0;
    assign inst_rs_is_rdest = inst_ADD | inst_ADDI | inst_ADDU | inst_ADDIU | inst_SUB
                            | inst_SUBU | inst_SLT | inst_SLTI | inst_SLTU
                            | inst_SLTIU | inst_DIV | inst_DIVU | inst_MULT
                            | inst_MULTU | inst_AND | inst_ANDI | inst_NOR
                            | inst_OR | inst_ORI | inst_XOR | inst_XORI
                            | inst_SLLV | inst_SRAV | inst_BEQ | inst_BNE
                            | inst_BGEZ | inst_BGTZ | inst_BLEZ | inst_BLTZ
                            | inst_BGEZAL | inst_BLTZAL | inst_JR |inst_JALR
                            | inst_MTHI | inst_MTLO | inst_load | inst_store;





	wire [31:0] bd_pc;
	assign bd_pc = pc + 3'b100;


	wire 		j_taken;
	wire [31:0] j_target;
	assign  j_taken = inst_J | inst_JAL | inst_jr;

	assign j_target = inst_jr ? rs_real_value : {bd_pc[31:28],target,2'b00};


	wire rs_equal_rt;
	wire rs_ez;
	wire rs_ltz;
	assign rs_equal_rt = (rs_real_value == rt_real_value);
	assign rs_ez = ~(|rs_real_value);
	assign rs_ltz = rs_real_value[31];
	wire br_taken;
	wire [31:0] br_target;
	assign br_taken = inst_BEQ & rs_equal_rt
					| inst_BNE & ~rs_equal_rt
					| inst_BGEZ & ~rs_ltz
                    | inst_BGEZAL & ~rs_ltz
					| inst_BGTZ & ~rs_ltz & ~rs_ez
					| inst_BLEZ & (rs_ltz | rs_ez)
					| inst_BLTZ & rs_ltz
					| inst_BLTZAL & rs_ltz;

	assign br_target[31:2] = bd_pc[31:2] + {{14{offset[15]}}, offset};
	assign br_target[1:0] = bd_pc[1:0];


	wire jbr_taken;
	wire [31:0] jbr_target;
	assign jbr_taken = (j_taken | br_taken) & ID_over;
	assign jbr_target = j_taken ? j_target : br_target;


	assign jbr_bus = {jbr_taken, jbr_target};




	wire rs_wait;
	wire rt_wait;
	wire [31:0] rs_quick_get;
	wire [31:0] rt_quick_get;
	
	assign rs_wait = ~inst_no_rs & inst_rs_is_rdest & (rs!=5'd0) & ((rs==EXE_wdest) | (rs==MEM_wdest) | (rs==WB_wdest));
	assign rt_wait = ~inst_no_rt & inst_rt_is_rdest & (rt!=5'd0) & ((rt==EXE_wdest) | (rt==MEM_wdest) | (rt==WB_wdest));
	
	assign rs_quick_get = ((rs==EXE_wdest) & EXE_quick_en & EXE_over) ? EXE_result_quick_get : ((rs==MEM_wdest) & MEM_quick_en & MEM_over) ? MEM_result_quick_get : 32'd0;
	assign rt_quick_get = ((rt==EXE_wdest) & EXE_quick_en & EXE_over) ? EXE_result_quick_get : ((rt==MEM_wdest) & MEM_quick_en & MEM_over) ? MEM_result_quick_get : 32'd0;

    assign rs_real_value = (rs_wait & (((rs==EXE_wdest) & EXE_quick_en & EXE_over) | ((rs==MEM_wdest) & MEM_quick_en & MEM_over))) ? rs_quick_get : rs_value;
    assign rt_real_value = (rt_wait & (((rt==EXE_wdest) & EXE_quick_en & EXE_over) | ((rt==MEM_wdest) & MEM_quick_en & MEM_over))) ? rt_quick_get : rt_value;






	assign ID_over = ID_valid 
	               & (~rs_wait | ((rs==EXE_wdest) & EXE_quick_en & EXE_over) | ((rs==MEM_wdest) & MEM_quick_en & MEM_over)) 
	               & (~rt_wait | ((rt==EXE_wdest) & EXE_quick_en & EXE_over) | ((rt==MEM_wdest) & MEM_quick_en & MEM_over))
	               & (~inst_jbr | IF_over);




	wire [1:0] muldiv;
	wire muldiv_signed;
	wire mthi;
	wire mtlo;
    assign muldiv = inst_mul ? 2'b01 : inst_div ? 2'b10 : 2'b00;
    assign muldiv_signed = inst_signed;
	assign mthi = inst_MTHI;
	assign mtlo = inst_MTLO;

	wire [11:0] alu_control;
	wire [31:0] alu_operand1;
	wire [31:0] alu_operand2;



	assign alu_operand1 = inst_j_link ? pc : inst_shf_sa ? {27'd0,sa} : inst_op1_use_rs_low5 ? {27'd0,rs_real_value[4:0]} : rs_real_value;
	assign alu_operand2 = inst_j_link ? 32'd8 : inst_imm_zero ? {16'd0, imm} : inst_imm_sign ? {{16{imm[15]}},imm} : rt_real_value;
	assign alu_control = {inst_add,
						  inst_sub, 
						  inst_slt, 
						  inst_sltu,  
						  inst_and, 
						  inst_nor, 
						  inst_or, 
						  inst_xor, 
						  inst_sll, 
						  inst_srl, 
						  inst_sra, 
						  inst_lui};

	wire lb_sign;
	wire ls_word;
    wire [1:0] ls_bit;
	wire [5:0] mem_control;
	wire [31:0] store_data;
	assign lb_sign = inst_LB;
	assign ls_word = inst_LW | inst_SW | inst_LWL | inst_LWR | inst_SWL | inst_SWR;
    assign ls_bit[1] = inst_LWL | inst_SWL | inst_LW | inst_SW;
    assign ls_bit[0] = inst_LWR | inst_SWR | inst_LW | inst_SW;
	assign mem_control = {inst_load,
						  inst_store,
						  ls_word,
						  lb_sign,
                          ls_bit};


	wire mfhi;
	wire mflo;
	wire mtc0;
	wire mfc0;
	wire [7:0] cp0r_addr;
	wire syscall;
    wire eret;
	wire break;
    wire ri_exc;
    wire ov_exc_en;
    wire [1:0] halfword;
	wire [3:0] rf_wen;
	wire [4:0] rf_wdest;
	wire       data_related_en;
	assign syscall = inst_SYSCALL;
	assign eret = inst_ERET;
    assign break = inst_BREAK;
    assign ri_exc = ~(inst_add | inst_sub | inst_slt | inst_sltu
                  | inst_and | inst_nor | inst_or  | inst_xor 
                  | inst_sll | inst_srl | inst_sra | inst_lui
                  | inst_mul | inst_div
                  | inst_load | inst_store | inst_jbr 
                  | mthi | mtlo | mfhi | mflo | mtc0 | mfc0 
                  | syscall | eret | break);
    assign ov_exc_en = inst_ADD | inst_ADDI | inst_SUB;
	assign mfhi = inst_MFHI;
	assign mflo = inst_MFLO;
	assign mtc0 = inst_MTC0;
	assign mfc0 = inst_MFC0;
	assign cp0r_addr = {rd,cp0r_sel};
	assign halfword = (inst_LH | inst_SH) ? 2'b10 : inst_LHU ? 2'b01 : 2'b00; 
	assign rf_wen = {4{inst_wdest_rt | inst_wdest_31 | inst_wdest_rd}};
	assign rf_wdest = inst_wdest_rt ? rt :
					  inst_wdest_31 ? 5'd31 :
					  inst_wdest_rd ? rd : 5'd0;
	assign data_related_en = (((alu_control!=12'd0) | (muldiv!=2'd0)) & (!inst_load)) ? 1'b1 : 1'b0;
	assign store_data = rt_real_value;
	assign ID_EXE_bus = {muldiv, muldiv_signed, mthi, mtlo,
						 alu_control, alu_operand1, alu_operand2,
						 data_related_en,
						 mem_control, store_data,
						 mfhi, mflo,
						 mtc0, mfc0, cp0r_addr,
                         syscall, eret, break, addr_exc, ri_exc,ov_exc_en,
						 is_ds,halfword,rf_wen, rf_wdest,
						 pc};



	assign  ID_pc = pc;

endmodule