data/full_repos/permissive/528252229/id.v
1: b'%Error: data/full_repos/permissive/528252229/id.v:2: Cannot find include file: defines.v\n`include "defines.v" \n         ^~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/528252229,data/full_repos/permissive/528252229/defines.v\n             data/full_repos/permissive/528252229,data/full_repos/permissive/528252229/defines.v.v\n             data/full_repos/permissive/528252229,data/full_repos/permissive/528252229/defines.v.sv\n             defines.v\n             defines.v.v\n             defines.v.sv\n             obj_dir/defines.v\n             obj_dir/defines.v.v\n             obj_dir/defines.v.sv\n%Error: data/full_repos/permissive/528252229/id.v:7: Define or directive not defined: \'`InstAddrBus\'\n input wire[`InstAddrBus]   pc_i,          \n            ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:7: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n input wire[`InstAddrBus]   pc_i,          \n                        ^\n%Error: data/full_repos/permissive/528252229/id.v:8: Define or directive not defined: \'`InstBus\'\n input wire[`InstBus]          inst_i,        \n            ^~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:12: syntax error, unexpected input, expecting IDENTIFIER or do or final\n input wire[`RegBus]     ex_wdata_i,    \n ^~~~~\n%Error: data/full_repos/permissive/528252229/id.v:12: Define or directive not defined: \'`RegBus\'\n input wire[`RegBus]     ex_wdata_i,    \n            ^~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:13: Define or directive not defined: \'`RegAddrBus\'\n input wire[`RegAddrBus]       ex_wd_i,       \n            ^~~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:14: Define or directive not defined: \'`AluOpBus\'\n input wire[`AluOpBus]         ex_aluop_i,    \n            ^~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:18: syntax error, unexpected input, expecting IDENTIFIER or do or final\n input wire[`RegBus]     mem_wdata_i,   \n ^~~~~\n%Error: data/full_repos/permissive/528252229/id.v:18: Define or directive not defined: \'`RegBus\'\n input wire[`RegBus]     mem_wdata_i,   \n            ^~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:19: Define or directive not defined: \'`RegAddrBus\'\n input wire[`RegAddrBus]       mem_wd_i,      \n            ^~~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:22: Define or directive not defined: \'`RegBus\'\n input wire[`RegBus]           reg1_data_i,   \n            ^~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:23: Define or directive not defined: \'`RegBus\'\n input wire[`RegBus]           reg2_data_i,   \n            ^~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:27: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n output reg                    reg2_read_o,   \n ^~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:28: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n output reg[`RegAddrBus]       reg1_addr_o,   \n ^~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:28: Define or directive not defined: \'`RegAddrBus\'\n output reg[`RegAddrBus]       reg1_addr_o,   \n            ^~~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:29: Define or directive not defined: \'`RegAddrBus\'\n output reg[`RegAddrBus]       reg2_addr_o,   \n            ^~~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:32: Define or directive not defined: \'`AluOpBus\'\n output reg[`AluOpBus]         aluop_o,       \n            ^~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:33: Define or directive not defined: \'`AluSelBus\'\n output reg[`AluSelBus]        alusel_o,      \n            ^~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:34: Define or directive not defined: \'`RegBus\'\n output reg[`RegBus]           reg1_o,        \n            ^~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:35: Define or directive not defined: \'`RegBus\'\n output reg[`RegBus]           reg2_o,        \n            ^~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:36: Define or directive not defined: \'`RegAddrBus\'\n output reg[`RegAddrBus]       wd_o,          \n            ^~~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:37: Define or directive not defined: \'`WriteBus\'\n output reg[`WriteBus]         wreg_o,        \n            ^~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:38: Define or directive not defined: \'`RegBus\'\n output reg[`RegBus]     return_addr_o,  \n            ^~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:42: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n output reg[`InstAddrBus]   branch_target_address_o,   \n ^~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:42: Define or directive not defined: \'`InstAddrBus\'\n output reg[`InstAddrBus]   branch_target_address_o,   \n            ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:44: Define or directive not defined: \'`RegBus\'\n output reg[`RegBus]       inst_o,\n            ^~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:45: Define or directive not defined: \'`InstAddrBus\'\n output wire[`InstAddrBus]   pc_o,\n             ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:66: syntax error, unexpected assign\n assign pc_o = pc_i;\n ^~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:67: Define or directive not defined: \'`InstAddrBus\'\n wire [`InstAddrBus] pc_plus_4 = pc_i + 4;\n       ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:67: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n wire [`InstAddrBus] pc_plus_4 = pc_i + 4;\n                   ^\n%Error: data/full_repos/permissive/528252229/id.v:68: Define or directive not defined: \'`InstAddrBus\'\n wire [`InstAddrBus] pc_plus_8 = pc_i + 8;\n       ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:68: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n wire [`InstAddrBus] pc_plus_8 = pc_i + 8;\n                   ^\n%Error: data/full_repos/permissive/528252229/id.v:69: Define or directive not defined: \'`RegBus\'\n wire [`RegBus]  imm_sll2_sign = {imm16_signe[29:0], 2\'b00};\n       ^~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:69: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n wire [`RegBus]  imm_sll2_sign = {imm16_signe[29:0], 2\'b00};\n              ^\n%Error: data/full_repos/permissive/528252229/id.v:76: syntax error, unexpected assign\n    assign stallreq = stallreq_reg1 | stallreq_reg2;\n    ^~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:77: Define or directive not defined: \'`ALU_OP_LW\'\n    assign ex_inst_load = ((ex_aluop_i == `ALU_OP_LW) || \n                                          ^~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:78: Define or directive not defined: \'`ALU_OP_LH\'\n                           (ex_aluop_i == `ALU_OP_LH) || \n                                          ^~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:79: Define or directive not defined: \'`ALU_OP_LB\'\n                           (ex_aluop_i == `ALU_OP_LB)) ? 1\'b1 : 1\'b0;\n                                          ^~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:82: Define or directive not defined: \'`RstDisable\'\n  if(rst == `RstDisable) begin\n            ^~~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:83: Define or directive not defined: \'`ReadDisable\'\n   reg1_read_o <= `ReadDisable;\n                  ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:84: Define or directive not defined: \'`ReadDisable\'\n   reg2_read_o <= `ReadDisable;\n                  ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:85: Define or directive not defined: \'`ZeroRegAddr\'\n   reg1_addr_o <= `ZeroRegAddr;\n                  ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:86: Define or directive not defined: \'`ZeroRegAddr\'\n   reg2_addr_o <= `ZeroRegAddr;\n                  ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:87: Define or directive not defined: \'`ALU_OP_NOP\'\n   aluop_o <= `ALU_OP_NOP;\n              ^~~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:88: Define or directive not defined: \'`ALU_RES_NOP\'\n   alusel_o <= `ALU_RES_NOP;\n               ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:89: Define or directive not defined: \'`ZeroWord\'\n   reg1_o <= `ZeroWord;\n             ^~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:90: Define or directive not defined: \'`ZeroWord\'\n   reg2_o <= `ZeroWord;\n             ^~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:91: Define or directive not defined: \'`ZeroRegAddr\'\n   wd_o <= `ZeroRegAddr;\n           ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/528252229/id.v:92: Define or directive not defined: \'`WriteDisable\'\n   wreg_o <= `WriteDisable;\n             ^~~~~~~~~~~~~\n%Error: Exiting due to too many errors encountered; --error-limit=50\n'
module id(

	input wire					  rst,
	input wire[`InstAddrBus]	  pc_i,
	input wire[`InstBus]          inst_i,


	input wire					  ex_wreg_i,
	input wire[`RegBus]			  ex_wdata_i,
	input wire[`RegAddrBus]       ex_wd_i,
	input wire[`AluOpBus]         ex_aluop_i,
	

	input wire					  mem_wreg_i,
	input wire[`RegBus]			  mem_wdata_i,
	input wire[`RegAddrBus]       mem_wd_i,
	

	input wire[`RegBus]           reg1_data_i,
	input wire[`RegBus]           reg2_data_i,
    

	output reg                    reg1_read_o,
	output reg                    reg2_read_o,
	output reg[`RegAddrBus]       reg1_addr_o,
	output reg[`RegAddrBus]       reg2_addr_o,
	

	output reg[`AluOpBus]         aluop_o,
	output reg[`AluSelBus]        alusel_o,
	output reg[`RegBus]           reg1_o,
	output reg[`RegBus]           reg2_o,
	output reg[`RegAddrBus]       wd_o,
	output reg[`WriteBus]         wreg_o,
	output reg[`RegBus] 		  return_addr_o,


	output reg                    branch_flag_o,
	output reg[`InstAddrBus]	  branch_target_address_o,

	output reg[`RegBus]		  	  inst_o,
	output wire[`InstAddrBus]	  pc_o,
	output wire 			      stallreq
			
);

	wire [5:0] opcode = inst_i[31:26];
	wire [4:0] rs = inst_i[25:21];
	wire [4:0] rt = inst_i[20:16];
	wire [4:0] rd = inst_i[15:11];
	wire [4:0] sa = inst_i[10:6];
	wire [5:0] func = inst_i[5:0];
	wire [15:0] imm16 = inst_i[15:0];
	wire [25:0] imm26 = inst_i[25:0];
	wire [31:0] imm16_signe = {{16{imm16[15]}}, imm16};
	wire [31:0] imm16_unsigne = {16'b0, imm16};
	wire [31:0] imm26_signe = {{6{imm26[25]}}, imm26};
	wire [31:0] imm26_unsigne = {6'b0, imm26};

	reg [1:0]		reg1_conflict_flag;
	reg [1:0]		reg2_conflict_flag;
	
	assign pc_o = pc_i;
	wire [`InstAddrBus] pc_plus_4 = pc_i + 4;
	wire [`InstAddrBus] pc_plus_8 = pc_i + 8;
	wire [`RegBus]		imm_sll2_sign = {imm16_signe[29:0], 2'b00};
    

    reg stallreq_reg1;
    reg stallreq_reg2;
    wire ex_inst_load;
    
    assign stallreq = stallreq_reg1 | stallreq_reg2;
    assign ex_inst_load = ((ex_aluop_i == `ALU_OP_LW) || 
                           (ex_aluop_i == `ALU_OP_LH) || 
                           (ex_aluop_i == `ALU_OP_LB)) ? 1'b1 : 1'b0;
    
	always @(*) begin
		if(rst == `RstDisable) begin
			reg1_read_o <= `ReadDisable;
			reg2_read_o <= `ReadDisable;
			reg1_addr_o <= `ZeroRegAddr;
			reg2_addr_o <= `ZeroRegAddr;
			aluop_o <= `ALU_OP_NOP;
			alusel_o <= `ALU_RES_NOP;
			reg1_o <= `ZeroWord;
			reg2_o <= `ZeroWord;
			wd_o <= `ZeroRegAddr;
			wreg_o <= `WriteDisable;
			inst_o <= `ZeroWord;
			reg1_conflict_flag <= `NoConflict;
			reg2_conflict_flag <= `NoConflict;
		end else begin

			reg1_read_o <= `ReadDisable;
			reg2_read_o <= `ReadDisable;
			reg1_addr_o <= `ZeroRegAddr;
			reg2_addr_o <= `ZeroRegAddr;
			aluop_o <= `ALU_OP_NOP;
			alusel_o <= `ALU_RES_NOP;
			reg1_o <= `ZeroWord;
			reg2_o <= `ZeroWord;
			wd_o <= `ZeroRegAddr;
			wreg_o <= `WriteDisable;
			inst_o <= inst_i;
			case(opcode)
				`INST_ORI :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_ORI;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_unsigne;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_ANDI :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_ANDI;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_unsigne;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_XORI :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_XORI;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_unsigne;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_LUI :	begin




					aluop_o <= `ALU_OP_LUI;
					reg1_o <= `ZeroWord;
					reg2_o <= imm16_unsigne;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_ADDI :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_ADDI;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_signe;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_ADDIU :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_ADDIU;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_signe;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_SLTI :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_SLTI;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_signe;
					wd_o <=rt;
					wreg_o <= `WriteEnable;
				end
				`INST_SLTIU :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_ADDI;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_signe;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_J :	begin




					aluop_o <= `ALU_OP_J;




				end
				`INST_JAL :	begin




					aluop_o <= `ALU_OP_JAL;


					wd_o <= 31;
					wreg_o <= `WriteEnable;
				end
				`INST_BEQ_B :	begin
					if(rs == `RS_B && rt == `RT_B) begin




						aluop_o <= `ALU_OP_B;




					end else begin
						reg1_read_o <= `ReadEnable;
						reg2_read_o <= `ReadEnable;
						reg1_addr_o <= rs;
						reg2_addr_o <= rt;
						aluop_o <= `ALU_OP_BEQ;
                        reg1_o <= reg1_data_i;
                        reg2_o <= reg2_data_i;


					end
				end
				`INST_BGTZ :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_BGTZ;
					reg1_o <= reg1_data_i;
					reg2_o <= reg2_data_i;


				end
				`INST_BLEZ :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_BLEZ;
					reg1_o <= reg1_data_i;
					reg2_o <= reg2_data_i;


				end
				`INST_BNE :	begin
					reg1_read_o <= `ReadEnable;
					reg2_read_o <= `ReadEnable;
					reg1_addr_o <= rs;
					reg2_addr_o <= rt;
					aluop_o <= `ALU_OP_BNE;
					reg1_o <= reg1_data_i;
					reg2_o <= reg2_data_i;


				end
				`INST_BLTZ_BLTZAL_BGEZ_BGEZAL_BAL :	begin
					if(rt == `RT_BLTZ) begin
						reg1_read_o <= `ReadEnable;

						reg1_addr_o <= rs;

						aluop_o <= `ALU_OP_BLTZ;
                        reg1_o <= reg1_data_i;
                        reg2_o <= reg2_data_i;


					end else if(rt == `RT_BLTZAL) begin
						reg1_read_o <= `ReadEnable;

						reg1_addr_o <= rs;

						aluop_o <= `ALU_OP_BLTZAL;
                        reg1_o <= reg1_data_i;
                        reg2_o <= reg2_data_i;
						wd_o <= 31;
						wreg_o <= `WriteEnable;
					end else if (rt == `RT_BGEZ) begin
						reg1_read_o <= `ReadEnable;

						reg1_addr_o <= rs;

						aluop_o <= `ALU_OP_BGEZ;
                        reg1_o <= reg1_data_i;
                        reg2_o <= reg2_data_i;


					end else begin
						if(rs == `RS_BAL) begin




							aluop_o <= `ALU_OP_BAL;


							wd_o <= 31;
							wreg_o <= `WriteEnable;
						end else begin
							reg1_read_o <= `ReadEnable;

							reg1_addr_o <= rs;

							aluop_o <= `ALU_OP_BGEZAL;


							wd_o <= 31;
							wreg_o <= `WriteEnable;
						end
					end
				end
				`INST_LW :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_LW;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_signe;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_SW :	begin
					reg1_read_o <= `ReadEnable;
					reg2_read_o <= `ReadEnable;
					reg1_addr_o <= rs;
					reg2_addr_o <= rt;
					aluop_o <= `ALU_OP_SW;
					reg1_o <= reg1_data_i + imm16_signe;
					reg2_o <= reg2_data_i;


				end
				`INST_LB :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_LB;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_signe;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_SB :	begin
					reg1_read_o <= `ReadEnable;
					reg2_read_o <= `ReadEnable;
					reg1_addr_o <= rs;
					reg2_addr_o <= rt;
					aluop_o <= `ALU_OP_SB;
					reg1_o <= reg1_data_i + imm16_signe;
					reg2_o <= reg2_data_i;


				end
				`INST_LH :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_LH;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_signe;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_SH :	begin
					reg1_read_o <= `ReadEnable;
					reg2_read_o <= `ReadEnable;
					reg1_addr_o <= rs;
					reg2_addr_o <= rt;
					aluop_o <= `ALU_OP_SH;
					reg1_o <= reg1_data_i + imm16_signe;
					reg2_o <= reg2_data_i;


				end
				`INST_SPECIAL : begin
					case (func) 
						`FUNC_AND : begin
						    reg1_read_o <= `ReadEnable;
						    reg2_read_o <= `ReadEnable;
						    reg1_addr_o <= rs;
						    reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_AND;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_NOR : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_NOR;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_OR : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_OR;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_XOR : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_XOR;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SLL : begin

							reg2_read_o <= `ReadEnable;

							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SLL;
							reg1_o <= imm16_unsigne;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SLLV : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SLLV;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SRL : begin

							reg2_read_o <= `ReadEnable;

							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SRL;
							reg1_o <= imm16_unsigne;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SRLV : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SRLV;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SRA : begin

							reg2_read_o <= `ReadEnable;

							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SRA;
							reg1_o <= imm16_unsigne;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SRAV : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SLLV;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_NOP : begin




							aluop_o <= `ALU_OP_SLL;




						end
						`FUNC_SSNOP : begin




							aluop_o <= `ALU_OP_SLL;




						end
						`FUNC_SYNC : begin




							aluop_o <= `ALU_OP_SLL;




						end
						`FUNC_MOVN : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_MOVN;
							if(reg2_data_i != 0) begin
								reg1_o <= reg1_data_i;
								reg2_o <= reg2_data_i;
								wd_o <= rd;
								wreg_o <= `WriteEnable;
							end
							
						end
						`FUNC_MOVZ : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_MOVZ;
							if(reg2_data_i == 0) begin
								reg1_o <= reg1_data_i;
								reg2_o <= reg2_data_i;
								wd_o <= rd;
								wreg_o <= `WriteEnable;
							end
						end
						`FUNC_ADD : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_ADD;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_ADDU : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_ADDU;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SUB : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SUB;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SUBU : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SUBU;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SLT : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SLT;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SLTU : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SLTU;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_JR : begin
							reg1_read_o <= `ReadEnable;

							reg1_addr_o <= rs;

							aluop_o <= `ALU_OP_JR;
							reg1_o <= reg1_data_i;



						end
						`FUNC_JALR : begin
							reg1_read_o <= `ReadEnable;

							reg1_addr_o <= rs;

							aluop_o <= `ALU_OP_JALR;


							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						default : begin

						end
					endcase
				end
				default : begin

				end
			endcase

		end

        stallreq_reg1 <= `NoStop;
        stallreq_reg2 <= `NoStop;
        if(ex_inst_load == 1'b1 && ex_wd_i == reg1_addr_o && reg1_read_o == 1'b1) begin
            stallreq_reg1 <= `Stop;
        end else if(reg1_read_o == `ReadEnable && ex_wreg_i == `WriteEnable && reg1_addr_o == ex_wd_i) begin

            if(opcode == `INST_SW || opcode == `INST_SH || opcode == `INST_SB) begin
                reg1_o <= ex_wdata_i + imm16_signe;
            end else begin
                reg1_o <= ex_wdata_i;
            end
        end
        else if(reg1_read_o == `ReadEnable && mem_wreg_i == `WriteEnable && reg1_addr_o == mem_wd_i) begin

            if(opcode == `INST_SW || opcode == `INST_SH || opcode == `INST_SB) begin
                reg1_o <= mem_wdata_i + imm16_signe;
            end else begin
                reg1_o <= mem_wdata_i;
            end
        end

        if(ex_inst_load == 1'b1 && ex_wd_i == reg2_addr_o && reg2_read_o == 1'b1) begin
            stallreq_reg2 <= `Stop;
        end else if(reg2_read_o == `ReadEnable && ex_wreg_i == `WriteEnable && reg2_addr_o == ex_wd_i) begin

            reg2_o <= ex_wdata_i;
        end
        else if(reg2_read_o == `ReadEnable && mem_wreg_i == `WriteEnable && reg2_addr_o == mem_wd_i) begin

            reg2_o <= mem_wdata_i;
        end
	end


        
        


















    
    always @(*) begin
		if(rst == `RstDisable) begin
			return_addr_o <= `ZeroWord;
			branch_flag_o <= `NotBranch;
			branch_target_address_o <= `InitialPc;
		end
		else begin
			return_addr_o <= `ZeroWord;
			branch_flag_o <= `NotBranch;
			branch_target_address_o <= `InitialPc;
			case(opcode) 
				`INST_J :	begin

					branch_flag_o <= `Branch;
					branch_target_address_o <= {pc_plus_4[31:28], inst_i[25:0], 2'b00};
				end
				`INST_JAL :	begin
					return_addr_o <= pc_plus_8;
					branch_flag_o <= `Branch;
					branch_target_address_o <= {pc_plus_4[31:28], inst_i[25:0], 2'b00};
				end
				`INST_BEQ_B :	begin
					if(rs == `RS_B && rt == `RT_B) begin

						branch_flag_o <= `Branch;
						branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
					end else begin
						if(reg1_o == reg2_o) begin

							branch_flag_o <= `Branch;
							branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
						end
					end
				end
				`INST_BGTZ :	begin
					if(reg1_o > 0) begin
						branch_flag_o <= `Branch;
						branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
					end
				end
				`INST_BLEZ :	begin

					if(reg1_o <= 0) begin
						branch_flag_o <= `Branch;
						branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
					end
				end
				`INST_BNE :	begin
					if(reg1_o != reg2_o) begin

						branch_flag_o <= `Branch;
						branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
					end
				end
				`INST_BLTZ_BLTZAL_BGEZ_BGEZAL_BAL :	begin
					if(rt == `RT_BLTZ) begin
						if(reg1_o[31] == 1'b1) begin

							branch_flag_o <= `Branch;
							branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
						end
					end else if(rt == `RT_BLTZAL) begin
						if(reg1_o[31] == 1'b1) begin
							return_addr_o <= pc_plus_8;
							branch_flag_o <= `Branch;
							branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
						end
					end else if (rt == `RT_BGEZ) begin
						if(reg1_o[31] == 1'b0) begin

							branch_flag_o <= `Branch;
							branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
						end
					end else begin
						if(rs == `RS_BAL) begin
							return_addr_o <= pc_plus_8;
							branch_flag_o <= `Branch;
							branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
						end else begin
							if(reg1_o[31] == 1'b0) begin
								return_addr_o <= pc_plus_8;
								branch_flag_o <= `Branch;
								branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
							end
						end
					end
				end
				`INST_SPECIAL : begin
				    case(func) 
				        `FUNC_JR : begin
				            branch_flag_o <= `Branch;
							branch_target_address_o <= reg1_o;
				        end
				        `FUNC_JALR : begin
				            branch_flag_o <= `Branch;
							branch_target_address_o <= reg1_o;
				        end
				    endcase
				end
				default : begin
				
				end
			endcase
		end
	end

endmodule
module id(

	input wire					  rst,
	input wire[`InstAddrBus]	  pc_i,
	input wire[`InstBus]          inst_i,


	input wire					  ex_wreg_i,
	input wire[`RegBus]			  ex_wdata_i,
	input wire[`RegAddrBus]       ex_wd_i,
	input wire[`AluOpBus]         ex_aluop_i,
	

	input wire					  mem_wreg_i,
	input wire[`RegBus]			  mem_wdata_i,
	input wire[`RegAddrBus]       mem_wd_i,
	

	input wire[`RegBus]           reg1_data_i,
	input wire[`RegBus]           reg2_data_i,
    

	output reg                    reg1_read_o,
	output reg                    reg2_read_o,
	output reg[`RegAddrBus]       reg1_addr_o,
	output reg[`RegAddrBus]       reg2_addr_o,
	

	output reg[`AluOpBus]         aluop_o,
	output reg[`AluSelBus]        alusel_o,
	output reg[`RegBus]           reg1_o,
	output reg[`RegBus]           reg2_o,
	output reg[`RegAddrBus]       wd_o,
	output reg[`WriteBus]         wreg_o,
	output reg[`RegBus] 		  return_addr_o,


	output reg                    branch_flag_o,
	output reg[`InstAddrBus]	  branch_target_address_o,

	output reg[`RegBus]		  	  inst_o,
	output wire[`InstAddrBus]	  pc_o,
	output wire 			      stallreq
			
);


	wire [5:0] opcode = inst_i[31:26];
	wire [4:0] rs = inst_i[25:21];
	wire [4:0] rt = inst_i[20:16];
	wire [4:0] rd = inst_i[15:11];
	wire [4:0] sa = inst_i[10:6];
	wire [5:0] func = inst_i[5:0];
	wire [15:0] imm16 = inst_i[15:0];
	wire [25:0] imm26 = inst_i[25:0];
	wire [31:0] imm16_signe = {{16{imm16[15]}}, imm16};
	wire [31:0] imm16_unsigne = {16'b0, imm16};
	wire [31:0] imm26_signe = {{6{imm26[25]}}, imm26};
	wire [31:0] imm26_unsigne = {6'b0, imm26};

	reg [1:0]		reg1_conflict_flag;
	reg [1:0]		reg2_conflict_flag;
	
	assign pc_o = pc_i;
	wire [`InstAddrBus] pc_plus_4 = pc_i + 4;
	wire [`InstAddrBus] pc_plus_8 = pc_i + 8;
	wire [`RegBus]		imm_sll2_sign = {imm16_signe[29:0], 2'b00};
    

    reg stallreq_reg1;
    reg stallreq_reg2;
    wire ex_inst_load;
    
    assign stallreq = stallreq_reg1 | stallreq_reg2;
    assign ex_inst_load = ((ex_aluop_i == `ALU_OP_LW) || 
                           (ex_aluop_i == `ALU_OP_LH) || 
                           (ex_aluop_i == `ALU_OP_LB)) ? 1'b1 : 1'b0;
    
	always @(*) begin
		if(rst == `RstDisable) begin
			reg1_read_o <= `ReadDisable;
			reg2_read_o <= `ReadDisable;
			reg1_addr_o <= `ZeroRegAddr;
			reg2_addr_o <= `ZeroRegAddr;
			aluop_o <= `ALU_OP_NOP;
			alusel_o <= `ALU_RES_NOP;
			reg1_o <= `ZeroWord;
			reg2_o <= `ZeroWord;
			wd_o <= `ZeroRegAddr;
			wreg_o <= `WriteDisable;
			inst_o <= `ZeroWord;
			reg1_conflict_flag <= `NoConflict;
			reg2_conflict_flag <= `NoConflict;
		end else begin

			reg1_read_o <= `ReadDisable;
			reg2_read_o <= `ReadDisable;
			reg1_addr_o <= `ZeroRegAddr;
			reg2_addr_o <= `ZeroRegAddr;
			aluop_o <= `ALU_OP_NOP;
			alusel_o <= `ALU_RES_NOP;
			reg1_o <= `ZeroWord;
			reg2_o <= `ZeroWord;
			wd_o <= `ZeroRegAddr;
			wreg_o <= `WriteDisable;
			inst_o <= inst_i;
			case(opcode)
				`INST_ORI :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_ORI;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_unsigne;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_ANDI :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_ANDI;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_unsigne;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_XORI :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_XORI;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_unsigne;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_LUI :	begin




					aluop_o <= `ALU_OP_LUI;
					reg1_o <= `ZeroWord;
					reg2_o <= imm16_unsigne;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_ADDI :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_ADDI;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_signe;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_ADDIU :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_ADDIU;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_signe;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_SLTI :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_SLTI;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_signe;
					wd_o <=rt;
					wreg_o <= `WriteEnable;
				end
				`INST_SLTIU :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_ADDI;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_signe;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_J :	begin




					aluop_o <= `ALU_OP_J;




				end
				`INST_JAL :	begin




					aluop_o <= `ALU_OP_JAL;


					wd_o <= 31;
					wreg_o <= `WriteEnable;
				end
				`INST_BEQ_B :	begin
					if(rs == `RS_B && rt == `RT_B) begin




						aluop_o <= `ALU_OP_B;




					end else begin
						reg1_read_o <= `ReadEnable;
						reg2_read_o <= `ReadEnable;
						reg1_addr_o <= rs;
						reg2_addr_o <= rt;
						aluop_o <= `ALU_OP_BEQ;
                        reg1_o <= reg1_data_i;
                        reg2_o <= reg2_data_i;


					end
				end
				`INST_BGTZ :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_BGTZ;
					reg1_o <= reg1_data_i;
					reg2_o <= reg2_data_i;


				end
				`INST_BLEZ :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_BLEZ;
					reg1_o <= reg1_data_i;
					reg2_o <= reg2_data_i;


				end
				`INST_BNE :	begin
					reg1_read_o <= `ReadEnable;
					reg2_read_o <= `ReadEnable;
					reg1_addr_o <= rs;
					reg2_addr_o <= rt;
					aluop_o <= `ALU_OP_BNE;
					reg1_o <= reg1_data_i;
					reg2_o <= reg2_data_i;


				end
				`INST_BLTZ_BLTZAL_BGEZ_BGEZAL_BAL :	begin
					if(rt == `RT_BLTZ) begin
						reg1_read_o <= `ReadEnable;

						reg1_addr_o <= rs;

						aluop_o <= `ALU_OP_BLTZ;
                        reg1_o <= reg1_data_i;
                        reg2_o <= reg2_data_i;


					end else if(rt == `RT_BLTZAL) begin
						reg1_read_o <= `ReadEnable;

						reg1_addr_o <= rs;

						aluop_o <= `ALU_OP_BLTZAL;
                        reg1_o <= reg1_data_i;
                        reg2_o <= reg2_data_i;
						wd_o <= 31;
						wreg_o <= `WriteEnable;
					end else if (rt == `RT_BGEZ) begin
						reg1_read_o <= `ReadEnable;

						reg1_addr_o <= rs;

						aluop_o <= `ALU_OP_BGEZ;
                        reg1_o <= reg1_data_i;
                        reg2_o <= reg2_data_i;


					end else begin
						if(rs == `RS_BAL) begin




							aluop_o <= `ALU_OP_BAL;


							wd_o <= 31;
							wreg_o <= `WriteEnable;
						end else begin
							reg1_read_o <= `ReadEnable;

							reg1_addr_o <= rs;

							aluop_o <= `ALU_OP_BGEZAL;


							wd_o <= 31;
							wreg_o <= `WriteEnable;
						end
					end
				end
				`INST_LW :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_LW;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_signe;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_SW :	begin
					reg1_read_o <= `ReadEnable;
					reg2_read_o <= `ReadEnable;
					reg1_addr_o <= rs;
					reg2_addr_o <= rt;
					aluop_o <= `ALU_OP_SW;
					reg1_o <= reg1_data_i + imm16_signe;
					reg2_o <= reg2_data_i;


				end
				`INST_LB :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_LB;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_signe;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_SB :	begin
					reg1_read_o <= `ReadEnable;
					reg2_read_o <= `ReadEnable;
					reg1_addr_o <= rs;
					reg2_addr_o <= rt;
					aluop_o <= `ALU_OP_SB;
					reg1_o <= reg1_data_i + imm16_signe;
					reg2_o <= reg2_data_i;


				end
				`INST_LH :	begin
					reg1_read_o <= `ReadEnable;

					reg1_addr_o <= rs;

					aluop_o <= `ALU_OP_LH;
					reg1_o <= reg1_data_i;
					reg2_o <= imm16_signe;
					wd_o <= rt;
					wreg_o <= `WriteEnable;
				end
				`INST_SH :	begin
					reg1_read_o <= `ReadEnable;
					reg2_read_o <= `ReadEnable;
					reg1_addr_o <= rs;
					reg2_addr_o <= rt;
					aluop_o <= `ALU_OP_SH;
					reg1_o <= reg1_data_i + imm16_signe;
					reg2_o <= reg2_data_i;


				end
				`INST_SPECIAL : begin
					case (func) 
						`FUNC_AND : begin
						    reg1_read_o <= `ReadEnable;
						    reg2_read_o <= `ReadEnable;
						    reg1_addr_o <= rs;
						    reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_AND;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_NOR : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_NOR;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_OR : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_OR;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_XOR : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_XOR;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SLL : begin

							reg2_read_o <= `ReadEnable;

							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SLL;
							reg1_o <= imm16_unsigne;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SLLV : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SLLV;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SRL : begin

							reg2_read_o <= `ReadEnable;

							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SRL;
							reg1_o <= imm16_unsigne;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SRLV : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SRLV;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SRA : begin

							reg2_read_o <= `ReadEnable;

							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SRA;
							reg1_o <= imm16_unsigne;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SRAV : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SLLV;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_NOP : begin




							aluop_o <= `ALU_OP_SLL;




						end
						`FUNC_SSNOP : begin




							aluop_o <= `ALU_OP_SLL;




						end
						`FUNC_SYNC : begin




							aluop_o <= `ALU_OP_SLL;




						end
						`FUNC_MOVN : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_MOVN;
							if(reg2_data_i != 0) begin
								reg1_o <= reg1_data_i;
								reg2_o <= reg2_data_i;
								wd_o <= rd;
								wreg_o <= `WriteEnable;
							end
							
						end
						`FUNC_MOVZ : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_MOVZ;
							if(reg2_data_i == 0) begin
								reg1_o <= reg1_data_i;
								reg2_o <= reg2_data_i;
								wd_o <= rd;
								wreg_o <= `WriteEnable;
							end
						end
						`FUNC_ADD : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_ADD;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_ADDU : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_ADDU;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SUB : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SUB;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SUBU : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SUBU;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SLT : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SLT;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_SLTU : begin
							reg1_read_o <= `ReadEnable;
							reg2_read_o <= `ReadEnable;
							reg1_addr_o <= rs;
							reg2_addr_o <= rt;
							aluop_o <= `ALU_OP_SLTU;
							reg1_o <= reg1_data_i;
							reg2_o <= reg2_data_i;
							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						`FUNC_JR : begin
							reg1_read_o <= `ReadEnable;

							reg1_addr_o <= rs;

							aluop_o <= `ALU_OP_JR;
							reg1_o <= reg1_data_i;



						end
						`FUNC_JALR : begin
							reg1_read_o <= `ReadEnable;

							reg1_addr_o <= rs;

							aluop_o <= `ALU_OP_JALR;


							wd_o <= rd;
							wreg_o <= `WriteEnable;
						end
						default : begin

						end
					endcase
				end
				default : begin

				end
			endcase

		end

        stallreq_reg1 <= `NoStop;
        stallreq_reg2 <= `NoStop;
        if(ex_inst_load == 1'b1 && ex_wd_i == reg1_addr_o && reg1_read_o == 1'b1) begin
            stallreq_reg1 <= `Stop;
        end else if(reg1_read_o == `ReadEnable && ex_wreg_i == `WriteEnable && reg1_addr_o == ex_wd_i) begin

            if(opcode == `INST_SW || opcode == `INST_SH || opcode == `INST_SB) begin
                reg1_o <= ex_wdata_i + imm16_signe;
            end else begin
                reg1_o <= ex_wdata_i;
            end
        end
        else if(reg1_read_o == `ReadEnable && mem_wreg_i == `WriteEnable && reg1_addr_o == mem_wd_i) begin

            if(opcode == `INST_SW || opcode == `INST_SH || opcode == `INST_SB) begin
                reg1_o <= mem_wdata_i + imm16_signe;
            end else begin
                reg1_o <= mem_wdata_i;
            end
        end

        if(ex_inst_load == 1'b1 && ex_wd_i == reg2_addr_o && reg2_read_o == 1'b1) begin
            stallreq_reg2 <= `Stop;
        end else if(reg2_read_o == `ReadEnable && ex_wreg_i == `WriteEnable && reg2_addr_o == ex_wd_i) begin

            reg2_o <= ex_wdata_i;
        end
        else if(reg2_read_o == `ReadEnable && mem_wreg_i == `WriteEnable && reg2_addr_o == mem_wd_i) begin

            reg2_o <= mem_wdata_i;
        end
	end


        
        


















    
    always @(*) begin
		if(rst == `RstDisable) begin
			return_addr_o <= `ZeroWord;
			branch_flag_o <= `NotBranch;
			branch_target_address_o <= `InitialPc;
		end
		else begin
			return_addr_o <= `ZeroWord;
			branch_flag_o <= `NotBranch;
			branch_target_address_o <= `InitialPc;
			case(opcode) 
				`INST_J :	begin

					branch_flag_o <= `Branch;
					branch_target_address_o <= {pc_plus_4[31:28], inst_i[25:0], 2'b00};
				end
				`INST_JAL :	begin
					return_addr_o <= pc_plus_8;
					branch_flag_o <= `Branch;
					branch_target_address_o <= {pc_plus_4[31:28], inst_i[25:0], 2'b00};
				end
				`INST_BEQ_B :	begin
					if(rs == `RS_B && rt == `RT_B) begin

						branch_flag_o <= `Branch;
						branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
					end else begin
						if(reg1_o == reg2_o) begin

							branch_flag_o <= `Branch;
							branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
						end
					end
				end
				`INST_BGTZ :	begin
					if(reg1_o > 0) begin
						branch_flag_o <= `Branch;
						branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
					end
				end
				`INST_BLEZ :	begin

					if(reg1_o <= 0) begin
						branch_flag_o <= `Branch;
						branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
					end
				end
				`INST_BNE :	begin
					if(reg1_o != reg2_o) begin

						branch_flag_o <= `Branch;
						branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
					end
				end
				`INST_BLTZ_BLTZAL_BGEZ_BGEZAL_BAL :	begin
					if(rt == `RT_BLTZ) begin
						if(reg1_o[31] == 1'b1) begin

							branch_flag_o <= `Branch;
							branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
						end
					end else if(rt == `RT_BLTZAL) begin
						if(reg1_o[31] == 1'b1) begin
							return_addr_o <= pc_plus_8;
							branch_flag_o <= `Branch;
							branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
						end
					end else if (rt == `RT_BGEZ) begin
						if(reg1_o[31] == 1'b0) begin

							branch_flag_o <= `Branch;
							branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
						end
					end else begin
						if(rs == `RS_BAL) begin
							return_addr_o <= pc_plus_8;
							branch_flag_o <= `Branch;
							branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
						end else begin
							if(reg1_o[31] == 1'b0) begin
								return_addr_o <= pc_plus_8;
								branch_flag_o <= `Branch;
								branch_target_address_o <= pc_plus_4 + imm_sll2_sign;
							end
						end
					end
				end
				`INST_SPECIAL : begin
				    case(func) 
				        `FUNC_JR : begin
				            branch_flag_o <= `Branch;
							branch_target_address_o <= reg1_o;
				        end
				        `FUNC_JALR : begin
				            branch_flag_o <= `Branch;
							branch_target_address_o <= reg1_o;
				        end
				    endcase
				end
				default : begin
				
				end
			endcase
		end
	end

endmodule