data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v
[Errno 2] No such file or directory: 'preprocess.output'
1: b'%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:22: Cannot find include file: opcode.h\n`include "opcode.h" \n         ^~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/103257524/src/cpu,data/full_repos/permissive/103257524/opcode.h\n             data/full_repos/permissive/103257524/src/cpu,data/full_repos/permissive/103257524/opcode.h.v\n             data/full_repos/permissive/103257524/src/cpu,data/full_repos/permissive/103257524/opcode.h.sv\n             opcode.h\n             opcode.h.v\n             opcode.h.sv\n             obj_dir/opcode.h\n             obj_dir/opcode.h.v\n             obj_dir/opcode.h.sv\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:38: Define or directive not defined: \'`ALU_OPCODE_WIDTH\'\n output reg [`ALU_OPCODE_WIDTH-1:0] alu_opcode,\n             ^~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:45: Define or directive not defined: \'`MEM_OPCODE_WIDTH\'\n output reg [`MEM_OPCODE_WIDTH-1:0] mem_opcode,\n             ^~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:365: Define or directive not defined: \'`ALU_OPCODE_WIDTH\'\n  input [`ALU_OPCODE_WIDTH-1:0] alu_op;\n         ^~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:366: Define or directive not defined: \'`MEM_OPCODE_WIDTH\'\n  input [`MEM_OPCODE_WIDTH-1:0] mem_op;\n         ^~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:386: Define or directive not defined: \'`ALU_OPCODE_WIDTH\'\n  input [`ALU_OPCODE_WIDTH-1:0] alu_op;\n         ^~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:387: Define or directive not defined: \'`MEM_OPCODE_WIDTH\'\n  input [`MEM_OPCODE_WIDTH-1:0] mem_op;\n         ^~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:650: Define or directive not defined: \'`ALU_NOP\'\n   alu_opcode <= `ALU_NOP;\n                 ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:650: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n   alu_opcode <= `ALU_NOP;\n                         ^\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:657: Define or directive not defined: \'`MEM_NOP\'\n   mem_opcode <= `MEM_NOP;\n                 ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:657: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n   mem_opcode <= `MEM_NOP;\n                         ^\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:669: Define or directive not defined: \'`ALU_ADD\'\n     OPFUNC_ADD:  decode_rtype(rd, 1, 1, `ALU_ADD, `MEM_NOP);\n                                         ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:669: Define or directive not defined: \'`MEM_NOP\'\n     OPFUNC_ADD:  decode_rtype(rd, 1, 1, `ALU_ADD, `MEM_NOP);\n                                                   ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:670: Define or directive not defined: \'`ALU_ADDU\'\n     OPFUNC_ADDU: decode_rtype(rd, 1, 1, `ALU_ADDU, `MEM_NOP);\n                                         ^~~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:670: Define or directive not defined: \'`MEM_NOP\'\n     OPFUNC_ADDU: decode_rtype(rd, 1, 1, `ALU_ADDU, `MEM_NOP);\n                                                    ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:671: Define or directive not defined: \'`ALU_SUB\'\n     OPFUNC_SUB:  decode_rtype(rd, 1, 1, `ALU_SUB, `MEM_NOP);\n                                         ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:671: Define or directive not defined: \'`MEM_NOP\'\n     OPFUNC_SUB:  decode_rtype(rd, 1, 1, `ALU_SUB, `MEM_NOP);\n                                                   ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:672: Define or directive not defined: \'`ALU_SUBU\'\n     OPFUNC_SUBU: decode_rtype(rd, 1, 1, `ALU_SUBU, `MEM_NOP);\n                                         ^~~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:672: Define or directive not defined: \'`MEM_NOP\'\n     OPFUNC_SUBU: decode_rtype(rd, 1, 1, `ALU_SUBU, `MEM_NOP);\n                                                    ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:673: Define or directive not defined: \'`ALU_SLL\'\n     OPFUNC_SLLV: decode_rtype(rd, 1, 1, `ALU_SLL, `MEM_NOP);\n                                         ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:673: Define or directive not defined: \'`MEM_NOP\'\n     OPFUNC_SLLV: decode_rtype(rd, 1, 1, `ALU_SLL, `MEM_NOP);\n                                                   ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:674: Define or directive not defined: \'`ALU_ROR\'\n     OPFUNC_SRLV: decode_rtype(rd, 1, 1, sa == 5\'h01 ? `ALU_ROR : `ALU_SRL, `MEM_NOP);\n                                                       ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:674: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\n     OPFUNC_SRLV: decode_rtype(rd, 1, 1, sa == 5\'h01 ? `ALU_ROR : `ALU_SRL, `MEM_NOP);\n                                                                ^\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:674: Define or directive not defined: \'`ALU_SRL\'\n     OPFUNC_SRLV: decode_rtype(rd, 1, 1, sa == 5\'h01 ? `ALU_ROR : `ALU_SRL, `MEM_NOP);\n                                                                  ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:674: Define or directive not defined: \'`MEM_NOP\'\n     OPFUNC_SRLV: decode_rtype(rd, 1, 1, sa == 5\'h01 ? `ALU_ROR : `ALU_SRL, `MEM_NOP);\n                                                                            ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:675: Define or directive not defined: \'`ALU_SRA\'\n     OPFUNC_SRAV: decode_rtype(rd, 1, 1, `ALU_SRA, `MEM_NOP);\n                                         ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:675: Define or directive not defined: \'`MEM_NOP\'\n     OPFUNC_SRAV: decode_rtype(rd, 1, 1, `ALU_SRA, `MEM_NOP);\n                                                   ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:676: Define or directive not defined: \'`ALU_AND\'\n     OPFUNC_AND:  decode_rtype(rd, 1, 1, `ALU_AND, `MEM_NOP);\n                                         ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:676: Define or directive not defined: \'`MEM_NOP\'\n     OPFUNC_AND:  decode_rtype(rd, 1, 1, `ALU_AND, `MEM_NOP);\n                                                   ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:677: Define or directive not defined: \'`ALU_OR\'\n     OPFUNC_OR:  decode_rtype(rd, 1, 1, `ALU_OR, `MEM_NOP);\n                                        ^~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:677: Define or directive not defined: \'`MEM_NOP\'\n     OPFUNC_OR:  decode_rtype(rd, 1, 1, `ALU_OR, `MEM_NOP);\n                                                 ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:678: Define or directive not defined: \'`ALU_NOR\'\n     OPFUNC_NOR:  decode_rtype(rd, 1, 1, `ALU_NOR, `MEM_NOP);\n                                         ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:678: Define or directive not defined: \'`MEM_NOP\'\n     OPFUNC_NOR:  decode_rtype(rd, 1, 1, `ALU_NOR, `MEM_NOP);\n                                                   ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:679: Define or directive not defined: \'`ALU_XOR\'\n     OPFUNC_XOR:  decode_rtype(rd, 1, 1, `ALU_XOR, `MEM_NOP);\n                                         ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:679: Define or directive not defined: \'`MEM_NOP\'\n     OPFUNC_XOR:  decode_rtype(rd, 1, 1, `ALU_XOR, `MEM_NOP);\n                                                   ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:681: Define or directive not defined: \'`ALU_SLL\'\n      decode_rtype(rd, 0, 1, `ALU_SLL, `MEM_NOP);\n                             ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:681: Define or directive not defined: \'`MEM_NOP\'\n      decode_rtype(rd, 0, 1, `ALU_SLL, `MEM_NOP);\n                                       ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:685: Define or directive not defined: \'`ALU_ROR\'\n      decode_rtype(rd, 0, 1, rs == 5\'h01 ? `ALU_ROR : `ALU_SRL, `MEM_NOP);\n                                           ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:685: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\n      decode_rtype(rd, 0, 1, rs == 5\'h01 ? `ALU_ROR : `ALU_SRL, `MEM_NOP);\n                                                    ^\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:685: Define or directive not defined: \'`ALU_SRL\'\n      decode_rtype(rd, 0, 1, rs == 5\'h01 ? `ALU_ROR : `ALU_SRL, `MEM_NOP);\n                                                      ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:685: Define or directive not defined: \'`MEM_NOP\'\n      decode_rtype(rd, 0, 1, rs == 5\'h01 ? `ALU_ROR : `ALU_SRL, `MEM_NOP);\n                                                                ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:689: Define or directive not defined: \'`ALU_SRA\'\n      decode_rtype(rd, 0, 1, `ALU_SRA, `MEM_NOP);\n                             ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:689: Define or directive not defined: \'`MEM_NOP\'\n      decode_rtype(rd, 0, 1, `ALU_SRA, `MEM_NOP);\n                                       ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:694: Define or directive not defined: \'`ALU_MULTL\'\n       decode_rtype(rd, 1, 1, `ALU_MULTL, `MEM_NOP);\n                              ^~~~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:694: Define or directive not defined: \'`MEM_NOP\'\n       decode_rtype(rd, 1, 1, `ALU_MULTL, `MEM_NOP);\n                                          ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:696: Define or directive not defined: \'`ALU_MULTH\'\n       decode_rtype(rd, 1, 1, `ALU_MULTH, `MEM_NOP);\n                              ^~~~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:696: Define or directive not defined: \'`MEM_NOP\'\n       decode_rtype(rd, 1, 1, `ALU_MULTH, `MEM_NOP);\n                                          ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:701: Define or directive not defined: \'`ALU_MULTLU\'\n       decode_rtype(rd, 1, 1, `ALU_MULTLU, `MEM_NOP);\n                              ^~~~~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:701: Define or directive not defined: \'`MEM_NOP\'\n       decode_rtype(rd, 1, 1, `ALU_MULTLU, `MEM_NOP);\n                                           ^~~~~~~~\n%Error: data/full_repos/permissive/103257524/src/cpu/pipeline_decode.v:703: Define or directive not defined: \'`ALU_MULTHU\'\n       decode_rtype(rd, 1, 1, `ALU_MULTHU, `MEM_NOP);\n                              ^~~~~~~~~~~\n%Error: Exiting due to too many errors encountered; --error-limit=50\n'
module pipeline_decode(
	input CLK,
	input RST,
	
	input [31:0] 		prev_insn,
	input [31:0] 		prev_insnPC,
	input 				prev_placeholder_insn,
	output reg 			prev_next_insn_enabled,
	output reg [31:0] 	prev_next_insn,
	output 				prev_busy,
	
	input 								next_busy,
	output reg [31:0] 					next_insnPC,
	output reg [2:0]					next_insn_id,
	output reg [`ALU_OPCODE_WIDTH-1:0]	alu_opcode,
	output reg [31:0]					alu_src1,
	output reg 							alu_src1_forward,
	output reg [2:0]					alu_src1_forward_from,
	output reg [31:0]					alu_src2,
	output reg 							alu_src2_forward,
	output reg [2:0]					alu_src2_forward_from,
	output reg [`MEM_OPCODE_WIDTH-1:0]	mem_opcode,
	output reg [31:0]					mem_src2,
	output reg 							mem_src2_forward,
	output reg [2:0]					mem_src2_forward_from,
	
	input [2:0]		writeback_insn_id,
	input [31:0] 	writeback_data,
	
	input [2:0]		alu_forward_insn_id,
	input [31:0]	alu_forward_data
    );
    
    localparam OPCD_SPECIAL 	= 6'h00;
    localparam OPCD_REGIMM		= 6'h01;
    localparam OPCD_BEQ			= 6'h04;
    localparam OPCD_BNE			= 6'h05;
    localparam OPCD_POP06		= 6'h06;
    localparam OPCD_POP07		= 6'h07;

	localparam OPCD_POP10		= 6'h08;
    localparam OPCD_ADDIU		= 6'h09;
    localparam OPCD_SLTI		= 6'h0A;
    localparam OPCD_SLTIU		= 6'h0B;
    localparam OPCD_ANDI		= 6'h0C;
    localparam OPCD_ORI			= 6'h0D;
    localparam OPCD_XORI		= 6'h0E;
    localparam OPCD_AUI			= 6'h0F;
	localparam OPCD_POP26		= 6'h16;
	localparam OPCD_POP27		= 6'h17;
	localparam OPCD_POP30		= 6'h18;
    localparam OPCD_LB			= 6'h20;
    localparam OPCD_LH			= 6'h21;
    localparam OPCD_LW			= 6'h23;
    localparam OPCD_LBU			= 6'h24;
    localparam OPCD_LHU			= 6'h25;
    localparam OPCD_SB			= 6'h28;
    localparam OPCD_SH			= 6'h29;
	localparam OPCD_SW			= 6'h2B;
    localparam OPCD_LWC1		= 6'h31;
    localparam OPCD_SWC1		= 6'h39;
    localparam OPCD_J			= 6'h02;
    localparam OPCD_JAL			= 6'h03;
    localparam OPCD_BC			= 6'h32;
	localparam OPCD_POP66		= 6'h36;
    localparam OPCD_BALC		= 6'h3A;
	localparam OPCD_POP76		= 6'h3E;
    
    localparam OPFUNC_SLL		= 6'h00;
    localparam OPFUNC_SRL		= 6'h02;
    localparam OPFUNC_SRA		= 6'h03;
    localparam OPFUNC_SLLV		= 6'h04;
    localparam OPFUNC_SRLV		= 6'h06;
    localparam OPFUNC_SRAV		= 6'h07;
    localparam OPFUNC_JR		= 6'h08;
    localparam OPFUNC_JALR		= 6'h09;
    localparam OPFUNC_SYSCALL	= 6'h0C;
    localparam OPFUNC_BREAK		= 6'h0D;
    localparam OPFUNC_SOP30		= 6'h18;
    localparam OPFUNC_SOP31		= 6'h19;
    localparam OPFUNC_SOP32		= 6'h1A;
    localparam OPFUNC_SOP33		= 6'h1B;
    localparam OPFUNC_ADD		= 6'h20;
    localparam OPFUNC_ADDU		= 6'h21;
    localparam OPFUNC_SUB		= 6'h22;
    localparam OPFUNC_SUBU		= 6'h23;
    localparam OPFUNC_AND		= 6'h24;
    localparam OPFUNC_OR		= 6'h25;
    localparam OPFUNC_XOR		= 6'h26;
    localparam OPFUNC_NOR		= 6'h27;
    localparam OPFUNC_SLT		= 6'h2A;
    localparam OPFUNC_SLTU		= 6'h2B;
    
    
    
    reg [31:0] 	insn;
    reg [31:0]	insnPC;
    reg [2:0] 	insn_id;
    reg [4:0]	insn_write_reg[7:0];

	reg			insn_data_overrided[7:0];
	
    reg [31:0] 	reg_file[31:1];
	wire [31:0]	GPR[31:0];
	
    reg 		reg_lock[31:0];
    reg [2:0]	reg_lock_by[31:0];


	reg [4:0]	next_insn_write_reg;

	
	reg [4:0] next_insn_write_reg_pending;

    
	genvar j;
	generate 
		for(j=1; j<32; j=j+1)
			assign GPR[j] = reg_file[j];
	endgenerate
	assign GPR[0] = 0;
    
    
	
    reg busy;
    assign prev_busy = busy || next_busy;
	
	wire writeback_flag =!insn_data_overrided[writeback_insn_id];
	wire alu_forward_flag =!insn_data_overrided[alu_forward_insn_id];
	
	wire [4:0] writeback_reg = insn_write_reg[writeback_insn_id];

	wire [4:0] alu_forward_reg = insn_write_reg[alu_forward_insn_id];

	
    integer i;

	
	task write_register;
		input [4:0] regid;

		begin


				next_insn_write_reg_pending <= regid;

		end
	endtask
	
	reg drop_next_insn;
	
	localparam NEVER 		= 0;
	localparam ALWAYS 		= 1;
	localparam RS_EQ_RT 	= 2;
	localparam RS_NE_RT		= 3;
	localparam RS_GTU_RT	= 4;
	localparam RS_LTU_RT	= 5;
	localparam RS_GEU_RT	= 6;
	localparam RS_LEU_RT	= 7;
	localparam RS_GT_RT		= 8;
	localparam RS_LT_RT		= 9;
	localparam RS_GE_RT		= 10;
	localparam RS_LE_RT		= 11;
	localparam RS_EQ_ZERO	= 12;
	localparam RS_NE_ZERO	= 13;
	localparam RS_GT_ZERO	= 14;
	localparam RS_LT_ZERO	= 15;
	localparam RS_GE_ZERO	= 16;
	localparam RS_LE_ZERO	= 17;
	localparam RT_EQ_ZERO	= 18;
	localparam RT_NE_ZERO	= 19;
	localparam RT_GT_ZERO	= 20;
	localparam RT_LT_ZERO	= 21;
	localparam RT_GE_ZERO	= 22;
	localparam RT_LE_ZERO	= 23;
	
	reg [23:0] jump_cond;
	reg [6:0] jump_cond_basic;
	reg [4:0] 	jump_cond_id;
	
	localparam JUMP_J = 0;
	localparam JUMP_BC = 1;
	localparam JUMP_BALC = 2;
	localparam JUMP_BC_LONG = 4;
	localparam JUMP_J_LONG = 8;
	localparam JUMP_BC_VERY_LONG = 16;
	localparam JUMP_GPR_RS = 32;
	reg	[5:0]	jump_type;
	
	reg [3:0] POP_insn_type;
	reg [31:0] Branch_target;
	reg [31:0] BC_target;
	reg [31:0] BC_long_target;
	reg [31:0] J_target;
	reg [31:0] BC_very_long_target;
	




	reg [31:0] GPR_rs, GPR_rt;
	reg 		rs_lock, rt_lock;
	reg [2:0] rs_lock_by, rt_lock_by;

	

	
	reg [5:0] opcode;
    reg [4:0] rs, rt, rd, sa;
    reg [5:0] opfunc;
    reg [15:0] imm;
    reg [25:0] j_addr;
	
	task fetch_rs;
		begin
			alu_src1 <= GPR_rs;
			alu_src1_forward <= rs_lock;
			alu_src1_forward_from <= rs_lock_by;
		end
	endtask
	
	task fetch_rt;
		begin
			alu_src2 <= GPR_rt;
			alu_src2_forward <= rt_lock;
			alu_src2_forward_from <= rt_lock_by;
		end
	endtask
	
	task decode_rtype;
		input [4:0] dst;
		input use_src1;
		input use_src2;
		input [`ALU_OPCODE_WIDTH-1:0] alu_op;
		input [`MEM_OPCODE_WIDTH-1:0] mem_op;
		
		begin
			if(use_src1) begin
				fetch_rs();
			end
			if(use_src2) begin
				fetch_rt();
			end
			alu_opcode <= alu_op;
			mem_opcode <= mem_op;
			write_register(dst);
		end
	endtask
	
	task decode_itype;
		input [4:0] 	dst;
		input 			use_src1;
		input			sign_extend;

		input [`ALU_OPCODE_WIDTH-1:0] alu_op;
		input [`MEM_OPCODE_WIDTH-1:0] mem_op;
		
		begin
			if(use_src1) begin
				fetch_rs();
			end

			if(sign_extend)
				alu_src2 <= {{16{imm[15]}}, imm};
			else
				alu_src2 <= {16'b0, imm};
			alu_opcode <= alu_op;
			mem_opcode <= mem_op;
			write_register(dst);
		end
	endtask
	
	reg tmp_busy;
	
	reg [31:0] tmp_GPR_rs, tmp_GPR_rt;
	reg clear_next_insn;
	
	reg [31:0] last_next_insn;
	reg last_next_insn_enabled;
	reg last_drop_next_insn;
	
	reg [31:0]	insnPC_add_4;
	
	always @(posedge CLK or posedge RST) begin
		if(RST) begin
			insn <= 0;
			insnPC <= 0;
			reg_lock[0] <= 0;

			reg_lock_by[0] <= 0;
			for(i=1; i<32; i=i+1) begin
				reg_file[i] <= 0;
				reg_lock[i] <= 0;
				reg_lock_by[i] <= 0;

			end
			for(i=0; i<8; i=i+1) begin

				insn_data_overrided[i] <= 1;
				insn_write_reg[i] <= 0;
			end
			


			next_insnPC <= 0;
			alu_opcode <= 0;
			alu_src1 <= 0;
			alu_src2 <= 0;
			alu_src1_forward <= 0;
			alu_src1_forward_from <= 0;
			alu_src2_forward <= 0;
			alu_src2_forward_from <= 0;
			mem_opcode <= 0;
			mem_src2 <= 0;
			mem_src2_forward <= 0;
			mem_src2_forward_from <= 0;
			insn_id <= 0;
			next_insn_id <= 0;




			next_insn_write_reg_pending <= 0;
			


			last_next_insn <= 0;
			last_next_insn_enabled <= 0;
			last_drop_next_insn <= 0;
			
			clear_next_insn <= 1;
		end else begin
			if(writeback_flag) begin
				if(writeback_reg == 0)
					$display("Assertion Failed: Writeback_reg == 0");
				reg_file[writeback_reg] <= writeback_data;
				reg_lock[writeback_reg] <= 0;


			end
			if(alu_forward_flag) begin
				if(alu_forward_reg == 0)
					$display("Assertion Failed: ALU_forward_reg == 0");
					
				reg_file[alu_forward_reg] <= alu_forward_data;
				reg_lock[alu_forward_reg] <= 0;


			end

			if(!prev_busy) begin
				insn	= prev_insn;
				insnPC	= prev_insnPC;
				
				if(next_insn_write_reg != 0) begin
					insn_write_reg[next_insn_id]			<= next_insn_write_reg;

					insn_data_overrided[next_insn_id]		<= 0;
					reg_lock[next_insn_write_reg]			<= 1;

					if(reg_lock[next_insn_write_reg])
						insn_data_overrided[reg_lock_by[next_insn_write_reg]] <= 1;
					reg_lock_by[next_insn_write_reg]		<= next_insn_id;
				end else begin
					insn_write_reg[next_insn_id]	<= 0;
					insn_data_overrided[next_insn_id] <= 1;

				end
			end
			
			opcode 	= insn[31:26];
			rs 		= insn[25:21];
			rt 		= insn[20:16];
			rd 		= insn[15:11];
			sa 		= insn[10:6];
			opfunc 	= insn[5:0];
			imm 	= insn[15:0];
			j_addr	= insn[25:0];
			
			
			
			
			case(1'b1)
			writeback_flag && rs == writeback_reg: begin
				GPR_rs = writeback_data;
				rs_lock = 0;
				rs_lock_by = 0;

			end
			
			alu_forward_flag && rs == alu_forward_reg: begin
				GPR_rs = alu_forward_data;
				rs_lock = 0;
				rs_lock_by = 0;

			end
			
			default: begin
				GPR_rs	= GPR[rs];
				rs_lock = reg_lock[rs];
				rs_lock_by = reg_lock_by[rs];

			end
			endcase
			
			case(1'b1)
			writeback_flag && rt == writeback_reg: begin
				GPR_rt = writeback_data;
				rt_lock = 0;
				rt_lock_by = 0;

			end
			
			alu_forward_flag && rt == alu_forward_reg: begin
				GPR_rt = alu_forward_data;
				rt_lock = 0;
				rt_lock_by = 0;

			end
			
			default: begin
				GPR_rt	= GPR[rt];	
				rt_lock = reg_lock[rt];
				rt_lock_by = reg_lock_by[rt];

			end
			endcase
			
			if(!prev_busy) begin
				if(next_insn_write_reg != 0 && rs == next_insn_write_reg) begin
					rs_lock = 1;

					rs_lock_by = next_insn_id;
				end
				if(next_insn_write_reg != 0 && rt == next_insn_write_reg) begin
					rt_lock = 1;

					rt_lock_by = next_insn_id;
				end
			end
			


			insnPC_add_4 = insnPC + 4;
			Branch_target <= insnPC_add_4 + {{14{imm[15]}}, imm, 2'b00};
			BC_target <= insnPC_add_4 + {{14{imm[15]}}, imm, 2'b00};
			BC_long_target <= insnPC_add_4 + {{9{rt[4]}}, rt, imm, 2'b00};
			J_target <= {insnPC_add_4[31:28], rs, rt, imm, 2'b00};
			BC_very_long_target <= insnPC_add_4 + {{4{rs[4]}}, rs, rt, imm, 2'b00};
			


			jump_cond_basic[0] <= GPR_rs == GPR_rt;

			jump_cond_basic[1] <= GPR_rs > GPR_rt;



			jump_cond_basic[2] <= $signed(GPR_rs) > $signed(GPR_rt);



			jump_cond_basic[3] <= GPR_rs == 0;

			jump_cond_basic[4] <= $signed(GPR_rs) > 0;



			jump_cond_basic[5] <= GPR_rt == 0;

			jump_cond_basic[6] <= $signed(GPR_rt) > 0;



					
			if(rt == 0)
				POP_insn_type = rs_lock ? 4'd8 : 4'd0;
			else if(rs == 0)
				POP_insn_type = rt_lock ? 4'd8 : 4'd1;
			else if(rs == rt)
				POP_insn_type = rt_lock ? 4'd8 : 4'd2;
			else
				POP_insn_type = rs_lock || rt_lock ? 4'd8 : 4'd4;
			
			tmp_busy = 0;
			case(opcode)
			OPCD_SPECIAL: begin
				if(opfunc == OPFUNC_JR || opfunc == OPFUNC_JALR)
					tmp_busy = rs_lock;
			end
			OPCD_REGIMM: 			tmp_busy = rs_lock;
			OPCD_BEQ, OPCD_BNE: 	tmp_busy = rs_lock || rt_lock;
			OPCD_POP06, OPCD_POP07, 
			OPCD_POP10, OPCD_POP26, 
			OPCD_POP27, OPCD_POP30, 
			OPCD_POP66, OPCD_POP76:	tmp_busy = POP_insn_type[3];
			endcase
			
			busy <= tmp_busy;
			
			jump_cond_id <= NEVER;
			jump_type <= JUMP_J;
			
			clear_next_insn <= 0;
			if(!prev_placeholder_insn) begin

				clear_next_insn <= 1;
			end
			if(!next_busy) begin
				if(insn_id == 3'b011)
					insn_id = 0;
				else
					insn_id = insn_id + 1;
			end
			next_insn_write_reg_pending <= 0;

			alu_opcode <= `ALU_NOP;
			alu_src1 <= 0;
			alu_src2 <= 0;
			alu_src1_forward <= 0;
			alu_src2_forward <= 0;
			alu_src1_forward_from <= 0;
			alu_src2_forward_from <= 0;
			mem_opcode <= `MEM_NOP;
			mem_src2 <= 0;
			mem_src2_forward <= 0;
			mem_src2_forward_from <= 0;
			next_insnPC <= insnPC;
			next_insn_id <= busy ? 3'b111 : insn_id;
			
			if(!drop_next_insn && !tmp_busy) begin
				case(opcode)
				OPCD_SPECIAL: begin
					
					case(opfunc)
					OPFUNC_ADD:		decode_rtype(rd, 1, 1, `ALU_ADD, `MEM_NOP);
					OPFUNC_ADDU:	decode_rtype(rd, 1, 1, `ALU_ADDU, `MEM_NOP);
					OPFUNC_SUB:		decode_rtype(rd, 1, 1, `ALU_SUB, `MEM_NOP);
					OPFUNC_SUBU:	decode_rtype(rd, 1, 1, `ALU_SUBU, `MEM_NOP);
					OPFUNC_SLLV:	decode_rtype(rd, 1, 1, `ALU_SLL, `MEM_NOP);
					OPFUNC_SRLV:	decode_rtype(rd, 1, 1, sa == 5'h01 ? `ALU_ROR : `ALU_SRL, `MEM_NOP);
					OPFUNC_SRAV:	decode_rtype(rd, 1, 1, `ALU_SRA, `MEM_NOP);
					OPFUNC_AND:		decode_rtype(rd, 1, 1, `ALU_AND, `MEM_NOP);
					OPFUNC_OR:		decode_rtype(rd, 1, 1, `ALU_OR, `MEM_NOP);
					OPFUNC_NOR:		decode_rtype(rd, 1, 1, `ALU_NOR, `MEM_NOP);
					OPFUNC_XOR:		decode_rtype(rd, 1, 1, `ALU_XOR, `MEM_NOP);
					OPFUNC_SLL: begin
						decode_rtype(rd, 0, 1, `ALU_SLL, `MEM_NOP);
						alu_src1 <= {27'b0, sa};
					end
					OPFUNC_SRL: begin
						decode_rtype(rd, 0, 1, rs == 5'h01 ? `ALU_ROR : `ALU_SRL, `MEM_NOP);
						alu_src1 <= {27'b0, sa};
					end
					OPFUNC_SRA: begin
						decode_rtype(rd, 0, 1, `ALU_SRA, `MEM_NOP);
						alu_src1 <= {27'b0, sa};
					end
					OPFUNC_SOP30: begin
						if(sa == 5'b00010)
							decode_rtype(rd, 1, 1, `ALU_MULTL, `MEM_NOP);
						else if(sa == 5'b00011)
							decode_rtype(rd, 1, 1, `ALU_MULTH, `MEM_NOP);

					end
					OPFUNC_SOP31: begin
						if(sa == 5'b00010)
							decode_rtype(rd, 1, 1, `ALU_MULTLU, `MEM_NOP);
						else if(sa == 5'b00011)
							decode_rtype(rd, 1, 1, `ALU_MULTHU, `MEM_NOP);

					end
					OPFUNC_SOP32: begin
						if(sa == 5'b00010)
							decode_rtype(rd, 1, 1, `ALU_DIV, `MEM_NOP);
						else if(sa == 5'b00011)
							decode_rtype(rd, 1, 1, `ALU_MOD, `MEM_NOP);

					end
					OPFUNC_SOP33: begin
						if(sa == 5'b00010)
							decode_rtype(rd, 1, 1, `ALU_DIVU, `MEM_NOP);
						else if(sa == 5'b00011)
							decode_rtype(rd, 1, 1, `ALU_MODU, `MEM_NOP);
					end
					OPFUNC_JR: begin 
begin
							jump_cond_id <= ALWAYS;
							jump_type <= JUMP_GPR_RS;
						end

					end
					OPFUNC_JALR: begin
begin
							jump_cond_id <= ALWAYS;
							jump_type <= JUMP_GPR_RS;

							alu_src1 <= insnPC + 8;
							write_register(31);
						end
					end
					OPFUNC_SLT: 	decode_rtype(rd, 1, 1, `ALU_SLT, `MEM_NOP);
					OPFUNC_SLTU:	decode_rtype(rd, 1, 1, `ALU_SLTU, `MEM_NOP);
					default:;
					endcase
				end
				

				OPCD_ADDIU:		decode_itype(rt, 1, 1, `ALU_ADDU, `MEM_NOP);
				OPCD_ANDI:		decode_itype(rt, 1, 0, `ALU_AND, `MEM_NOP);
				OPCD_ORI:		decode_itype(rt, 1, 0, `ALU_OR, `MEM_NOP);
				OPCD_XORI:		decode_itype(rt, 1, 0, `ALU_XOR, `MEM_NOP);
				OPCD_BEQ: begin
begin

						jump_cond_id <= RS_EQ_RT;
						jump_type <= JUMP_J;
					end


				end
				OPCD_BNE: begin
begin

						jump_cond_id <= RS_NE_RT;

						jump_type <= JUMP_J;
					end


				end
				OPCD_J: begin


					jump_cond_id <= ALWAYS;
					jump_type <= JUMP_J_LONG;


				end
				OPCD_JAL: begin


					jump_cond_id <= ALWAYS;
					jump_type <= JUMP_J_LONG;


					alu_src1 <= insnPC + 8;
					write_register(31);
				end
				OPCD_BC: begin


					jump_cond_id <= ALWAYS;
					jump_type <= JUMP_BC_VERY_LONG;



				end
				OPCD_BALC: begin


					jump_cond_id <= ALWAYS;
					jump_type <= JUMP_BC_VERY_LONG;



					alu_src1 <= insnPC + 4;
					write_register(31);
				end
				OPCD_REGIMM: begin
					if(rt[0]) begin
						begin
							jump_cond_id <= RS_GE_ZERO;
							jump_type <= JUMP_J;
						end
					end elsebegin
						begin
							jump_cond_id <= RS_LT_ZERO;
							jump_type <= JUMP_J;
						end
					end

				end
				OPCD_POP06: begin
					case(POP_insn_type)
					0: begin

						jump_cond_id <= RS_LE_ZERO;

						jump_type <= JUMP_J;


					end
					
					1: begin

						jump_cond_id <= RT_LE_ZERO;

						jump_type <= JUMP_BALC;
						alu_src1 <= insnPC + 4;


					end
					
					2: begin

						jump_cond_id <= RT_GE_ZERO;

						jump_type <= JUMP_BALC;
						alu_src1 <= insnPC + 4;


					end
					
					4: begin

						jump_cond_id <= RS_GEU_RT;

						jump_type <= JUMP_BC;


					end
					

					endcase
				end
				OPCD_POP07: begin
					case(POP_insn_type)
					0: begin

						jump_cond_id <= RS_GT_ZERO;
						jump_type <= JUMP_J;


					end 

					1: begin

						jump_cond_id <= RT_GT_ZERO;
						jump_type <= JUMP_BALC;
						alu_src1 <= insnPC + 4;


					end 

					2: begin

						jump_cond_id <= RT_LT_ZERO;
						jump_type <= JUMP_BALC;
						alu_src1 <= insnPC + 4;


					end 

					4: begin

						jump_cond_id <= RS_LTU_RT;
						jump_type <= JUMP_BC;


					end
					

					endcase
				end
				OPCD_POP10: begin
					case(POP_insn_type)
					1: begin

						jump_cond_id <= RT_EQ_ZERO;
						jump_type <= JUMP_BALC;
						alu_src1 <= insnPC + 4;


					end 
					
					4: begin

						jump_cond_id <= RS_EQ_RT;
						jump_type <= JUMP_BC;


					end
					

					endcase
				end
				OPCD_POP30: begin
					case(POP_insn_type)
					1: begin

						jump_cond_id <= RT_NE_ZERO;

						jump_type <= JUMP_BALC;
						alu_src1 <= insnPC + 4;


					end 

					4: begin

						jump_cond_id <= RS_NE_RT;

						jump_type <= JUMP_BC;


					end
					

					endcase
				end
				OPCD_POP26: begin
					case(POP_insn_type)
					1: begin

						jump_cond_id <= RT_LE_ZERO;

						jump_type <= JUMP_BC;


					end 

					2: begin

						jump_cond_id <= RT_GE_ZERO;

						jump_type <= JUMP_BC;


					end 

					4: begin

						jump_cond_id <= RS_GE_RT;

						jump_type <= JUMP_BC;


					end
					

					endcase
				end
				OPCD_POP27: begin
					case(POP_insn_type)
					1: begin

						jump_cond_id <= RT_GT_ZERO;
						jump_type <= JUMP_BC;


					end 
					
					2: begin

						jump_cond_id <= RT_LT_ZERO;
						jump_type <= JUMP_BC;


					end 
					
					4: begin

						jump_cond_id <= RS_LT_RT;
						jump_type <= JUMP_BC;


					end
					

					endcase
				end
				OPCD_POP66: begin
					case(POP_insn_type)
					0: begin

						jump_cond_id <= RS_EQ_ZERO;
						jump_type <= JUMP_BC_LONG;
					end






					

					endcase
				end
				OPCD_POP76: begin
					case(POP_insn_type)
					0: begin

						jump_cond_id <= RS_NE_ZERO;

						jump_type <= JUMP_BC_LONG;






					end
					

					endcase
				end
				
				OPCD_SLTI: 		decode_itype(rt, 1, 1, `ALU_SLT, `MEM_NOP);
				OPCD_SLTIU:		decode_itype(rt, 1, 1, `ALU_SLTU, `MEM_NOP);
				OPCD_LB:		decode_itype(rt, 1, 1, `ALU_ADDU, `MEM_LB);
				OPCD_LBU:		decode_itype(rt, 1, 1, `ALU_ADDU, `MEM_LBU);
				OPCD_LH:		decode_itype(rt, 1, 1, `ALU_ADDU, `MEM_LH);
				OPCD_LHU:		decode_itype(rt, 1, 1, `ALU_ADDU, `MEM_LHU);
				OPCD_LW:		decode_itype(rt, 1, 1, `ALU_ADDU, `MEM_LW);
				OPCD_SB: begin
					decode_itype(0, 1, 1, `ALU_ADDU, `MEM_SB);
					mem_src2 <= GPR_rt;
					mem_src2_forward <= rt_lock;
					mem_src2_forward_from <= rt_lock_by;

				end
				OPCD_SH: begin
					decode_itype(0, 1, 1, `ALU_ADDU, `MEM_SH);
					mem_src2 <= GPR_rt;
					mem_src2_forward <= rt_lock;
					mem_src2_forward_from <= rt_lock_by;

				end
				OPCD_SW: begin
					decode_itype(0, 1, 1, `ALU_ADDU, `MEM_SW);
					mem_src2 <= GPR_rt;
					mem_src2_forward <= rt_lock;
					mem_src2_forward_from <= rt_lock_by;

				end
				OPCD_AUI: begin
					fetch_rs();

					alu_src2 <= {imm, 16'b0};
					alu_opcode <= `ALU_ADDU;
					write_register(rt);
				end
				
				default:;
				endcase
			end
			
			last_next_insn <= prev_next_insn;
			last_next_insn_enabled <= prev_next_insn_enabled;
			last_drop_next_insn <= drop_next_insn;
		end
	end
	
	always @(*) begin
		prev_next_insn = last_next_insn;
		prev_next_insn_enabled = last_next_insn_enabled;
		drop_next_insn = last_drop_next_insn;
		if(clear_next_insn) begin
			prev_next_insn = 0;
			prev_next_insn_enabled = 0;
			drop_next_insn = 0;
		end
		

		next_insn_write_reg = next_insn_write_reg_pending;
		
		jump_cond[0] = 0;
		jump_cond[1] = 1;
		jump_cond[2] = jump_cond_basic[0];
		jump_cond[3] = !jump_cond_basic[0];
		jump_cond[4] = jump_cond_basic[1];
		jump_cond[5] = !(jump_cond_basic[0] || jump_cond_basic[1]);
		jump_cond[6] = jump_cond_basic[0] || jump_cond_basic[1];
		jump_cond[7] = !jump_cond_basic[1];
		jump_cond[8] = jump_cond_basic[2];
		jump_cond[9] = !(jump_cond_basic[0] || jump_cond_basic[2]);
		jump_cond[10] = jump_cond_basic[0] || jump_cond_basic[2];
		jump_cond[11] = !jump_cond_basic[2];
		jump_cond[12] = jump_cond_basic[3];
		jump_cond[13] = !jump_cond_basic[3];
		jump_cond[14] = jump_cond_basic[4];
		jump_cond[15] = !(jump_cond_basic[3] || jump_cond_basic[4]);
		jump_cond[16] = jump_cond_basic[3] || jump_cond_basic[4];
		jump_cond[17] = !jump_cond_basic[4];
		jump_cond[18] = jump_cond_basic[5];
		jump_cond[19] = !jump_cond_basic[5];
		jump_cond[20] = jump_cond_basic[6];
		jump_cond[21] = !(jump_cond_basic[5] || jump_cond_basic[6]);
		jump_cond[22] = jump_cond_basic[5] || jump_cond_basic[6];
		jump_cond[23] = !jump_cond_basic[6];
			
		if(jump_cond[jump_cond_id]) begin
			case(jump_type)
			JUMP_J: begin
				prev_next_insn = Branch_target;
				prev_next_insn_enabled = 1;
			end
			JUMP_BC: begin
				prev_next_insn = BC_target;
				prev_next_insn_enabled = 1;
				drop_next_insn = 1;
			end
			JUMP_BALC: begin
				prev_next_insn = BC_target;
				prev_next_insn_enabled = 1;
				drop_next_insn = 1;



				next_insn_write_reg = 31;
			end
			JUMP_BC_LONG: begin
				prev_next_insn = BC_long_target;
				prev_next_insn_enabled = 1;
				drop_next_insn = 1;
			end
			JUMP_GPR_RS: begin
				prev_next_insn = GPR_rs;
				prev_next_insn_enabled = 1;
			end
			JUMP_J_LONG: begin
				prev_next_insn = J_target;
				prev_next_insn_enabled = 1;
			end
			JUMP_BC_VERY_LONG: begin
				prev_next_insn = BC_very_long_target;
				prev_next_insn_enabled = 1;
				drop_next_insn = 1;
			end
			default:;
			endcase
		end
	end
endmodule
module pipeline_decode(
	input CLK,
	input RST,
	
	input [31:0] 		prev_insn,
	input [31:0] 		prev_insnPC,
	input 				prev_placeholder_insn,
	output reg 			prev_next_insn_enabled,
	output reg [31:0] 	prev_next_insn,
	output 				prev_busy,
	
	input 								next_busy,
	output reg [31:0] 					next_insnPC,
	output reg [2:0]					next_insn_id,
	output reg [`ALU_OPCODE_WIDTH-1:0]	alu_opcode,
	output reg [31:0]					alu_src1,
	output reg 							alu_src1_forward,
	output reg [2:0]					alu_src1_forward_from,
	output reg [31:0]					alu_src2,
	output reg 							alu_src2_forward,
	output reg [2:0]					alu_src2_forward_from,
	output reg [`MEM_OPCODE_WIDTH-1:0]	mem_opcode,
	output reg [31:0]					mem_src2,
	output reg 							mem_src2_forward,
	output reg [2:0]					mem_src2_forward_from,
	
	input [2:0]		writeback_insn_id,
	input [31:0] 	writeback_data,
	
	input [2:0]		alu_forward_insn_id,
	input [31:0]	alu_forward_data
    );

    
    localparam OPCD_SPECIAL 	= 6'h00;
    localparam OPCD_REGIMM		= 6'h01;
    localparam OPCD_BEQ			= 6'h04;
    localparam OPCD_BNE			= 6'h05;
    localparam OPCD_POP06		= 6'h06;
    localparam OPCD_POP07		= 6'h07;

	localparam OPCD_POP10		= 6'h08;
    localparam OPCD_ADDIU		= 6'h09;
    localparam OPCD_SLTI		= 6'h0A;
    localparam OPCD_SLTIU		= 6'h0B;
    localparam OPCD_ANDI		= 6'h0C;
    localparam OPCD_ORI			= 6'h0D;
    localparam OPCD_XORI		= 6'h0E;
    localparam OPCD_AUI			= 6'h0F;
	localparam OPCD_POP26		= 6'h16;
	localparam OPCD_POP27		= 6'h17;
	localparam OPCD_POP30		= 6'h18;
    localparam OPCD_LB			= 6'h20;
    localparam OPCD_LH			= 6'h21;
    localparam OPCD_LW			= 6'h23;
    localparam OPCD_LBU			= 6'h24;
    localparam OPCD_LHU			= 6'h25;
    localparam OPCD_SB			= 6'h28;
    localparam OPCD_SH			= 6'h29;
	localparam OPCD_SW			= 6'h2B;
    localparam OPCD_LWC1		= 6'h31;
    localparam OPCD_SWC1		= 6'h39;
    localparam OPCD_J			= 6'h02;
    localparam OPCD_JAL			= 6'h03;
    localparam OPCD_BC			= 6'h32;
	localparam OPCD_POP66		= 6'h36;
    localparam OPCD_BALC		= 6'h3A;
	localparam OPCD_POP76		= 6'h3E;
    
    localparam OPFUNC_SLL		= 6'h00;
    localparam OPFUNC_SRL		= 6'h02;
    localparam OPFUNC_SRA		= 6'h03;
    localparam OPFUNC_SLLV		= 6'h04;
    localparam OPFUNC_SRLV		= 6'h06;
    localparam OPFUNC_SRAV		= 6'h07;
    localparam OPFUNC_JR		= 6'h08;
    localparam OPFUNC_JALR		= 6'h09;
    localparam OPFUNC_SYSCALL	= 6'h0C;
    localparam OPFUNC_BREAK		= 6'h0D;
    localparam OPFUNC_SOP30		= 6'h18;
    localparam OPFUNC_SOP31		= 6'h19;
    localparam OPFUNC_SOP32		= 6'h1A;
    localparam OPFUNC_SOP33		= 6'h1B;
    localparam OPFUNC_ADD		= 6'h20;
    localparam OPFUNC_ADDU		= 6'h21;
    localparam OPFUNC_SUB		= 6'h22;
    localparam OPFUNC_SUBU		= 6'h23;
    localparam OPFUNC_AND		= 6'h24;
    localparam OPFUNC_OR		= 6'h25;
    localparam OPFUNC_XOR		= 6'h26;
    localparam OPFUNC_NOR		= 6'h27;
    localparam OPFUNC_SLT		= 6'h2A;
    localparam OPFUNC_SLTU		= 6'h2B;
    
    
    
    reg [31:0] 	insn;
    reg [31:0]	insnPC;
    reg [2:0] 	insn_id;
    reg [4:0]	insn_write_reg[7:0];

	reg			insn_data_overrided[7:0];
	
    reg [31:0] 	reg_file[31:1];
	wire [31:0]	GPR[31:0];
	
    reg 		reg_lock[31:0];
    reg [2:0]	reg_lock_by[31:0];


	reg [4:0]	next_insn_write_reg;

	
	reg [4:0] next_insn_write_reg_pending;

    
	genvar j;
	generate 
		for(j=1; j<32; j=j+1)
			assign GPR[j] = reg_file[j];
	endgenerate
	assign GPR[0] = 0;
    
    
	
    reg busy;
    assign prev_busy = busy || next_busy;
	
	wire writeback_flag =!insn_data_overrided[writeback_insn_id];
	wire alu_forward_flag =!insn_data_overrided[alu_forward_insn_id];
	
	wire [4:0] writeback_reg = insn_write_reg[writeback_insn_id];

	wire [4:0] alu_forward_reg = insn_write_reg[alu_forward_insn_id];

	
    integer i;

	
	task write_register;
		input [4:0] regid;

		begin


				next_insn_write_reg_pending <= regid;

		end
	endtask
	
	reg drop_next_insn;
	
	localparam NEVER 		= 0;
	localparam ALWAYS 		= 1;
	localparam RS_EQ_RT 	= 2;
	localparam RS_NE_RT		= 3;
	localparam RS_GTU_RT	= 4;
	localparam RS_LTU_RT	= 5;
	localparam RS_GEU_RT	= 6;
	localparam RS_LEU_RT	= 7;
	localparam RS_GT_RT		= 8;
	localparam RS_LT_RT		= 9;
	localparam RS_GE_RT		= 10;
	localparam RS_LE_RT		= 11;
	localparam RS_EQ_ZERO	= 12;
	localparam RS_NE_ZERO	= 13;
	localparam RS_GT_ZERO	= 14;
	localparam RS_LT_ZERO	= 15;
	localparam RS_GE_ZERO	= 16;
	localparam RS_LE_ZERO	= 17;
	localparam RT_EQ_ZERO	= 18;
	localparam RT_NE_ZERO	= 19;
	localparam RT_GT_ZERO	= 20;
	localparam RT_LT_ZERO	= 21;
	localparam RT_GE_ZERO	= 22;
	localparam RT_LE_ZERO	= 23;
	
	reg [23:0] jump_cond;
	reg [6:0] jump_cond_basic;
	reg [4:0] 	jump_cond_id;
	
	localparam JUMP_J = 0;
	localparam JUMP_BC = 1;
	localparam JUMP_BALC = 2;
	localparam JUMP_BC_LONG = 4;
	localparam JUMP_J_LONG = 8;
	localparam JUMP_BC_VERY_LONG = 16;
	localparam JUMP_GPR_RS = 32;
	reg	[5:0]	jump_type;
	
	reg [3:0] POP_insn_type;
	reg [31:0] Branch_target;
	reg [31:0] BC_target;
	reg [31:0] BC_long_target;
	reg [31:0] J_target;
	reg [31:0] BC_very_long_target;
	




	reg [31:0] GPR_rs, GPR_rt;
	reg 		rs_lock, rt_lock;
	reg [2:0] rs_lock_by, rt_lock_by;

	

	
	reg [5:0] opcode;
    reg [4:0] rs, rt, rd, sa;
    reg [5:0] opfunc;
    reg [15:0] imm;
    reg [25:0] j_addr;
	
	task fetch_rs;
		begin
			alu_src1 <= GPR_rs;
			alu_src1_forward <= rs_lock;
			alu_src1_forward_from <= rs_lock_by;
		end
	endtask
	
	task fetch_rt;
		begin
			alu_src2 <= GPR_rt;
			alu_src2_forward <= rt_lock;
			alu_src2_forward_from <= rt_lock_by;
		end
	endtask
	
	task decode_rtype;
		input [4:0] dst;
		input use_src1;
		input use_src2;
		input [`ALU_OPCODE_WIDTH-1:0] alu_op;
		input [`MEM_OPCODE_WIDTH-1:0] mem_op;
		
		begin
			if(use_src1) begin
				fetch_rs();
			end
			if(use_src2) begin
				fetch_rt();
			end
			alu_opcode <= alu_op;
			mem_opcode <= mem_op;
			write_register(dst);
		end
	endtask
	
	task decode_itype;
		input [4:0] 	dst;
		input 			use_src1;
		input			sign_extend;

		input [`ALU_OPCODE_WIDTH-1:0] alu_op;
		input [`MEM_OPCODE_WIDTH-1:0] mem_op;
		
		begin
			if(use_src1) begin
				fetch_rs();
			end

			if(sign_extend)
				alu_src2 <= {{16{imm[15]}}, imm};
			else
				alu_src2 <= {16'b0, imm};
			alu_opcode <= alu_op;
			mem_opcode <= mem_op;
			write_register(dst);
		end
	endtask
	
	reg tmp_busy;
	
	reg [31:0] tmp_GPR_rs, tmp_GPR_rt;
	reg clear_next_insn;
	
	reg [31:0] last_next_insn;
	reg last_next_insn_enabled;
	reg last_drop_next_insn;
	
	reg [31:0]	insnPC_add_4;
	
	always @(posedge CLK or posedge RST) begin
		if(RST) begin
			insn <= 0;
			insnPC <= 0;
			reg_lock[0] <= 0;

			reg_lock_by[0] <= 0;
			for(i=1; i<32; i=i+1) begin
				reg_file[i] <= 0;
				reg_lock[i] <= 0;
				reg_lock_by[i] <= 0;

			end
			for(i=0; i<8; i=i+1) begin

				insn_data_overrided[i] <= 1;
				insn_write_reg[i] <= 0;
			end
			


			next_insnPC <= 0;
			alu_opcode <= 0;
			alu_src1 <= 0;
			alu_src2 <= 0;
			alu_src1_forward <= 0;
			alu_src1_forward_from <= 0;
			alu_src2_forward <= 0;
			alu_src2_forward_from <= 0;
			mem_opcode <= 0;
			mem_src2 <= 0;
			mem_src2_forward <= 0;
			mem_src2_forward_from <= 0;
			insn_id <= 0;
			next_insn_id <= 0;




			next_insn_write_reg_pending <= 0;
			


			last_next_insn <= 0;
			last_next_insn_enabled <= 0;
			last_drop_next_insn <= 0;
			
			clear_next_insn <= 1;
		end else begin
			if(writeback_flag) begin
				if(writeback_reg == 0)
					$display("Assertion Failed: Writeback_reg == 0");
				reg_file[writeback_reg] <= writeback_data;
				reg_lock[writeback_reg] <= 0;


			end
			if(alu_forward_flag) begin
				if(alu_forward_reg == 0)
					$display("Assertion Failed: ALU_forward_reg == 0");
					
				reg_file[alu_forward_reg] <= alu_forward_data;
				reg_lock[alu_forward_reg] <= 0;


			end

			if(!prev_busy) begin
				insn	= prev_insn;
				insnPC	= prev_insnPC;
				
				if(next_insn_write_reg != 0) begin
					insn_write_reg[next_insn_id]			<= next_insn_write_reg;

					insn_data_overrided[next_insn_id]		<= 0;
					reg_lock[next_insn_write_reg]			<= 1;

					if(reg_lock[next_insn_write_reg])
						insn_data_overrided[reg_lock_by[next_insn_write_reg]] <= 1;
					reg_lock_by[next_insn_write_reg]		<= next_insn_id;
				end else begin
					insn_write_reg[next_insn_id]	<= 0;
					insn_data_overrided[next_insn_id] <= 1;

				end
			end
			
			opcode 	= insn[31:26];
			rs 		= insn[25:21];
			rt 		= insn[20:16];
			rd 		= insn[15:11];
			sa 		= insn[10:6];
			opfunc 	= insn[5:0];
			imm 	= insn[15:0];
			j_addr	= insn[25:0];
			
			
			
			
			case(1'b1)
			writeback_flag && rs == writeback_reg: begin
				GPR_rs = writeback_data;
				rs_lock = 0;
				rs_lock_by = 0;

			end
			
			alu_forward_flag && rs == alu_forward_reg: begin
				GPR_rs = alu_forward_data;
				rs_lock = 0;
				rs_lock_by = 0;

			end
			
			default: begin
				GPR_rs	= GPR[rs];
				rs_lock = reg_lock[rs];
				rs_lock_by = reg_lock_by[rs];

			end
			endcase
			
			case(1'b1)
			writeback_flag && rt == writeback_reg: begin
				GPR_rt = writeback_data;
				rt_lock = 0;
				rt_lock_by = 0;

			end
			
			alu_forward_flag && rt == alu_forward_reg: begin
				GPR_rt = alu_forward_data;
				rt_lock = 0;
				rt_lock_by = 0;

			end
			
			default: begin
				GPR_rt	= GPR[rt];	
				rt_lock = reg_lock[rt];
				rt_lock_by = reg_lock_by[rt];

			end
			endcase
			
			if(!prev_busy) begin
				if(next_insn_write_reg != 0 && rs == next_insn_write_reg) begin
					rs_lock = 1;

					rs_lock_by = next_insn_id;
				end
				if(next_insn_write_reg != 0 && rt == next_insn_write_reg) begin
					rt_lock = 1;

					rt_lock_by = next_insn_id;
				end
			end
			


			insnPC_add_4 = insnPC + 4;
			Branch_target <= insnPC_add_4 + {{14{imm[15]}}, imm, 2'b00};
			BC_target <= insnPC_add_4 + {{14{imm[15]}}, imm, 2'b00};
			BC_long_target <= insnPC_add_4 + {{9{rt[4]}}, rt, imm, 2'b00};
			J_target <= {insnPC_add_4[31:28], rs, rt, imm, 2'b00};
			BC_very_long_target <= insnPC_add_4 + {{4{rs[4]}}, rs, rt, imm, 2'b00};
			


			jump_cond_basic[0] <= GPR_rs == GPR_rt;

			jump_cond_basic[1] <= GPR_rs > GPR_rt;



			jump_cond_basic[2] <= $signed(GPR_rs) > $signed(GPR_rt);



			jump_cond_basic[3] <= GPR_rs == 0;

			jump_cond_basic[4] <= $signed(GPR_rs) > 0;



			jump_cond_basic[5] <= GPR_rt == 0;

			jump_cond_basic[6] <= $signed(GPR_rt) > 0;



					
			if(rt == 0)
				POP_insn_type = rs_lock ? 4'd8 : 4'd0;
			else if(rs == 0)
				POP_insn_type = rt_lock ? 4'd8 : 4'd1;
			else if(rs == rt)
				POP_insn_type = rt_lock ? 4'd8 : 4'd2;
			else
				POP_insn_type = rs_lock || rt_lock ? 4'd8 : 4'd4;
			
			tmp_busy = 0;
			case(opcode)
			OPCD_SPECIAL: begin
				if(opfunc == OPFUNC_JR || opfunc == OPFUNC_JALR)
					tmp_busy = rs_lock;
			end
			OPCD_REGIMM: 			tmp_busy = rs_lock;
			OPCD_BEQ, OPCD_BNE: 	tmp_busy = rs_lock || rt_lock;
			OPCD_POP06, OPCD_POP07, 
			OPCD_POP10, OPCD_POP26, 
			OPCD_POP27, OPCD_POP30, 
			OPCD_POP66, OPCD_POP76:	tmp_busy = POP_insn_type[3];
			endcase
			
			busy <= tmp_busy;
			
			jump_cond_id <= NEVER;
			jump_type <= JUMP_J;
			
			clear_next_insn <= 0;
			if(!prev_placeholder_insn) begin

				clear_next_insn <= 1;
			end
			if(!next_busy) begin
				if(insn_id == 3'b011)
					insn_id = 0;
				else
					insn_id = insn_id + 1;
			end
			next_insn_write_reg_pending <= 0;

			alu_opcode <= `ALU_NOP;
			alu_src1 <= 0;
			alu_src2 <= 0;
			alu_src1_forward <= 0;
			alu_src2_forward <= 0;
			alu_src1_forward_from <= 0;
			alu_src2_forward_from <= 0;
			mem_opcode <= `MEM_NOP;
			mem_src2 <= 0;
			mem_src2_forward <= 0;
			mem_src2_forward_from <= 0;
			next_insnPC <= insnPC;
			next_insn_id <= busy ? 3'b111 : insn_id;
			
			if(!drop_next_insn && !tmp_busy) begin
				case(opcode)
				OPCD_SPECIAL: begin
					
					case(opfunc)
					OPFUNC_ADD:		decode_rtype(rd, 1, 1, `ALU_ADD, `MEM_NOP);
					OPFUNC_ADDU:	decode_rtype(rd, 1, 1, `ALU_ADDU, `MEM_NOP);
					OPFUNC_SUB:		decode_rtype(rd, 1, 1, `ALU_SUB, `MEM_NOP);
					OPFUNC_SUBU:	decode_rtype(rd, 1, 1, `ALU_SUBU, `MEM_NOP);
					OPFUNC_SLLV:	decode_rtype(rd, 1, 1, `ALU_SLL, `MEM_NOP);
					OPFUNC_SRLV:	decode_rtype(rd, 1, 1, sa == 5'h01 ? `ALU_ROR : `ALU_SRL, `MEM_NOP);
					OPFUNC_SRAV:	decode_rtype(rd, 1, 1, `ALU_SRA, `MEM_NOP);
					OPFUNC_AND:		decode_rtype(rd, 1, 1, `ALU_AND, `MEM_NOP);
					OPFUNC_OR:		decode_rtype(rd, 1, 1, `ALU_OR, `MEM_NOP);
					OPFUNC_NOR:		decode_rtype(rd, 1, 1, `ALU_NOR, `MEM_NOP);
					OPFUNC_XOR:		decode_rtype(rd, 1, 1, `ALU_XOR, `MEM_NOP);
					OPFUNC_SLL: begin
						decode_rtype(rd, 0, 1, `ALU_SLL, `MEM_NOP);
						alu_src1 <= {27'b0, sa};
					end
					OPFUNC_SRL: begin
						decode_rtype(rd, 0, 1, rs == 5'h01 ? `ALU_ROR : `ALU_SRL, `MEM_NOP);
						alu_src1 <= {27'b0, sa};
					end
					OPFUNC_SRA: begin
						decode_rtype(rd, 0, 1, `ALU_SRA, `MEM_NOP);
						alu_src1 <= {27'b0, sa};
					end
					OPFUNC_SOP30: begin
						if(sa == 5'b00010)
							decode_rtype(rd, 1, 1, `ALU_MULTL, `MEM_NOP);
						else if(sa == 5'b00011)
							decode_rtype(rd, 1, 1, `ALU_MULTH, `MEM_NOP);

					end
					OPFUNC_SOP31: begin
						if(sa == 5'b00010)
							decode_rtype(rd, 1, 1, `ALU_MULTLU, `MEM_NOP);
						else if(sa == 5'b00011)
							decode_rtype(rd, 1, 1, `ALU_MULTHU, `MEM_NOP);

					end
					OPFUNC_SOP32: begin
						if(sa == 5'b00010)
							decode_rtype(rd, 1, 1, `ALU_DIV, `MEM_NOP);
						else if(sa == 5'b00011)
							decode_rtype(rd, 1, 1, `ALU_MOD, `MEM_NOP);

					end
					OPFUNC_SOP33: begin
						if(sa == 5'b00010)
							decode_rtype(rd, 1, 1, `ALU_DIVU, `MEM_NOP);
						else if(sa == 5'b00011)
							decode_rtype(rd, 1, 1, `ALU_MODU, `MEM_NOP);
					end
					OPFUNC_JR: begin 
begin
							jump_cond_id <= ALWAYS;
							jump_type <= JUMP_GPR_RS;
						end

					end
					OPFUNC_JALR: begin
begin
							jump_cond_id <= ALWAYS;
							jump_type <= JUMP_GPR_RS;

							alu_src1 <= insnPC + 8;
							write_register(31);
						end
					end
					OPFUNC_SLT: 	decode_rtype(rd, 1, 1, `ALU_SLT, `MEM_NOP);
					OPFUNC_SLTU:	decode_rtype(rd, 1, 1, `ALU_SLTU, `MEM_NOP);
					default:;
					endcase
				end
				

				OPCD_ADDIU:		decode_itype(rt, 1, 1, `ALU_ADDU, `MEM_NOP);
				OPCD_ANDI:		decode_itype(rt, 1, 0, `ALU_AND, `MEM_NOP);
				OPCD_ORI:		decode_itype(rt, 1, 0, `ALU_OR, `MEM_NOP);
				OPCD_XORI:		decode_itype(rt, 1, 0, `ALU_XOR, `MEM_NOP);
				OPCD_BEQ: begin
begin

						jump_cond_id <= RS_EQ_RT;
						jump_type <= JUMP_J;
					end


				end
				OPCD_BNE: begin
begin

						jump_cond_id <= RS_NE_RT;

						jump_type <= JUMP_J;
					end


				end
				OPCD_J: begin


					jump_cond_id <= ALWAYS;
					jump_type <= JUMP_J_LONG;


				end
				OPCD_JAL: begin


					jump_cond_id <= ALWAYS;
					jump_type <= JUMP_J_LONG;


					alu_src1 <= insnPC + 8;
					write_register(31);
				end
				OPCD_BC: begin


					jump_cond_id <= ALWAYS;
					jump_type <= JUMP_BC_VERY_LONG;



				end
				OPCD_BALC: begin


					jump_cond_id <= ALWAYS;
					jump_type <= JUMP_BC_VERY_LONG;



					alu_src1 <= insnPC + 4;
					write_register(31);
				end
				OPCD_REGIMM: begin
					if(rt[0]) begin
						begin
							jump_cond_id <= RS_GE_ZERO;
							jump_type <= JUMP_J;
						end
					end elsebegin
						begin
							jump_cond_id <= RS_LT_ZERO;
							jump_type <= JUMP_J;
						end
					end

				end
				OPCD_POP06: begin
					case(POP_insn_type)
					0: begin

						jump_cond_id <= RS_LE_ZERO;

						jump_type <= JUMP_J;


					end
					
					1: begin

						jump_cond_id <= RT_LE_ZERO;

						jump_type <= JUMP_BALC;
						alu_src1 <= insnPC + 4;


					end
					
					2: begin

						jump_cond_id <= RT_GE_ZERO;

						jump_type <= JUMP_BALC;
						alu_src1 <= insnPC + 4;


					end
					
					4: begin

						jump_cond_id <= RS_GEU_RT;

						jump_type <= JUMP_BC;


					end
					

					endcase
				end
				OPCD_POP07: begin
					case(POP_insn_type)
					0: begin

						jump_cond_id <= RS_GT_ZERO;
						jump_type <= JUMP_J;


					end 

					1: begin

						jump_cond_id <= RT_GT_ZERO;
						jump_type <= JUMP_BALC;
						alu_src1 <= insnPC + 4;


					end 

					2: begin

						jump_cond_id <= RT_LT_ZERO;
						jump_type <= JUMP_BALC;
						alu_src1 <= insnPC + 4;


					end 

					4: begin

						jump_cond_id <= RS_LTU_RT;
						jump_type <= JUMP_BC;


					end
					

					endcase
				end
				OPCD_POP10: begin
					case(POP_insn_type)
					1: begin

						jump_cond_id <= RT_EQ_ZERO;
						jump_type <= JUMP_BALC;
						alu_src1 <= insnPC + 4;


					end 
					
					4: begin

						jump_cond_id <= RS_EQ_RT;
						jump_type <= JUMP_BC;


					end
					

					endcase
				end
				OPCD_POP30: begin
					case(POP_insn_type)
					1: begin

						jump_cond_id <= RT_NE_ZERO;

						jump_type <= JUMP_BALC;
						alu_src1 <= insnPC + 4;


					end 

					4: begin

						jump_cond_id <= RS_NE_RT;

						jump_type <= JUMP_BC;


					end
					

					endcase
				end
				OPCD_POP26: begin
					case(POP_insn_type)
					1: begin

						jump_cond_id <= RT_LE_ZERO;

						jump_type <= JUMP_BC;


					end 

					2: begin

						jump_cond_id <= RT_GE_ZERO;

						jump_type <= JUMP_BC;


					end 

					4: begin

						jump_cond_id <= RS_GE_RT;

						jump_type <= JUMP_BC;


					end
					

					endcase
				end
				OPCD_POP27: begin
					case(POP_insn_type)
					1: begin

						jump_cond_id <= RT_GT_ZERO;
						jump_type <= JUMP_BC;


					end 
					
					2: begin

						jump_cond_id <= RT_LT_ZERO;
						jump_type <= JUMP_BC;


					end 
					
					4: begin

						jump_cond_id <= RS_LT_RT;
						jump_type <= JUMP_BC;


					end
					

					endcase
				end
				OPCD_POP66: begin
					case(POP_insn_type)
					0: begin

						jump_cond_id <= RS_EQ_ZERO;
						jump_type <= JUMP_BC_LONG;
					end






					

					endcase
				end
				OPCD_POP76: begin
					case(POP_insn_type)
					0: begin

						jump_cond_id <= RS_NE_ZERO;

						jump_type <= JUMP_BC_LONG;






					end
					

					endcase
				end
				
				OPCD_SLTI: 		decode_itype(rt, 1, 1, `ALU_SLT, `MEM_NOP);
				OPCD_SLTIU:		decode_itype(rt, 1, 1, `ALU_SLTU, `MEM_NOP);
				OPCD_LB:		decode_itype(rt, 1, 1, `ALU_ADDU, `MEM_LB);
				OPCD_LBU:		decode_itype(rt, 1, 1, `ALU_ADDU, `MEM_LBU);
				OPCD_LH:		decode_itype(rt, 1, 1, `ALU_ADDU, `MEM_LH);
				OPCD_LHU:		decode_itype(rt, 1, 1, `ALU_ADDU, `MEM_LHU);
				OPCD_LW:		decode_itype(rt, 1, 1, `ALU_ADDU, `MEM_LW);
				OPCD_SB: begin
					decode_itype(0, 1, 1, `ALU_ADDU, `MEM_SB);
					mem_src2 <= GPR_rt;
					mem_src2_forward <= rt_lock;
					mem_src2_forward_from <= rt_lock_by;

				end
				OPCD_SH: begin
					decode_itype(0, 1, 1, `ALU_ADDU, `MEM_SH);
					mem_src2 <= GPR_rt;
					mem_src2_forward <= rt_lock;
					mem_src2_forward_from <= rt_lock_by;

				end
				OPCD_SW: begin
					decode_itype(0, 1, 1, `ALU_ADDU, `MEM_SW);
					mem_src2 <= GPR_rt;
					mem_src2_forward <= rt_lock;
					mem_src2_forward_from <= rt_lock_by;

				end
				OPCD_AUI: begin
					fetch_rs();

					alu_src2 <= {imm, 16'b0};
					alu_opcode <= `ALU_ADDU;
					write_register(rt);
				end
				
				default:;
				endcase
			end
			
			last_next_insn <= prev_next_insn;
			last_next_insn_enabled <= prev_next_insn_enabled;
			last_drop_next_insn <= drop_next_insn;
		end
	end
	
	always @(*) begin
		prev_next_insn = last_next_insn;
		prev_next_insn_enabled = last_next_insn_enabled;
		drop_next_insn = last_drop_next_insn;
		if(clear_next_insn) begin
			prev_next_insn = 0;
			prev_next_insn_enabled = 0;
			drop_next_insn = 0;
		end
		

		next_insn_write_reg = next_insn_write_reg_pending;
		
		jump_cond[0] = 0;
		jump_cond[1] = 1;
		jump_cond[2] = jump_cond_basic[0];
		jump_cond[3] = !jump_cond_basic[0];
		jump_cond[4] = jump_cond_basic[1];
		jump_cond[5] = !(jump_cond_basic[0] || jump_cond_basic[1]);
		jump_cond[6] = jump_cond_basic[0] || jump_cond_basic[1];
		jump_cond[7] = !jump_cond_basic[1];
		jump_cond[8] = jump_cond_basic[2];
		jump_cond[9] = !(jump_cond_basic[0] || jump_cond_basic[2]);
		jump_cond[10] = jump_cond_basic[0] || jump_cond_basic[2];
		jump_cond[11] = !jump_cond_basic[2];
		jump_cond[12] = jump_cond_basic[3];
		jump_cond[13] = !jump_cond_basic[3];
		jump_cond[14] = jump_cond_basic[4];
		jump_cond[15] = !(jump_cond_basic[3] || jump_cond_basic[4]);
		jump_cond[16] = jump_cond_basic[3] || jump_cond_basic[4];
		jump_cond[17] = !jump_cond_basic[4];
		jump_cond[18] = jump_cond_basic[5];
		jump_cond[19] = !jump_cond_basic[5];
		jump_cond[20] = jump_cond_basic[6];
		jump_cond[21] = !(jump_cond_basic[5] || jump_cond_basic[6]);
		jump_cond[22] = jump_cond_basic[5] || jump_cond_basic[6];
		jump_cond[23] = !jump_cond_basic[6];
			
		if(jump_cond[jump_cond_id]) begin
			case(jump_type)
			JUMP_J: begin
				prev_next_insn = Branch_target;
				prev_next_insn_enabled = 1;
			end
			JUMP_BC: begin
				prev_next_insn = BC_target;
				prev_next_insn_enabled = 1;
				drop_next_insn = 1;
			end
			JUMP_BALC: begin
				prev_next_insn = BC_target;
				prev_next_insn_enabled = 1;
				drop_next_insn = 1;



				next_insn_write_reg = 31;
			end
			JUMP_BC_LONG: begin
				prev_next_insn = BC_long_target;
				prev_next_insn_enabled = 1;
				drop_next_insn = 1;
			end
			JUMP_GPR_RS: begin
				prev_next_insn = GPR_rs;
				prev_next_insn_enabled = 1;
			end
			JUMP_J_LONG: begin
				prev_next_insn = J_target;
				prev_next_insn_enabled = 1;
			end
			JUMP_BC_VERY_LONG: begin
				prev_next_insn = BC_very_long_target;
				prev_next_insn_enabled = 1;
				drop_next_insn = 1;
			end
			default:;
			endcase
		end
	end
endmodule