/****************************************************************************
          ISA definition file

  - The MIPS I ISA has a 6 bit opcode in the upper 6 bits.  
  - The opcode can also specify a "class".  There are two classes:
            1.  SPECIAL - look in lowest 6 bits to find operation
            2.  REGIMM - look in [20:16] to find type of branch

****************************************************************************/

/****** OPCODES - bits 31...26 *******/

`define VAL 31

`define WIDTH 32
`define NUMREGS 32
`define LOG2NUMREGS 5
`define PC_WIDTH 30
`define I_DATAWIDTH 32
`define I_ADDRESSWIDTH 14
`define I_SIZE 16384

`define D_ADDRESSWIDTH 32
`define DM_DATAWIDTH 32
`define DM_BYTEENAWIDTH 4
`define DM_ADDRESSWIDTH 16
`define DM_SIZE 16384



`define     OP_SPECIAL       6'b000000
`define     OP_REGIMM        6'b000001
`define     OP_J             6'b000010
`define     OP_JAL           6'b000011
`define     OP_BEQ           6'b000100
`define     OP_BNE           6'b000101
`define     OP_BLEZ          6'b000110
`define     OP_BGTZ          6'b000111

`define     OP_ADDI          6'b001000
`define     OP_ADDIU         6'b001001
`define     OP_SLTI          6'b001010
`define     OP_SLTIU         6'b001011
`define     OP_ANDI          6'b001100
`define     OP_ORI           6'b001101
`define     OP_XORI          6'b001110
`define     OP_LUI           6'b001111

`define     OP_LB            6'b100000
`define     OP_LH            6'b100001
`define     OP_LWL           6'b100010
`define     OP_LW            6'b100011
`define     OP_LBU           6'b100100
`define     OP_LHU           6'b100101
`define     OP_LWR           6'b100110

`define     OP_SB            6'b101100
`define     OP_SH            6'b101101
`define     OP_SWL           6'b101010
`define     OP_SW            6'b101111
`define     OP_SWR           6'b101110

/****** FUNCTION CLASS - bits 5...0 *******/
`define     FUNC_SLL         6'b000000
`define     FUNC_SRL         6'b000010
`define     FUNC_SRA         6'b000011
`define     FUNC_SLLV        6'b000100
`define     FUNC_SRLV        6'b000110
`define     FUNC_SRAV        6'b000111

`define     FUNC_JR          6'b001110
`define     FUNC_JALR        6'b001111

`define     FUNC_MFHI        6'b110100
`define     FUNC_MTHI        6'b110101
`define     FUNC_MFLO        6'b110110
`define     FUNC_MTLO        6'b110111

`define     FUNC_MULT        6'b111100
`define     FUNC_MULTU       6'b111101
`define     FUNC_DIV         6'b111110
`define     FUNC_DIVU        6'b111111

`define     FUNC_ADD         6'b100000
`define     FUNC_ADDU        6'b100001
`define     FUNC_SUB         6'b100010
`define     FUNC_SUBU        6'b100011
`define     FUNC_AND         6'b100100
`define     FUNC_OR          6'b100101
`define     FUNC_XOR         6'b100110
`define     FUNC_NOR         6'b100111

`define     FUNC_SLT         6'b101010
`define     FUNC_SLTU        6'b101011

/****** REGIMM Class - bits 20...16 *******/
`define     FUNC_BLTZ        1'b0
`define     FUNC_BGEZ        1'b1

`define     OP_COP2        6'b010010
`define     COP2_FUNC_CFC2      6'b111000
`define     COP2_FUNC_CTC2      6'b111010
`define     COP2_FUNC_MTC2      6'b111011

//`define     FUNC_BLTZAL      5'b10000
//`define     FUNC_BGEZAL      5'b10001

/****** 
 * Original REGIMM class, compressed above to save decode logic
`define     FUNC_BLTZ        5'b00000
`define     FUNC_BGEZ        5'b00001
`define     FUNC_BLTZAL      5'b10000
`define     FUNC_BGEZAL      5'b10001
*/


module system ( 
	clk,
	resetn,
	boot_iaddr,
	boot_idata,
	boot_iwe,
	boot_daddr,
	boot_ddata,
	boot_dwe,
	nop7_q
	);

/************************* IO Declarations *********************/
input clk;
input resetn;
input [31:0] boot_iaddr;
input [31:0] boot_idata;
input boot_iwe;
input [31:0] boot_daddr;
input [31:0] boot_ddata;
input boot_dwe;
output [31:0] nop7_q;


/*********************** Signal Declarations *******************/
wire	branch_mispred;
wire	stall_2nd_delayslot;
wire	has_delayslot;
wire	haz_zeroer0_q_pipereg5_q;
wire	haz_zeroer_q_pipereg5_q;
		// Datapath signals declarations
wire	addersub_result_slt;
wire	[ 31 : 0 ]	addersub_result;
wire	[ 31 : 0 ]	reg_file_b_readdataout;
wire	[ 31 : 0 ]	reg_file_a_readdataout;
wire	[ 31 : 0 ]	mul_shift_result;
wire	[ 31 : 0 ]	mul_lo;
wire	[ 31 : 0 ]	mul_hi;
wire	ctrl_mul_stalled;
wire	[ 31 : 0 ]	ifetch_pc_out;
wire	[ 31 : 0 ]	ifetch_instr;
wire	[ 5 : 0 ]	ifetch_opcode;
wire	[ 5 : 0 ]	ifetch_func;
wire	[4 : 0 ]	ifetch_rs;
wire	[ 4 : 0 ]	ifetch_rt;
wire	[ 4 : 0 ]	ifetch_rd;
wire	[ 25 : 0 ]	ifetch_instr_index;
wire	[ 15 : 0 ]	ifetch_offset;
wire	[ 4 : 0 ]	ifetch_sa;
wire	[ 31 : 0 ]	ifetch_next_pc;
wire	[ 31 : 0 ]	data_mem_d_loadresult;
wire	ctrl_data_mem_stalled;
wire	[ 31 : 0 ]	logic_unit_result;
wire	[ 31 : 0 ]	pcadder_result;
wire	[ 31 : 0 ]	signext16_out;
wire	[ 31 : 0 ]	merge26lo_out;
wire	[ 31 : 0 ]	hi_reg_q;
wire	branchresolve_eqz;
wire	branchresolve_gez;
wire	branchresolve_gtz;
wire	branchresolve_lez;
wire	branchresolve_ltz;
wire	branchresolve_ne;
wire	branchresolve_eq;
wire	[ 31 : 0 ]	lo_reg_q;
wire	[ 31 : 0 ]	const8_out;
wire	[ 31 : 0 ]	const9_out;
wire	[ 31 : 0 ]	const_out;
wire	[ 31 : 0 ]	pipereg_q;
wire	[ 25 : 0 ]	pipereg1_q;
wire	[ 4 : 0 ]	pipereg2_q;
wire	[ 31 : 0 ]	pipereg5_q;
wire	[ 31 : 0 ]	pipereg14_q;
wire	[ 31 : 0 ]	pipereg3_q;
wire	[ 31 : 0 ]	nop7_q;
wire	[ 31 : 0 ]	nop_q;
wire	[ 31 : 0 ]	nop10_q;
wire	[ 31 : 0 ]	nop6_q;
wire	[ 31 : 0 ]	zeroer_q;
wire	[ 31 : 0 ]	zeroer0_q;
wire	[ 31 : 0 ]	zeroer4_q;
wire	[ 31 : 0 ]	fakedelay_q;
wire	[ 31 : 0 ]	mux3to1_ifetch_load_data_out;
wire	[ 31 : 0 ]	mux2to1_mul_opA_out;
wire	mux6to1_ifetch_load_out;
wire	[ 4 : 0 ]	mux3to1_mul_sa_out;
wire	[ 31 : 0 ]	mux2to1_addersub_opA_out;
wire	[ 31 : 0 ]	mux7to1_nop10_d_out;
wire	[ 31 : 0 ]	mux2to1_pipereg_d_out;
wire	[ 31 : 0 ]	mux3to1_nop6_d_out;
wire	[ 31 : 0 ]	mux3to1_zeroer4_d_out;
wire	[ 5 : 0 ]	pipereg11_q;
wire	[ 31 : 0 ]	mux2to1_nop_d_out;
wire	pipereg16_q;
wire	pipereg15_q;
wire	[ 31 : 0 ]	mux2to1_nop7_d_out;
wire	[ 5 : 0 ]	pipereg12_q;
wire	[ 4 : 0 ]	pipereg13_q;
/***************** Control Signals ***************/
		//Decoded Opcode signal declarations
reg	ctrl_mux2to1_pipereg_d_sel;
reg	[ 2 : 0 ]	ctrl_mux7to1_nop10_d_sel;
reg	ctrl_mux2to1_addersub_opA_sel;
reg	[ 2 : 0 ]	ctrl_mux6to1_ifetch_load_sel;
reg	[ 1 : 0 ]	ctrl_mux3to1_nop6_d_sel;
reg	ctrl_mux2to1_mul_opA_sel;
reg	[ 1 : 0 ]	ctrl_mux3to1_mul_sa_sel;
reg	[ 1 : 0 ]	ctrl_mux3to1_ifetch_load_data_sel;
reg	[ 1 : 0 ]	ctrl_mux3to1_zeroer4_d_sel;
reg	ctrl_zeroer4_en;
reg	ctrl_zeroer0_en;
reg	ctrl_zeroer_en;
reg	[ 3 : 0 ]	ctrl_data_mem_op;
reg	[ 2 : 0 ]	ctrl_addersub_op;
reg	ctrl_ifetch_op;
reg	[ 2 : 0 ]	ctrl_mul_op;
reg	[ 1 : 0 ]	ctrl_logic_unit_op;
		//Enable signal declarations
reg	ctrl_hi_reg_en;
reg	ctrl_lo_reg_en;
reg	ctrl_branchresolve_en;
reg	ctrl_reg_file_c_we;
reg	ctrl_reg_file_b_en;
reg	ctrl_reg_file_a_en;
reg	ctrl_data_mem_en;
reg	ctrl_ifetch_we;
reg	ctrl_ifetch_en;
reg	ctrl_mul_start;
		//Other Signals
wire	squash_stage2;
wire	stall_out_stage2;
wire	squash_stage1;
wire	stall_out_stage1;
wire	ctrl_pipereg16_squashn;
wire	ctrl_pipereg15_squashn;
wire	ctrl_pipereg14_squashn;
wire	ctrl_pipereg_squashn;
wire	ctrl_pipereg5_squashn;
wire	ctrl_pipereg2_squashn;
wire	ctrl_pipereg3_squashn;
wire	ctrl_pipereg1_squashn;
wire	ctrl_pipereg11_squashn;
wire	ctrl_pipereg12_squashn;
wire	ctrl_pipereg13_squashn;
wire	ctrl_pipereg16_resetn;
wire	ctrl_pipereg15_resetn;
wire	ctrl_pipereg14_resetn;
wire	ctrl_pipereg_resetn;
wire	ctrl_pipereg5_resetn;
wire	ctrl_pipereg2_resetn;
wire	ctrl_pipereg3_resetn;
wire	ctrl_pipereg1_resetn;
wire	ctrl_pipereg11_resetn;
wire	ctrl_pipereg12_resetn;
wire	ctrl_pipereg13_resetn;
wire	ctrl_pipereg16_en;
wire	ctrl_pipereg15_en;
wire	ctrl_pipereg14_en;
wire	ctrl_pipereg_en;
wire	ctrl_pipereg5_en;
wire	ctrl_pipereg2_en;
wire	ctrl_pipereg3_en;
wire	ctrl_pipereg1_en;
wire	ctrl_pipereg11_en;
wire	ctrl_pipereg12_en;
wire	ctrl_pipereg13_en;
wire crtl_ifetch_squashn;

/****************************** Control **************************/
		//Decode Logic for Opcode and Multiplex Select signals
always@(posedge clk)
begin
		// Initialize control opcodes to zero
	
	case (ifetch_opcode)
		`OP_ADDI:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_mux3to1_zeroer4_d_sel <= 2'b10;
			ctrl_zeroer4_en <= 1'b1;
			ctrl_zeroer_en <= 1'b1;
		end
		`OP_ADDIU:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_mux3to1_zeroer4_d_sel <= 2'b10;
			ctrl_zeroer4_en <= 1'b1;
			ctrl_zeroer_en <= 1'b1;
		end
		`OP_ANDI:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_mux3to1_zeroer4_d_sel <= 2'b10;
			ctrl_zeroer4_en <= 1'b1;
			ctrl_zeroer_en <= 1'b1;
		end
		`OP_BEQ:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_zeroer0_en <= 1'b1;
			ctrl_zeroer_en <= 1'b1;
		end
		`OP_BGTZ:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_zeroer_en <= 1'b1;
		end
		`OP_BLEZ:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_zeroer_en <= 1'b1;
		end
		`OP_BNE:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_zeroer0_en <= 1'b1;
			ctrl_zeroer_en <= 1'b1;
		end
		`OP_JAL:
		begin
			ctrl_mux3to1_zeroer4_d_sel <= 2'b10;
			ctrl_zeroer4_en <= 1'b1;
		end
		`OP_LB:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_mux3to1_zeroer4_d_sel <= 2'b10;
			ctrl_zeroer4_en <= 1'b1;
			ctrl_zeroer_en <= 1'b1;
		end
		`OP_LBU:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_mux3to1_zeroer4_d_sel <= 2'b10;
			ctrl_zeroer4_en <= 1'b1;
			ctrl_zeroer_en <= 1'b1;
		end
		`OP_LH:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_mux3to1_zeroer4_d_sel <= 2'b10;
			ctrl_zeroer4_en <= 1'b1;
			ctrl_zeroer_en <= 1'b1;
		end
		`OP_LHU:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_mux3to1_zeroer4_d_sel <= 2'b10;
			ctrl_zeroer4_en <= 1'b1;
			ctrl_zeroer_en <= 1'b1;
		end
		`OP_LUI:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_mux3to1_zeroer4_d_sel <= 2'b10;
			ctrl_zeroer4_en <= 1'b1;
		end
		`OP_LW:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_mux3to1_zeroer4_d_sel <= 2'b10;
			ctrl_zeroer4_en <= 1'b1;
			ctrl_zeroer_en <= 1'b1;
		end
		`OP_ORI:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_mux3to1_zeroer4_d_sel <= 2'b10;
			ctrl_zeroer4_en <= 1'b1;
			ctrl_zeroer_en <= 1'b1;
		end
		`OP_REGIMM:
		case (ifetch_rt[0])
			`FUNC_BGEZ:
			begin
				ctrl_mux2to1_pipereg_d_sel <= 1'b1;
				ctrl_zeroer_en <= 1'b1;
			end
			`FUNC_BLTZ:
			begin
				ctrl_mux2to1_pipereg_d_sel <= 1'b1;
				ctrl_zeroer_en <= 1'b1;
			end
		endcase
		`OP_SB:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_zeroer0_en <= 1'b1;
			ctrl_zeroer_en <= 1'b1;
		end
		`OP_SH:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_zeroer0_en <= 1'b1;
			ctrl_zeroer_en <= 1'b1;
		end
		`OP_SLTI:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_mux3to1_zeroer4_d_sel <= 2'b10;
			ctrl_zeroer4_en <= 1'b1;
			ctrl_zeroer_en <= 1'b1;
		end
		`OP_SLTIU:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_mux3to1_zeroer4_d_sel <= 2'b10;
			ctrl_zeroer4_en <= 1'b1;
			ctrl_zeroer_en <= 1'b1;
		end
		`OP_SPECIAL:
		case (ifetch_func)
			`FUNC_ADD:
			begin
				ctrl_mux3to1_zeroer4_d_sel <= 2'b01;
				ctrl_zeroer4_en <= 1'b1;
				ctrl_zeroer0_en <= 1'b1;
				ctrl_zeroer_en <= 1'b1;
			end
			`FUNC_ADDU:
			begin
				ctrl_mux3to1_zeroer4_d_sel <= 2'b01;
				ctrl_zeroer4_en <= 1'b1;
				ctrl_zeroer0_en <= 1'b1;
				ctrl_zeroer_en <= 1'b1;
			end
			`FUNC_AND:
			begin
				ctrl_mux3to1_zeroer4_d_sel <= 2'b01;
				ctrl_zeroer4_en <= 1'b1;
				ctrl_zeroer0_en <= 1'b1;
				ctrl_zeroer_en <= 1'b1;
			end
			`FUNC_JALR:
			begin
				ctrl_mux3to1_zeroer4_d_sel <= 2'b01;
				ctrl_zeroer4_en <= 1'b1;
				ctrl_zeroer_en <= 1'b1;
			end
			`FUNC_JR:
				ctrl_zeroer_en <= 1'b1;
			`FUNC_MFHI:
			begin
				ctrl_mux3to1_zeroer4_d_sel <= 2'b01;
				ctrl_zeroer4_en <= 1'b1;
			end
			`FUNC_MFLO:
			begin
				ctrl_mux3to1_zeroer4_d_sel <= 2'b01;
				ctrl_zeroer4_en <= 1'b1;
			end
			`FUNC_MULT:
			begin
				ctrl_zeroer0_en <= 1'b1;
				ctrl_zeroer_en <= 1'b1;
			end
			`FUNC_MULTU:
			begin
				ctrl_zeroer0_en <= 1'b1;
				ctrl_zeroer_en <= 1'b1;
			end
			`FUNC_NOR:
			begin
				ctrl_mux3to1_zeroer4_d_sel <= 2'b01;
				ctrl_zeroer4_en <= 1'b1;
				ctrl_zeroer0_en <= 1'b1;
				ctrl_zeroer_en <= 1'b1;
			end
			`FUNC_OR:
			begin
				ctrl_mux3to1_zeroer4_d_sel <= 2'b01;
				ctrl_zeroer4_en <= 1'b1;
				ctrl_zeroer0_en <= 1'b1;
				ctrl_zeroer_en <= 1'b1;
			end
			`FUNC_SLL:
			begin
				ctrl_mux3to1_zeroer4_d_sel <= 2'b01;
				ctrl_zeroer4_en <= 1'b1;
				ctrl_zeroer0_en <= 1'b1;
			end
			`FUNC_SLLV:
			begin
				ctrl_mux3to1_zeroer4_d_sel <= 2'b01;
				ctrl_zeroer4_en <= 1'b1;
				ctrl_zeroer0_en <= 1'b1;
				ctrl_zeroer_en <= 1'b1;
			end
			`FUNC_SLT:
			begin
				ctrl_mux3to1_zeroer4_d_sel <= 2'b01;
				ctrl_zeroer4_en <= 1'b1;
				ctrl_zeroer0_en <= 1'b1;
				ctrl_zeroer_en <= 1'b1;
			end
			`FUNC_SLTU:
			begin
				ctrl_mux3to1_zeroer4_d_sel <= 2'b01;
				ctrl_zeroer4_en <= 1'b1;
				ctrl_zeroer0_en <= 1'b1;
				ctrl_zeroer_en <= 1'b1;
			end
			`FUNC_SRA:
			begin
				ctrl_mux3to1_zeroer4_d_sel <= 2'b01;
				ctrl_zeroer4_en <= 1'b1;
				ctrl_zeroer0_en <= 1'b1;
			end
			`FUNC_SRAV:
			begin
				ctrl_mux3to1_zeroer4_d_sel <= 2'b01;
				ctrl_zeroer4_en <= 1'b1;
				ctrl_zeroer0_en <= 1'b1;
				ctrl_zeroer_en <= 1'b1;
			end
			`FUNC_SRL:
			begin
				ctrl_mux3to1_zeroer4_d_sel <= 2'b01;
				ctrl_zeroer4_en <= 1'b1;
				ctrl_zeroer0_en <= 1'b1;
			end
			`FUNC_SRLV:
			begin
				ctrl_mux3to1_zeroer4_d_sel <= 2'b01;
				ctrl_zeroer4_en <= 1'b1;
				ctrl_zeroer0_en <= 1'b1;
				ctrl_zeroer_en <= 1'b1;
			end
			`FUNC_SUB:
			begin
				ctrl_mux3to1_zeroer4_d_sel <= 2'b01;
				ctrl_zeroer4_en <= 1'b1;
				ctrl_zeroer0_en <= 1'b1;
				ctrl_zeroer_en <= 1'b1;
			end
			`FUNC_SUBU:
			begin
				ctrl_mux3to1_zeroer4_d_sel <= 2'b01;
				ctrl_zeroer4_en <= 1'b1;
				ctrl_zeroer0_en <= 1'b1;
				ctrl_zeroer_en <= 1'b1;
			end
			`FUNC_XOR:
			begin
				ctrl_mux3to1_zeroer4_d_sel <= 2'b01;
				ctrl_zeroer4_en <= 1'b1;
				ctrl_zeroer0_en <= 1'b1;
				ctrl_zeroer_en <= 1'b1;
			end
		endcase
		`OP_SW:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_zeroer0_en <= 1'b1;
			ctrl_zeroer_en <= 1'b1;
		end
		`OP_XORI:
		begin
			ctrl_mux2to1_pipereg_d_sel <= 1'b1;
			ctrl_mux3to1_zeroer4_d_sel <= 2'b10;
			ctrl_zeroer4_en <= 1'b1;
			ctrl_zeroer_en <= 1'b1;
		end
	endcase

		//Logic for enable signals in Pipe Stage 1
	ctrl_reg_file_b_en <= ~stall_out_stage2;
	ctrl_reg_file_a_en <= ~stall_out_stage2;
	ctrl_ifetch_en <= ~stall_out_stage2;

		//Decode Logic for Opcode and Multiplex Select signals


		// Initialize control opcodes to zero

	
	case (pipereg11_q)
		`OP_ADDI:
		begin
			ctrl_mux7to1_nop10_d_sel <= 3'b110;
			ctrl_mux2to1_addersub_opA_sel <= 1'b0;
			ctrl_mux3to1_nop6_d_sel <= 2'b10;
			ctrl_addersub_op <= 3'b011;
		end
		`OP_ADDIU:
		begin
			ctrl_mux7to1_nop10_d_sel <= 3'b110;
			ctrl_mux2to1_addersub_opA_sel <= 1'b0;
			ctrl_mux3to1_nop6_d_sel <= 2'b10;
			ctrl_addersub_op <= 3'b001;
		end
		`OP_ANDI:
		begin
			ctrl_mux7to1_nop10_d_sel <= 3'b100;
			ctrl_mux3to1_nop6_d_sel <= 2'b10;
			ctrl_logic_unit_op <= 2'b00;
		end
		`OP_BEQ:
		begin
			ctrl_mux6to1_ifetch_load_sel <= 3'b101;
			ctrl_mux3to1_ifetch_load_data_sel<= 2'b10;
			ctrl_ifetch_op <= 1'b0;
		end
		`OP_BGTZ:
		begin
			ctrl_mux6to1_ifetch_load_sel <= 3'b000;
			ctrl_mux3to1_ifetch_load_data_sel<= 2'b10;
			ctrl_ifetch_op <= 1'b0;
		end
		`OP_BLEZ:
		begin
			ctrl_mux6to1_ifetch_load_sel <= 3'b011;
			ctrl_mux3to1_ifetch_load_data_sel<= 2'b10;
			ctrl_ifetch_op <= 1'b0;
		end
		`OP_BNE:
		begin
			ctrl_mux6to1_ifetch_load_sel <= 3'b100;
			ctrl_mux3to1_ifetch_load_data_sel<= 2'b10;
			ctrl_ifetch_op <= 1'b0;
		end
		`OP_J:
		begin
			ctrl_mux3to1_ifetch_load_data_sel<= 2'b01;
			ctrl_ifetch_op <= 1'b1;
		end
		`OP_JAL:
		begin
			ctrl_mux7to1_nop10_d_sel <= 3'b110;
			ctrl_mux2to1_addersub_opA_sel <= 1'b1;
			ctrl_mux3to1_ifetch_load_data_sel<= 2'b01;
			ctrl_addersub_op <= 3'b001;
			ctrl_ifetch_op <= 1'b1;
		end
		`OP_LB:
		begin
			ctrl_mux7to1_nop10_d_sel <= 3'b010;
			ctrl_mux2to1_addersub_opA_sel <= 1'b0;
			ctrl_mux3to1_nop6_d_sel <= 2'b10;
			ctrl_data_mem_op <= 4'b0111;
			ctrl_addersub_op <= 3'b011;
		end
		`OP_LBU:
		begin
			ctrl_mux7to1_nop10_d_sel <= 3'b010;
			ctrl_mux2to1_addersub_opA_sel <= 1'b0;
			ctrl_mux3to1_nop6_d_sel <= 2'b10;
			ctrl_data_mem_op <= 4'b0011;
			ctrl_addersub_op <= 3'b011;
		end
		`OP_LH:
		begin
			ctrl_mux7to1_nop10_d_sel <= 3'b010;
			ctrl_mux2to1_addersub_opA_sel <= 1'b0;
			ctrl_mux3to1_nop6_d_sel <= 2'b10;
			ctrl_data_mem_op <= 4'b0101;
			ctrl_addersub_op <= 3'b011;
		end
		`OP_LHU:
		begin
			ctrl_mux7to1_nop10_d_sel <= 3'b010;
			ctrl_mux2to1_addersub_opA_sel <= 1'b0;
			ctrl_mux3to1_nop6_d_sel <= 2'b10;
			ctrl_data_mem_op <= 4'b0001;
			ctrl_addersub_op <= 3'b011;
		end
		`OP_LUI:
		begin
			ctrl_mux7to1_nop10_d_sel <= 3'b011;
			ctrl_mux3to1_nop6_d_sel <= 2'b10;
			ctrl_mux2to1_mul_opA_sel <= 1'b0;
			ctrl_mux3to1_mul_sa_sel <= 2'b01;
			ctrl_mul_op <= 3'b000;
		end
		`OP_LW:
		begin
			ctrl_mux7to1_nop10_d_sel <= 3'b010;
			ctrl_mux2to1_addersub_opA_sel <= 1'b0;
			ctrl_mux3to1_nop6_d_sel <= 2'b10;
			ctrl_data_mem_op <= 4'b0000;
			ctrl_addersub_op <= 3'b011;
		end
		`OP_ORI:
		begin
			ctrl_mux7to1_nop10_d_sel <= 3'b100;
			ctrl_mux3to1_nop6_d_sel <= 2'b10;
			ctrl_logic_unit_op <= 2'b01;
		end
		`OP_REGIMM:
		case (pipereg13_q[0])
			`FUNC_BGEZ:
			begin
				ctrl_mux6to1_ifetch_load_sel <= 3'b001;
				ctrl_mux3to1_ifetch_load_data_sel<= 2'b10;
				ctrl_ifetch_op <= 1'b0;
			end
			`FUNC_BLTZ:
			begin
				ctrl_mux6to1_ifetch_load_sel <= 3'b010;
				ctrl_mux3to1_ifetch_load_data_sel<= 2'b10;
				ctrl_ifetch_op <= 1'b0;
			end
		endcase
		`OP_SB:
		begin
			ctrl_mux2to1_addersub_opA_sel <= 1'b0;
			ctrl_mux3to1_nop6_d_sel <= 2'b10;
			ctrl_data_mem_op <= 4'b0011;
			ctrl_addersub_op <= 3'b011;
		end
		`OP_SH:
		begin
			ctrl_mux2to1_addersub_opA_sel <= 1'b0;
			ctrl_mux3to1_nop6_d_sel <= 2'b10;
			ctrl_data_mem_op <= 4'b1001;
			ctrl_addersub_op <= 3'b011;
		end
		`OP_SLTI:
		begin
			ctrl_mux7to1_nop10_d_sel <= 3'b101;
			ctrl_mux2to1_addersub_opA_sel <= 1'b0;
			ctrl_mux3to1_nop6_d_sel <= 2'b10;
			ctrl_addersub_op <= 3'b101;
		end
		`OP_SLTIU:
		begin
			ctrl_mux7to1_nop10_d_sel <= 3'b101;
			ctrl_mux2to1_addersub_opA_sel <= 1'b0;
			ctrl_mux3to1_nop6_d_sel <= 2'b10;
			ctrl_addersub_op <= 3'b100;
		end
		`OP_SPECIAL:
		case (pipereg12_q)
			`FUNC_ADD:
			begin
				ctrl_mux7to1_nop10_d_sel <= 3'b110;
				ctrl_mux2to1_addersub_opA_sel <= 1'b0;
				ctrl_mux3to1_nop6_d_sel <= 2'b01;
				ctrl_addersub_op <= 3'b011;
			end
			`FUNC_ADDU:
			begin
				ctrl_mux7to1_nop10_d_sel <= 3'b110;
				ctrl_mux2to1_addersub_opA_sel <= 1'b0;
				ctrl_mux3to1_nop6_d_sel <= 2'b01;
				ctrl_addersub_op <= 3'b001;
			end
			`FUNC_AND:
			begin
				ctrl_mux7to1_nop10_d_sel <= 3'b100;
				ctrl_mux3to1_nop6_d_sel <= 2'b01;
				ctrl_logic_unit_op <= 2'b00;
			end
			`FUNC_JALR:
			begin
				ctrl_mux7to1_nop10_d_sel <= 3'b110;
				ctrl_mux2to1_addersub_opA_sel <= 1'b1;
				ctrl_mux3to1_ifetch_load_data_sel<= 2'b00;
				ctrl_addersub_op <= 3'b001;
				ctrl_ifetch_op <= 1'b1;
			end
			`FUNC_JR:
			begin
				ctrl_mux3to1_ifetch_load_data_sel<= 2'b00;
				ctrl_ifetch_op <= 1'b1;
			end
			`FUNC_MFHI:
				ctrl_mux7to1_nop10_d_sel <= 3'b001;
			`FUNC_MFLO:
				ctrl_mux7to1_nop10_d_sel <= 3'b000;
			`FUNC_MULT:
			begin
				ctrl_mux2to1_mul_opA_sel <= 1'b1;
				ctrl_mul_op <= 3'b110;
			end
			`FUNC_MULTU:
			begin
				ctrl_mux2to1_mul_opA_sel <= 1'b1;
				ctrl_mul_op <= 3'b100;
			end
			`FUNC_NOR:
			begin
				ctrl_mux7to1_nop10_d_sel <= 3'b100;
				ctrl_mux3to1_nop6_d_sel <= 2'b01;
				ctrl_logic_unit_op <= 2'b11;
			end
			`FUNC_OR:
			begin
				ctrl_mux7to1_nop10_d_sel <= 3'b100;
				ctrl_mux3to1_nop6_d_sel <= 2'b01;
				ctrl_logic_unit_op <= 2'b01;
			end
			`FUNC_SLL:
			begin
				ctrl_mux7to1_nop10_d_sel <= 3'b011;
				ctrl_mux3to1_nop6_d_sel <= 2'b01;
				ctrl_mux2to1_mul_opA_sel <= 1'b0;
				ctrl_mux3to1_mul_sa_sel <= 2'b00;
				ctrl_mul_op <= 3'b000;
			end
			`FUNC_SLLV:
			begin
				ctrl_mux7to1_nop10_d_sel <= 3'b011;
				ctrl_mux3to1_nop6_d_sel <= 2'b01;
				ctrl_mux2to1_mul_opA_sel <= 1'b0;
				ctrl_mux3to1_mul_sa_sel <= 2'b10;
				ctrl_mul_op <= 3'b000;
			end
			`FUNC_SLT:
			begin
				ctrl_mux7to1_nop10_d_sel <= 3'b101;
				ctrl_mux2to1_addersub_opA_sel <= 1'b0;
				ctrl_mux3to1_nop6_d_sel <= 2'b01;
				ctrl_addersub_op <= 3'b110;
			end
			`FUNC_SLTU:
			begin
				ctrl_mux7to1_nop10_d_sel <= 3'b101;
				ctrl_mux2to1_addersub_opA_sel <= 1'b0;
				ctrl_mux3to1_nop6_d_sel <= 2'b01;
				ctrl_addersub_op <= 3'b100;
			end
			`FUNC_SRA:
			begin
				ctrl_mux7to1_nop10_d_sel <= 3'b011;
				ctrl_mux3to1_nop6_d_sel <= 2'b01;
				ctrl_mux2to1_mul_opA_sel <= 1'b0;
				ctrl_mux3to1_mul_sa_sel <= 2'b00;
				ctrl_mul_op <= 3'b011;
			end
			`FUNC_SRAV:
			begin
				ctrl_mux7to1_nop10_d_sel <= 3'b011;
				ctrl_mux3to1_nop6_d_sel <= 2'b01;
				ctrl_mux2to1_mul_opA_sel <= 1'b0;
				ctrl_mux3to1_mul_sa_sel <= 2'b10;
				ctrl_mul_op <= 3'b011;
			end
			`FUNC_SRL:
			begin
				ctrl_mux7to1_nop10_d_sel <= 3'b011;
				ctrl_mux3to1_nop6_d_sel <= 2'b01;
				ctrl_mux2to1_mul_opA_sel <= 1'b0;
				ctrl_mux3to1_mul_sa_sel <= 2'b00;
				ctrl_mul_op <= 3'b001;
			end
			`FUNC_SRLV:
			begin
				ctrl_mux7to1_nop10_d_sel <= 3'b011;
				ctrl_mux3to1_nop6_d_sel <= 2'b01;
				ctrl_mux2to1_mul_opA_sel <= 1'b0;
				ctrl_mux3to1_mul_sa_sel <= 2'b10;
				ctrl_mul_op <= 3'b001;
			end
			`FUNC_SUB:
			begin
				ctrl_mux7to1_nop10_d_sel <= 3'b110;
				ctrl_mux2to1_addersub_opA_sel <= 1'b0;
				ctrl_mux3to1_nop6_d_sel <= 2'b01;
				ctrl_addersub_op <= 3'b000;
			end
			`FUNC_SUBU:
			begin
				ctrl_mux7to1_nop10_d_sel <= 3'b110;
				ctrl_mux2to1_addersub_opA_sel <= 1'b0;
				ctrl_mux3to1_nop6_d_sel <= 2'b01;
				ctrl_addersub_op <= 3'b010;
			end
			`FUNC_XOR:
			begin
				ctrl_mux7to1_nop10_d_sel <= 3'b100;
				ctrl_mux3to1_nop6_d_sel <= 2'b01;
				ctrl_logic_unit_op <= 2'b10;
			end
		endcase
		`OP_SW:
		begin
			ctrl_mux2to1_addersub_opA_sel <= 1'b0;
			ctrl_mux3to1_nop6_d_sel <= 2'b10;
			ctrl_data_mem_op <= 4'b1000;
			ctrl_addersub_op <= 3'b011;
		end
		`OP_XORI:
		begin
			ctrl_mux7to1_nop10_d_sel <= 3'b100;
			ctrl_mux3to1_nop6_d_sel <= 2'b10;
			ctrl_logic_unit_op <= 2'b10;
		end
	endcase


	
		//Logic for enable signals in Pipe Stage 2



	case (pipereg11_q)
		`OP_ADDI:
			ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
		`OP_ADDIU:
			ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
		`OP_ANDI:
			ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
		`OP_BEQ:
		begin
			ctrl_branchresolve_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
		end
		`OP_BGTZ:
		begin
			ctrl_branchresolve_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
		end
		`OP_BLEZ:
		begin
			ctrl_branchresolve_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
		end
		`OP_BNE:
		begin
			ctrl_branchresolve_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
		end
		`OP_J:
			ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
		`OP_JAL:
		begin
			ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
		end
		`OP_LB:
		begin
			ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			ctrl_data_mem_en <=1'b1;
		end
		`OP_LBU:
		begin
			ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			ctrl_data_mem_en <=1'b1;
		end
		`OP_LH:
		begin
			ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			ctrl_data_mem_en <=1'b1;
		end
		`OP_LHU:
		begin
			ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			ctrl_data_mem_en <=1'b1;
		end
		`OP_LUI:
		begin
			ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			ctrl_mul_start <=1'b1;
		end
		`OP_LW:
		begin
			ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			ctrl_data_mem_en <=1'b1;
		end
		`OP_ORI:
			ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
		`OP_REGIMM:
		case (pipereg13_q[0])
			`FUNC_BGEZ:
			begin
				ctrl_branchresolve_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
				ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			end
			`FUNC_BLTZ:
			begin
				ctrl_branchresolve_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
				ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			end
		endcase
		`OP_SB:
			ctrl_data_mem_en <=1'b1;
		`OP_SH:
			ctrl_data_mem_en <=1'b1;
		`OP_SLTI:
			ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
		`OP_SLTIU:
			ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
		`OP_SPECIAL:
		case (pipereg12_q)
			`FUNC_ADD:
				ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			`FUNC_ADDU:
				ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			`FUNC_AND:
				ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			`FUNC_JALR:
			begin
				ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
				ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			end
			`FUNC_JR:
				ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			`FUNC_MFHI:
				ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			`FUNC_MFLO:
				ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			`FUNC_MULT:
			begin
				ctrl_hi_reg_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
				ctrl_lo_reg_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
				ctrl_mul_start <=1'b1;
			end
			`FUNC_MULTU:
			begin
				ctrl_hi_reg_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
				ctrl_lo_reg_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
				ctrl_mul_start <=1'b1;
			end
			`FUNC_NOR:
				ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			`FUNC_OR:
				ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			`FUNC_SLL:
			begin
				ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
				ctrl_mul_start <=1'b1;
			end
			`FUNC_SLLV:
			begin
				ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
				ctrl_mul_start <=1'b1;
			end
			`FUNC_SLT:
				ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			`FUNC_SLTU:
				ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			`FUNC_SRA:
			begin
				ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
				ctrl_mul_start <=1'b1;
			end
			`FUNC_SRAV:
			begin
				ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
				ctrl_mul_start <=1'b1;
			end
			`FUNC_SRL:
			begin
				ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
				ctrl_mul_start <=1'b1;
			end
			`FUNC_SRLV:
			begin
				ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
				ctrl_mul_start <=1'b1;
			end
			`FUNC_SUB:
				ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			`FUNC_SUBU:
				ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
			`FUNC_XOR:
				ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
		endcase
		`OP_SW:
			ctrl_data_mem_en <=1'b1;
		`OP_XORI:
			ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled;
	endcase
end

/********* Stall Network & PipeReg Control ********/
assign stall_out_stage1 = stall_out_stage2;
assign ctrl_pipereg13_en = ~stall_out_stage1;
assign ctrl_pipereg12_en = ~stall_out_stage1;
assign ctrl_pipereg11_en = ~stall_out_stage1;
assign ctrl_pipereg1_en = ~stall_out_stage1;
assign ctrl_pipereg3_en = ~stall_out_stage1;
assign ctrl_pipereg2_en = ~stall_out_stage1;
assign ctrl_pipereg5_en = ~stall_out_stage1;
assign ctrl_pipereg_en = ~stall_out_stage1;
assign ctrl_pipereg14_en = ~stall_out_stage1;
assign ctrl_pipereg15_en = ~stall_out_stage1;
assign ctrl_pipereg16_en = ~stall_out_stage1;
assign stall_out_stage2 = ctrl_data_mem_stalled|ctrl_mul_stalled;
assign branch_mispred = (((ctrl_ifetch_op==1) || (ctrl_ifetch_op==0 && mux6to1_ifetch_load_out)) & ctrl_ifetch_we);
assign stall_2nd_delayslot = &has_delayslot;
assign has_delayslot = 0;
assign squash_stage1 = ((stall_out_stage1&~stall_out_stage2))|~resetn;
assign ctrl_pipereg13_resetn = ~squash_stage1;
assign ctrl_pipereg12_resetn = ~squash_stage1;
assign ctrl_pipereg11_resetn = ~squash_stage1;
assign ctrl_pipereg1_resetn = ~squash_stage1;
assign ctrl_pipereg3_resetn = ~squash_stage1;
assign ctrl_pipereg2_resetn = ~squash_stage1;
assign ctrl_pipereg5_resetn = ~squash_stage1;
assign ctrl_pipereg_resetn = ~squash_stage1;
assign ctrl_pipereg14_resetn = ~squash_stage1;
assign ctrl_pipereg15_resetn = ~squash_stage1;
assign ctrl_pipereg16_resetn = ~squash_stage1;
assign ctrl_pipereg16_squashn = 1'b1;
assign ctrl_pipereg15_squashn = 1'b1;
assign ctrl_pipereg14_squashn = 1'b1;
assign ctrl_pipereg_squashn = 1'b1;
assign ctrl_pipereg5_squashn = 1'b1;
assign ctrl_pipereg2_squashn = 1'b1;
assign ctrl_pipereg3_squashn = 1'b1;
assign ctrl_pipereg1_squashn = 1'b1;
assign ctrl_pipereg11_squashn = 1'b1;
assign ctrl_pipereg12_squashn = 1'b1;
assign ctrl_pipereg13_squashn = 1'b1;
assign ctrl_ifetch_squashn = 1'b1;
wire ctrl_ifetch_squashn;

assign squash_stage2 = ((stall_out_stage2))|~resetn;

/****************************** Datapath **************************/
/******************** Hazard Detection Logic ***********************/
assign haz_zeroer0_q_pipereg5_q = (zeroer0_q==pipereg5_q) && (|zeroer0_q);
assign haz_zeroer_q_pipereg5_q = (zeroer_q==pipereg5_q) && (|zeroer_q);
assign const8_out = 32'b00000000000000000000000000000000;
assign const9_out = 32'b00000000000000000000000000010000;
assign const_out =  32'b00000000000000000000000000011111;




/*************** DATAPATH COMPONENTS **************/
addersub addersub (
	.opB(nop6_q),
	.opA(mux2to1_addersub_opA_out),
	.op(ctrl_addersub_op),
	.result_slt(addersub_result_slt),
	.result(addersub_result));
//	defparam
	//	addersub.WIDTH=32;

reg_file reg_file (
	.clk(clk),
	.resetn(resetn),
	.c_writedatain(nop10_q),
	.c_reg(pipereg5_q),
	.b_reg(zeroer0_q),
	.a_reg(zeroer_q),
	.c_we(ctrl_reg_file_c_we),
	.b_en(ctrl_reg_file_b_en),
	.a_en(ctrl_reg_file_a_en),
	.b_readdataout(reg_file_b_readdataout),
	.a_readdataout(reg_file_a_readdataout));

mul mul (
	.clk(clk),
	.resetn(resetn),
	.sa(mux3to1_mul_sa_out),
	.dst(pipereg5_q),
	.opB(nop7_q),
	.opA(mux2to1_mul_opA_out),
	.op(ctrl_mul_op),
	.start(ctrl_mul_start),
	.stalled(ctrl_mul_stalled),
	.shift_result(mul_shift_result),
	.lo(mul_lo),
	.hi(mul_hi));
//	defparam
	//	mul.WIDTH=32;

ifetch ifetch (
	.clk(clk),
	.resetn(resetn),
	.boot_iaddr(boot_iaddr),
	.boot_idata(boot_idata),
	.boot_iwe(boot_iwe),
	.load(mux6to1_ifetch_load_out),
	.load_data(mux3to1_ifetch_load_data_out),
	.op(ctrl_ifetch_op),
	.we(ctrl_ifetch_we),
	.squashn(ctrl_ifetch_squashn),
	.en(ctrl_ifetch_en),
	.pc_out(ifetch_pc_out),
	.instr(ifetch_instr),
	.opcode(ifetch_opcode),
	.func(ifetch_func),
	.rs(ifetch_rs),
	.rt(ifetch_rt),
	.rd(ifetch_rd),
	.instr_index(ifetch_instr_index),
	.offset(ifetch_offset),
	.sa(ifetch_sa),
	.next_pc(ifetch_next_pc));
	
data_mem data_mem (
	.clk(clk),
	.resetn(resetn),
	.stalled(ctrl_data_mem_stalled),
	.d_writedata(nop7_q),
	.d_address(addersub_result),
	.boot_daddr(boot_daddr),
	.boot_ddata(boot_ddata),
	.boot_dwe(boot_dwe),
	.op(ctrl_data_mem_op),
	.d_loadresult(data_mem_d_loadresult));

logic_unit logic_unit (
	.opB(nop6_q),
	.opA(nop_q),
	.op(ctrl_logic_unit_op),
	.result(logic_unit_result));
//	defparam
	//	logic_unit.WIDTH=32;

pcadder pcadder (
	.offset(pipereg_q),
	.pc(pipereg3_q),
	.result(pcadder_result));

signext16 signext16 (
	.in(ifetch_offset),
	.out(signext16_out));

merge26lo merge26lo (
	.in2(pipereg1_q),
	.in1(pipereg3_q),
	.out(merge26lo_out));

hi_reg hi_reg (
	.clk(clk),
	.resetn(resetn),
	.d(mul_hi),
	.en(ctrl_hi_reg_en),
	.q(hi_reg_q));
//	defparam
//		hi_reg.WIDTH=32;

branchresolve branchresolve (
	.rt(nop7_q),
	.rs(nop_q),
	.en(ctrl_branchresolve_en),
	.eqz(branchresolve_eqz),
	.gez(branchresolve_gez),
	.gtz(branchresolve_gtz),
	.lez(branchresolve_lez),
	.ltz(branchresolve_ltz),
	.ne(branchresolve_ne),
	.eq(branchresolve_eq));
//	defparam
//		branchresolve.WIDTH=32;

lo_reg lo_reg (
	.clk(clk),
	.resetn(resetn),
	.d(mul_lo),
	.en(ctrl_lo_reg_en),
	.q(lo_reg_q));
//	defparam
//		lo_reg.WIDTH=32;

/*
const const8 (
	.out(const8_out));
//	defparam
	//	const8.WIDTH=32,
		//const8.VAL=0;

const const9 (
	.out(const9_out));
//	defparam
	//	const9.WIDTH=32,
		//const9.VAL=16;

const const (
	.out(const_out));
//	defparam
	//	const.WIDTH=32,
		//const.VAL=31;
		*/

pipereg_w32 pipereg (
	.clk(clk),
	.resetn(ctrl_pipereg_resetn),
	.d(mux2to1_pipereg_d_out),
	.squashn(ctrl_pipereg_squashn),
	.en(ctrl_pipereg_en),
	.q(pipereg_q));
//	defparam
	//	pipereg.WIDTH=32;

pipereg_w26 pipereg1 (
	.clk(clk),
	.resetn(ctrl_pipereg1_resetn),
	.d(ifetch_instr_index),
	.squashn(ctrl_pipereg1_squashn),
	.en(ctrl_pipereg1_en),
	.q(pipereg1_q));
//	defparam
	//	pipereg1.WIDTH=26;

pipereg_w5 pipereg2 (
	.clk(clk),
	.resetn(ctrl_pipereg2_resetn),
	.d(ifetch_sa),
	.squashn(ctrl_pipereg2_squashn),
	.en(ctrl_pipereg2_en),
	.q(pipereg2_q));
//	defparam
	//	pipereg2.WIDTH=5;

pipereg_w5 pipereg5 (
	.clk(clk),
	.resetn(ctrl_pipereg5_resetn),
	.d(zeroer4_q),
	.squashn(ctrl_pipereg5_squashn),
	.en(ctrl_pipereg5_en),
	.q(pipereg5_q));
	//defparam
		//pipereg5.WIDTH=5;

pipereg_w32 pipereg14 (
	.clk(clk),
	.resetn(ctrl_pipereg14_resetn),
	.d(nop10_q),
	.squashn(ctrl_pipereg14_squashn),
	.en(ctrl_pipereg14_en),
	.q(pipereg14_q));
	//defparam
	//	pipereg14.WIDTH=32;

pipereg_w32 pipereg3 (
	.clk(clk),
	.resetn(ctrl_pipereg3_resetn),
	.d(ifetch_pc_out),
	.squashn(ctrl_pipereg3_squashn),
	.en(ctrl_pipereg3_en),
	.q(pipereg3_q));
//	defparam
//		pipereg3.WIDTH=32;

nop nop7 (
	.d(mux2to1_nop7_d_out),
	.q(nop7_q));
	//defparam
//		nop7.WIDTH=32;

nop nop (
	.d(mux2to1_nop_d_out),
	.q(nop_q));
	//defparam
	//	nop.WIDTH=32;

nop nop10 (
	.d(mux7to1_nop10_d_out),
	.q(nop10_q));
	//defparam
	//	nop10.WIDTH=32;

nop nop6 (
	.d(mux3to1_nop6_d_out),
	.q(nop6_q));
	//defparam
	//	nop6.WIDTH=32;

zeroer zeroer (
	.d(ifetch_rs),
	.en(ctrl_zeroer_en),
	.q(zeroer_q));
	//defparam
	//	zeroer.WIDTH=5;

zeroer zeroer0 (
	.d(ifetch_rt),
	.en(ctrl_zeroer0_en),
	.q(zeroer0_q));
	//defparam
	//	zeroer0.WIDTH=5;

zeroer zeroer4 (
	.d(mux3to1_zeroer4_d_out),
	.en(ctrl_zeroer4_en),
	.q(zeroer4_q));
	//defparam
	//	zeroer4.WIDTH=5;

fakedelay fakedelay (
	.clk(clk),
	.d(ifetch_pc_out),
	.q(fakedelay_q));
	//defparam
	//	fakedelay.WIDTH=32;

		// Multiplexor mux3to1_ifetch_load_data instantiation
assign mux3to1_ifetch_load_data_out = 
	(ctrl_mux3to1_ifetch_load_data_sel==2) ? pcadder_result :
	(ctrl_mux3to1_ifetch_load_data_sel==1) ? merge26lo_out :
	nop_q;

		// Multiplexor mux2to1_mul_opA instantiation
assign mux2to1_mul_opA_out = 
	(ctrl_mux2to1_mul_opA_sel==1) ? nop_q :
	nop6_q;

		// Multiplexor mux6to1_ifetch_load instantiation
assign mux6to1_ifetch_load_out = 
	(ctrl_mux6to1_ifetch_load_sel==3'd5) ? branchresolve_eq :
	(ctrl_mux6to1_ifetch_load_sel==3'd4) ? branchresolve_ne :
	(ctrl_mux6to1_ifetch_load_sel==3'd3) ? branchresolve_lez :
	(ctrl_mux6to1_ifetch_load_sel==3'd2) ? branchresolve_ltz :
	(ctrl_mux6to1_ifetch_load_sel==3'd1) ? branchresolve_gez :
	branchresolve_gtz;

		// Multiplexor mux3to1_mul_sa instantiation
assign mux3to1_mul_sa_out = 
	(ctrl_mux3to1_mul_sa_sel==2) ? nop_q :
	(ctrl_mux3to1_mul_sa_sel==1) ? const9_out :
	pipereg2_q;

		// Multiplexor mux2to1_addersub_opA instantiation
assign mux2to1_addersub_opA_out = 
	(ctrl_mux2to1_addersub_opA_sel==1) ? fakedelay_q :
	nop_q;

		// Multiplexor mux7to1_nop10_d instantiation
assign mux7to1_nop10_d_out = 
	(ctrl_mux7to1_nop10_d_sel==3'd6) ? addersub_result :
	(ctrl_mux7to1_nop10_d_sel==3'd5) ? addersub_result_slt :
	(ctrl_mux7to1_nop10_d_sel==3'd4) ? logic_unit_result :
	(ctrl_mux7to1_nop10_d_sel==3'd3) ? mul_shift_result :
	(ctrl_mux7to1_nop10_d_sel==3'd2) ? data_mem_d_loadresult :
	(ctrl_mux7to1_nop10_d_sel==3'd1) ? hi_reg_q :
	lo_reg_q;

		// Multiplexor mux2to1_pipereg_d instantiation
assign mux2to1_pipereg_d_out = 
	(ctrl_mux2to1_pipereg_d_sel==1) ? ifetch_offset :
	signext16_out;

		// Multiplexor mux3to1_nop6_d instantiation
assign mux3to1_nop6_d_out = 
	(ctrl_mux3to1_nop6_d_sel==2) ? pipereg_q :
	(ctrl_mux3to1_nop6_d_sel==1) ? nop7_q :
	const8_out;

		// Multiplexor mux3to1_zeroer4_d instantiation
assign mux3to1_zeroer4_d_out = 
	(ctrl_mux3to1_zeroer4_d_sel==2) ? ifetch_rt :
	(ctrl_mux3to1_zeroer4_d_sel==1) ? ifetch_rd :
	const_out;

pipereg_w6 pipereg11 (
	.clk(clk),
	.resetn(ctrl_pipereg11_resetn),
	.d(ifetch_opcode),
	.squashn(ctrl_pipereg11_squashn),
	.en(ctrl_pipereg11_en),
	.q(pipereg11_q));
	//defparam
	//	pipereg11.WIDTH=6;

		// Multiplexor mux2to1_nop_d instantiation
assign mux2to1_nop_d_out = 
	(pipereg15_q==1) ? pipereg14_q :
	reg_file_a_readdataout;

pipereg_w1 pipereg16 (
	.clk(clk),
	.resetn(ctrl_pipereg16_resetn),
	.d(haz_zeroer0_q_pipereg5_q),
	.squashn(ctrl_pipereg16_squashn),
	.en(ctrl_pipereg16_en),
	.q(pipereg16_q));
	//defparam
	//	pipereg16.WIDTH=1;

pipereg_w1 pipereg15 (
	.clk(clk),
	.resetn(ctrl_pipereg15_resetn),
	.d(haz_zeroer_q_pipereg5_q),
	.squashn(ctrl_pipereg15_squashn),
	.en(ctrl_pipereg15_en),
	.q(pipereg15_q));
	//defparam
	//	pipereg15.WIDTH=1;

		// Multiplexor mux2to1_nop7_d instantiation
assign mux2to1_nop7_d_out = 
	(pipereg16_q==1) ? pipereg14_q :
	reg_file_b_readdataout;

pipereg_w6 pipereg12 (
	.clk(clk),
	.resetn(ctrl_pipereg12_resetn),
	.d(ifetch_func),
	.squashn(ctrl_pipereg12_squashn),
	.en(ctrl_pipereg12_en),
	.q(pipereg12_q));
	//defparam
	//	pipereg12.WIDTH=6;

pipereg_w5 pipereg13 (
	.clk(clk),
	.resetn(ctrl_pipereg13_resetn),
	.d(ifetch_rt),
	.squashn(ctrl_pipereg13_squashn),
	.en(ctrl_pipereg13_en),
	.q(pipereg13_q));
	//defparam
	//	pipereg13.WIDTH=5;



endmodule

/****************************************************************************
          AddSub unit
- Should perform ADD, ADDU, SUBU, SUB, SLT, SLTU

  is_slt signext addsub
    op[2] op[1] op[0]  |  Operation
0     0     0     0         SUBU
2     0     1     0         SUB
1     0     0     1         ADDU
3     0     1     1         ADD
4     1     0     0         SLTU
6     1     1     0         SLT

****************************************************************************/
module addersub (
            opB, opA,
            op, 
            result_slt,
            result );

//parameter WIDTH=32;
//`DEFINE WIDTH 32


input [31:0] opA;
input [31:0] opB;
//input carry_in;
input [2:0] op;
output result_slt;
output [31:0] result;



wire [32:0] sum;


wire addsub;
wire useless;
assign useless = op[1] & op[2];


assign addsub=op[0];
wire not_addsub;
assign not_addsub = ~addsub;

assign result=sum[31:0];

assign result_slt=sum[32];

dummy_add_sub adder32bit (opA,opB,not_addsub,sum);


// This is an LPM from Altera, replacing with a dummy one for now
/*
lpm_add_sub adder_inst(
    .dataa({signext&opA[WIDTH-1],opA}),
    .datab({signext&opB[WIDTH-1],opB}),
    .cin(~addsub),
    .add_sub(addsub),
    .result(sum)
        // synopsys translate_off
        ,
        .cout (),
        .clken (),
        .clock (),
        .overflow (),
        .aclr ()
        // synopsys translate_on
    );
//defparam 
//    adder_inst.lpm_width=WIDTH+1,
//   adder_inst.lpm_representation="SIGNED";
*/

endmodule





module dummy_add_sub (dataa,datab,cin,result);
//this is goign to be UUUUGGGGGGLLLYYYYY
//probably going to do some serious timing violations
// but i'm sure it will be interesting for the packing problem
input [31:0] dataa;
input [31:0] datab;
input cin;
output [32:0] result;
//
wire [31:0] carry_from;
wire [31:0] sum;


full_adder bit0 (cin,dataa[0],datab[0],sum[0],carry_from [0]);
full_adder bit1 (carry_from [0],dataa[1],datab[1],sum[1],carry_from [1]);
full_adder bit2 (carry_from [1],dataa[2],datab[2],sum[2],carry_from [2]);
full_adder bit3 (carry_from [2],dataa[3],datab[3],sum[3],carry_from [3]);
full_adder bit4 (carry_from [3],dataa[4],datab[4],sum[4],carry_from [4]);
full_adder bit5 (carry_from [4],dataa[5],datab[5],sum[5],carry_from [5]);
full_adder bit6 (carry_from [5],dataa[6],datab[6],sum[6],carry_from [6]);
full_adder bit7 (carry_from [6],dataa[7],datab[7],sum[7],carry_from [7]);

full_adder bit8 (carry_from [7],dataa[8],datab[8],sum[8],carry_from [8]);
full_adder bit9 (carry_from [8],dataa[9],datab[9],sum[9],carry_from [9]);
full_adder bit10 (carry_from [9],dataa[10],datab[10],sum[10],carry_from [10]);
full_adder bit11 (carry_from [10],dataa[11],datab[11],sum[11],carry_from [11]);
full_adder bit12 (carry_from [11],dataa[12],datab[12],sum[12],carry_from [12]);
full_adder bit13 (carry_from [12],dataa[13],datab[13],sum[13],carry_from [13]);
full_adder bit14 (carry_from [13],dataa[14],datab[14],sum[14],carry_from [14]);
full_adder bit15 (carry_from [14],dataa[15],datab[15],sum[15],carry_from [15]);

full_adder bit16 (carry_from [15],dataa[16],datab[16],sum[16],carry_from [16]);
full_adder bit17 (carry_from [16],dataa[17],datab[17],sum[17],carry_from [17]);
full_adder bit18 (carry_from [17],dataa[18],datab[18],sum[18],carry_from [18]);
full_adder bit19 (carry_from [18],dataa[19],datab[19],sum[19],carry_from [19]);
full_adder bit20 (carry_from [19],dataa[20],datab[20],sum[20],carry_from [20]);
full_adder bit21 (carry_from [20],dataa[21],datab[21],sum[21],carry_from [21]);
full_adder bit22 (carry_from [21],dataa[22],datab[22],sum[22],carry_from [22]);
full_adder bit23 (carry_from [22],dataa[23],datab[23],sum[23],carry_from [23]);

full_adder bit24 (carry_from [23],dataa[24],datab[24],sum[24],carry_from [24]);
full_adder bit25 (carry_from [24],dataa[25],datab[25],sum[25],carry_from [25]);
full_adder bit26 (carry_from [25],dataa[26],datab[26],sum[26],carry_from [26]);
full_adder bit27 (carry_from [26],dataa[27],datab[27],sum[27],carry_from [27]);
full_adder bit28 (carry_from [27],dataa[28],datab[28],sum[28],carry_from [28]);
full_adder bit29 (carry_from [28],dataa[29],datab[29],sum[29],carry_from [29]);
full_adder bit30 (carry_from [29],dataa[30],datab[30],sum[30],carry_from [30]);
full_adder bit31 (carry_from [30],dataa[31],datab[31],sum[31],carry_from [31]);

assign result [31:0] = sum;
assign result [32] = carry_from [31];

endmodule




module full_adder (cin,x,y,s,cout);
input cin;
input x;
input y;
output s;
output cout;
assign s = x^y^cin;
assign cout = (x&y) | (x & cin) | (y&cin);
endmodule

/****************************************************************************
          Register File

   - Has two read ports (a and b) and one write port (c)
   - sel chooses the register to be read/written
****************************************************************************/

module reg_file(clk,resetn,  c_writedatain,
	c_reg,b_reg,a_reg,c_we, b_en, a_en,
b_readdataout, a_readdataout);


//parameter WIDTH=32;
//parameter NUMREGS=32;
//parameter LOG2NUMREGS=5;

input clk;
input resetn;

input a_en;
input b_en;
input [31:0] c_writedatain;
input c_we;
input [31:0] a_reg;
input [31:0] b_reg;
input [31:0] c_reg;
output [31:0] a_readdataout;
output [31:0] b_readdataout;
reg [31:0] a_readdataout;
reg [31:0] b_readdataout;


wire [31:0] a_readdataout_temp;
wire [31:0] b_readdataout_temp;


assign b_readdataout = b_readdataout_temp;
assign a_readdataout = a_readdataout_temp;

/*
	altsyncram	reg_file1(
				.wren_a (c_we&(|c_reg)),
				.clock0 (clk),
        .clock1 (clk),
        .clocken1 (a_en),
				.address_a (c_reg[LOG2NUMREGS-1:0]),
				.address_b (a_reg[LOG2NUMREGS-1:0]),
				.data_a (c_writedatain),
				.q_b (a_readdataout)
        // synopsys translate_off
        ,
        .aclr0 (1'b0),
        .aclr1 (1'b0),
        .byteena_a (1'b1),
        .byteena_b (1'b1),
        .data_b (32'b11111111),
        .wren_b (1'b0),
        .rden_b(1'b1),
        .q_a (),
        .clocken0 (1'b1),
        .addressstall_a (1'b0),
        .addressstall_b (1'b0)
        // synopsys translate_on
    );
	defparam
		reg_file1.operation_mode = "DUAL_PORT",
		reg_file1.width_a = WIDTH,
		reg_file1.widthad_a = LOG2NUMREGS,
		reg_file1.numwords_a = NUMREGS,
		reg_file1.width_b = WIDTH,
		reg_file1.widthad_b = LOG2NUMREGS,
		reg_file1.numwords_b = NUMREGS,
		reg_file1.lpm_type = "altsyncram",
		reg_file1.width_byteena_a = 1,
		reg_file1.outdata_reg_b = "UNREGISTERED",
		reg_file1.indata_aclr_a = "NONE",
		reg_file1.wrcontrol_aclr_a = "NONE",
		reg_file1.address_aclr_a = "NONE",
		reg_file1.rdcontrol_reg_b = "CLOCK1",
		reg_file1.address_reg_b = "CLOCK1",
		reg_file1.address_aclr_b = "NONE",
		reg_file1.outdata_aclr_b = "NONE",
		reg_file1.read_during_write_mode_mixed_ports = "OLD_DATA",
		reg_file1.ram_block_type = "AUTO",
		reg_file1.intended_device_family = "Stratix";

		//Reg file duplicated to avoid contention between 2 read
		//and 1 write
		*/
		wire [31:0] dummy_out;
		wire [31:0] constone;
		assign constone = 32'b11111111111111111111111111111111;
		wire wren1;
		assign wren1 = (c_we & (|c_reg));
	dual_port_ram regfile1_replace (
  .clk (clk),
  .we1(wren1),
  .we2(1'b0),
  .data1(c_writedatain),
  .data2(constone),
  .out1(a_readdataout_temp),
  .out2(dummy_out),
  .addr1(c_reg),
  .addr2(a_reg));
		
		
		
		//MORE MEMORY
		/*
	altsyncram	reg_file2(
				.wren_a (c_we&(|c_reg)),
				.clock0 (clk),
        .clock1 (clk),
        .clocken1 (b_en),
				.address_a (c_reg[LOG2NUMREGS-1:0]),
				.address_b (b_reg[LOG2NUMREGS-1:0]),
				.data_a (c_writedatain),
				.q_b (b_readdataout)
        // synopsys translate_off
        ,
        .aclr0 (1'b0),
        .aclr1 (1'b0),
        .byteena_a (1'b1),
        .byteena_b (1'b1),
        .data_b (32'b11111111),
        .rden_b(1'b1),
        .wren_b (1'b0),
        .q_a (),
        .clocken0 (1'b1),
        .addressstall_a (1'b0),
        .addressstall_b (1'b0)
        // synopsys translate_on
    );
	defparam
		reg_file2.operation_mode = "DUAL_PORT",
		reg_file2.width_a = WIDTH,
		reg_file2.widthad_a = LOG2NUMREGS,
		reg_file2.numwords_a = NUMREGS,
		reg_file2.width_b = WIDTH,
		reg_file2.widthad_b = LOG2NUMREGS,
		reg_file2.numwords_b = NUMREGS,
		reg_file2.lpm_type = "altsyncram",
		reg_file2.width_byteena_a = 1,
		reg_file2.outdata_reg_b = "UNREGISTERED",
		reg_file2.indata_aclr_a = "NONE",
		reg_file2.wrcontrol_aclr_a = "NONE",
		reg_file2.address_aclr_a = "NONE",
		reg_file2.rdcontrol_reg_b = "CLOCK1",
		reg_file2.address_reg_b = "CLOCK1",
		reg_file2.address_aclr_b = "NONE",
		reg_file2.outdata_aclr_b = "NONE",
		reg_file2.read_during_write_mode_mixed_ports = "OLD_DATA",
		reg_file2.ram_block_type = "AUTO",
		reg_file2.intended_device_family = "Stratix";
*/

wire [31:0] dummywire;
dual_port_ram regfile2_replace(
  .clk (clk),
  .we1(wren1),
  .we2(1'b0),
  .data1(c_writedatain),
  .data2(constone),
  .out1(b_readdataout_temp),
  .out2(dummywire),
  .addr1(c_reg),
  .addr2(b_reg));
		

wire useless_inputs;
assign useless_inputs = resetn & b_en & a_en;
endmodule

/****************************************************************************
          MUL/DIV unit

Operation table

   op sign dir
4  1   0    x    |  MULTU
6  1   1    x    |  MULT
0  0   0    0    |  ShiftLeft
1  0   0    1    |  ShiftRightLogic
3  0   1    1    |  ShiftRightArith
****************************************************************************/
module mul(clk, resetn, sa,  dst, opB,opA,
            op, start, stalled,
            shift_result,
             lo,hi);
//parameter 32=32;


input clk;
input resetn;

input start;
output stalled;

input [4:0] dst;

input [31:0] opA;
input [31:0] opB;
input [4:0] sa;
input [2:0] op;

output [31:0] shift_result;
output [31:0] hi;
output [31:0] lo;

/********* Control Signals *********/
wire is_signed;
wire dir;
wire is_mul;
assign is_mul=op[2];      // selects between opB and the computed shift amount
assign is_signed=op[1];
assign dir=op[0];         // selects between 2^sa and 2^(32-sa) for right shift

/********* Circuit Body *********/
wire dum;
wire dum2; 
wire dum3;
wire [32:0] opB_mux_out;
wire [4:0] left_sa;     // Amount of left shift required for both left/right
reg [32:0] decoded_sa;
wire [31:0] result;
//assign opB_mux_out= (is_mul) ? {is_signed&opB[31],opB} : decoded_sa;
assign opB_mux_out = opB;



dummy_mult fake_mult_one (opA,opB_mux_out, clk, resetn, result);
assign hi = result [15:8];
assign lo = result [7:0];
// Cannot support this now
/*
lpm_mult  lpm_mult_component (
  .dataa ({is_signed&opA[31],opA}),
  .datab (opB_mux_out),
  .sum(),
  .clock(clk),
  .clken(),
  .aclr(~resetn),
  .result ({dum2,dum,hi,lo}));
defparam
  lpm_mult_component.lpm_32a = 32+1,
  lpm_mult_component.lpm_32b = 32+1,
  lpm_mult_component.lpm_32p = 2*32+2,
  lpm_mult_component.lpm_32s = 1,
  lpm_mult_component.lpm_pipeline = 1,
  lpm_mult_component.lpm_type = "LPM_MULT",
  lpm_mult_component.lpm_representation = "SIGNED",
  lpm_mult_component.lpm_hint = "MAXIMIZE_SPEED=6";
*/
assign shift_result= (dir & |sa) ? hi : lo;


// 1 cycle stall state machine
wire or_dst;
wire start_and_ismul;
wire request;

assign or_dst = |dst;
assign start_and_ismul = start & is_mul; 
assign request = (or_dst & start & ~is_mul) | (start_and_ismul);
onecyclestall staller(request,clk,resetn,stalled);


endmodule

module dummy_mult  (opA,opB_mux_out, clk, resetn, result);
input [31:0] opA;
input [31:0] opB_mux_out;
input  clk;
input  resetn;
output[31:0] result;
reg [31:0] result;


always @ (posedge clk)
begin
	if (resetn)
	result <= 32'b00000000000000000000000000000000;
	else
		//multiplier by star symbol
		//though this is probably supposed to be signed
		result <= opA * opB_mux_out;
end
		endmodule
		

/****************************************************************************
            Fetch Unit
op
  0  Conditional PC write
  1  UnConditional PC write

****************************************************************************/

module ifetch(clk,resetn,
 boot_iaddr, 
  boot_idata, 
  boot_iwe,
  load,
  load_data,
     op,
	  we,
	     squashn,
		  en,
		  pc_out,
		   instr,
		   opcode,
		    func,
			  rs,
        rt,
        rd,
			 instr_index,
			   offset,
			     sa,
		  next_pc);

//parameter PC_WIDTH=30;
//parameter I_DATAWIDTH=32;
//parameter I_ADDRESSWIDTH=14;
//parameter I_SIZE=16384;

input [31:0] boot_iaddr;
input [31:0] boot_idata;
input boot_iwe;

input clk;
input resetn;
input en;     // PC increment enable
input we;     // PC write enable
input squashn;// squash fetch
input op;     // determines if conditional or unconditional branch
input load;
input [`I_DATAWIDTH-1:0] load_data;
output [`I_DATAWIDTH-1:0] pc_out;   // output pc + 1 shifted left 2 bits
output [`PC_WIDTH-1:0] next_pc;
output [31:26] opcode;
output [25:21] rs;
output [20:16] rt;
output [15:11] rd;
output [10:6] sa;
output [15:0] offset;
output [25:0] instr_index;
output [5:0] func;
output [`I_DATAWIDTH-1:0] instr;


wire [`PC_WIDTH-1:0] pc_plus_1;
wire [`PC_WIDTH-1:0] pc;
assign pc_plus_1 = pc;
wire ctrl_load;
wire out_of_sync;

assign ctrl_load=(load&~op|op);
wire notresetn;
assign notresetn = ~resetn;
wire count_en;
assign count_en = (~ctrl_load)&~out_of_sync;
wire counter_en;
assign counter_en = en | we;
wire [32:2] reg_load_data;

assign reg_load_data = load_data [31:2];

wire reg_d;
wire reg_en;
assign reg_d = (we&(~en)&(squashn));
assign reg_en = en|we;


register_1bit sync_pcs_up( reg_d, clk, resetn,reg_en, out_of_sync);

wire wren1;
assign wren1 = 1'b0;
wire [31:0] next_pc_wire;
assign next_pc_wire = next_pc [13:0];

dual_port_ram imem_replace(
  .clk (clk),
  .we1(wren1),
  .we2(boot_iwe),
  .data1(load_data),
  .data2(boot_idata),
  .out1(instr),
  .out2(dummyout2),
  .addr1(next_pc_wire),
  .addr2(boot_iaddr));

wire [31:0]dummyout2;
wire [31:0] dummyin1;
assign dummyin1 = 32'b00000000000000000000000000000000;
wire dummy;


dummy_counter pc_reg ((reg_load_data),(clk),(counter_en),(count_en),(notresetn),(ctrl_load),(pc));
//assign {dummy,pc_plus_1} = pc + {1'b0,~out_of_sync};
//assign pc_out={pc_plus_1,2'b0};
assign pc_out [31:2] = pc_plus_1;
assign pc_out [1:0] = 2'b00;

assign next_pc = ctrl_load ? load_data[31:2] : pc_plus_1;
//assign next_pc = pc_plus_1;
assign opcode=instr[31:26];
assign rs=instr[25:21];
assign rt=instr[20:16];
assign rd=instr[15:11];
assign sa=instr[10:6];
assign offset=instr[15:0]; 
assign instr_index=instr[25:0];
assign func=instr[5:0];



endmodule


module dummy_counter (data,clock,clk_en,cnt_en,aset,sload,q);

input [31:2] data;
input clock;
input clk_en;
input cnt_en;
input aset;
input sload;
output [`PC_WIDTH-1:0] q;
reg [`PC_WIDTH-1:0] q;

wire [2:0] sload_cnten_aset;
assign sload_cnten_aset [0] = sload;
assign sload_cnten_aset [1] = cnt_en;
assign sload_cnten_aset [2] = aset;

always @ (posedge clock)

//if (cnt_en == 1)
//q <= q+1;
begin

case (sload_cnten_aset)
		3'b000:
		q <= q;
		3'b011:
		q <= q;
		3'b110:
		q <= q;
		3'b111:
		q <= q;
		3'b101:
		q <= q;
		3'b100: 
			q <= data;
		3'b010:
		begin
			if (clk_en) 
				q <= q+1;
			else
				q <= q;

			end
		3'b001:
			q <= 29'b00000000000000000000000000000;
		default:
			q <= q;
endcase
end
/*case (sload)
	1'b1:
		begin
			q = data;
		end
	default:
		begin
			case (cnt_en)
			1'b1:
				begin
					q = q+1;
				end
			default:
				begin
					case (aset)
					1'b1:
						begin
							q = 0;
						end
					default:
						begin
							q = q;
						end
					endcase
				end
			endcase

		end
	endcase
*/
		endmodule




module data_mem( clk, resetn, stalled,
                d_writedata,
                d_address,
                boot_daddr, boot_ddata, boot_dwe, 
                op,
                d_loadresult);

input clk;
input resetn;
output stalled;

input [31:0] boot_daddr;
input [31:0] boot_ddata;
input boot_dwe;

input [`D_ADDRESSWIDTH-1:0] d_address;
input [3:0] op;
input [31:0] d_writedata;
output [`DM_DATAWIDTH-1:0] d_loadresult;

wire [`DM_BYTEENAWIDTH-1:0] d_byteena;
wire [`DM_DATAWIDTH-1:0] d_readdatain;
wire [`DM_DATAWIDTH-1:0] d_writedatamem;

wire d_write;
wire [1:0] d_address_latched;

assign d_write=op[3];

wire [1:0] d_small_adr;
assign d_small_adr = d_address[1:0];

wire one;
assign one = 1'b1;
                

wire [1:0] d_adr_one_zero;
assign d_adr_one_zero = d_address [1:0];

wire [1:0] opsize;
assign opsize = op[1:0];
wire opext;
assign opext = op[2];


store_data_translator sdtrans_inst(
    .write_data(d_writedata),
    .d_address(d_adr_one_zero),
    .store_size(op[1:0]),
    .d_byteena(d_byteena),
    .d_writedataout(d_writedatamem));



load_data_translator ldtrans_inst(
    .d_readdatain(d_readdatain),
  
    .d_loadresult(d_loadresult));


wire  dnot_address;
assign dnot_address = ~d_address[31];
wire will_be_wren1;
assign will_be_wren1 = d_write&(dnot_address);
wire [31:0] dont_care;


wire [31:0] memaddr_wrd;


assign memaddr_wrd = d_address[`DM_ADDRESSWIDTH:2];
dual_port_ram dmem_replace(
  .clk (clk),
  .we1(will_be_wren1),
  .we2(boot_dwe),
  .data1(d_writedatamem),
  .data2(boot_ddata),
  .out1(d_readdatain),
.out2 (dont_care),
  .addr1(memaddr_wrd),
  .addr2(boot_daddr));
// 1 cycle stall state machine

wire en_and_not_d_write;
assign en_and_not_d_write = ~d_write;
onecyclestall staller(en_and_not_d_write,clk,resetn,stalled);

wire useless_inputs;
assign useless_inputs = |d_address;

endmodule

//temp in here




/****************************************************************************
          Store data translator
          - moves store data to appropriate byte/halfword 
          - interfaces with altera blockrams
****************************************************************************/
module store_data_translator(
    write_data,             // data in least significant position
    d_address,
    store_size,
    d_byteena,
    d_writedataout);        // shifted data to coincide with address
//parameter WIDTH=32;


input [31:0] write_data;
input [1:0] d_address;
input [1:0] store_size;
output [3:0] d_byteena;
output [31:0] d_writedataout;

reg [3:0] d_byteena;
reg [31:0] d_writedataout;

always @(write_data or d_address or store_size)
begin
    case (store_size)
        2'b11:
            case(d_address[1:0])
                2'b00: 
                begin 
                    d_byteena=4'b1000; 
                    d_writedataout={write_data[7:0],24'b0}; 
                end
                2'b01: 
                begin 
                    d_byteena=4'b0100; 
                    d_writedataout={8'b0,write_data[7:0],16'b0}; 
                end
                2'b10: 
                begin 
                    d_byteena=4'b0010; 
                    d_writedataout={16'b0,write_data[7:0],8'b0}; 
                end
                default: 
                begin 
                    d_byteena=4'b0001; 
                    d_writedataout={24'b0,write_data[7:0]}; 
                end
            endcase
        2'b01:
            case(d_address[1])
                1'b0: 
                begin 
                    d_byteena=4'b1100; 
                    d_writedataout={write_data[15:0],16'b0}; 
                end
                default: 
                begin 
                    d_byteena=4'b0011; 
                    d_writedataout={16'b0,write_data[15:0]}; 
                end
            endcase
        default:
        begin
            d_byteena=4'b1111;
            d_writedataout=write_data;
        end
    endcase
end

endmodule

/****************************************************************************
          Load data translator
          - moves read data to appropriate byte/halfword and zero/sign extends
****************************************************************************/

module load_data_translator(
    d_readdatain,
    d_loadresult);
//parameter WIDTH=32;


input [31:0] d_readdatain;

output [31:0] d_loadresult;

wire d_adr_one;
assign d_adr_one = d_address [1];
reg [31:0] d_loadresult;
reg sign;
wire [1:0] d_address;
assign d_address [1:0] =d_readdatain [25:24];


//assume always full-word-access
always @(d_readdatain or d_address )
begin
            d_loadresult[31:0]=d_readdatain[31:0];
end
/*
Odin II REFUSES TO ACKNOWLEDGE THAT SIGN EXTENDING IS NOT A COMBINATIONAL LOOP
always @(d_readdatain or d_address or load_size or load_sign_ext)
begin
    case (load_size)
        2'b11:
        begin
            case (d_address)
                2'b00:
					begin
					d_loadresult[7:0]=d_readdatain[31:24];
					sign = d_readdatain[31];
					end
                2'b01:
						begin
						d_loadresult[7:0]=d_readdatain[23:16];
						sign = d_readdatain[23];
						end
                2'b10: 
					begin
					d_loadresult[7:0]=d_readdatain[15:8];
					sign = d_readdatain[15];
					end
                default: 
					begin
					d_loadresult[7:0]=d_readdatain[7:0];
					sign = d_readdatain[7];
					end
            endcase
			// peter milankov note: do this by hand
			// odin II does not support multiple concatenation
            //d_loadresult[31:8]={24{load_sign_ext&d_loadresult[7]}};
			d_loadresult[31]= load_sign_ext&sign;
			d_loadresult[30]= load_sign_ext&sign;
			d_loadresult[29]= load_sign_ext&sign;
			d_loadresult[28]= load_sign_ext&sign;
			d_loadresult[27]= load_sign_ext&sign;
			d_loadresult[26]= load_sign_ext&sign;
			d_loadresult[25]= load_sign_ext&sign;
			d_loadresult[24]= load_sign_ext&sign;
			d_loadresult[23]= load_sign_ext&sign;
			d_loadresult[22]= load_sign_ext&sign;
			d_loadresult[21]= load_sign_ext&sign;
			d_loadresult[20]= load_sign_ext&sign;
			d_loadresult[19]= load_sign_ext&sign;
			d_loadresult[18]= load_sign_ext&sign;
			d_loadresult[17]= load_sign_ext&sign;
			d_loadresult[16]= load_sign_ext&sign;
			d_loadresult[15]= load_sign_ext&sign;
			d_loadresult[14]= load_sign_ext&sign;
			d_loadresult[13]= load_sign_ext&sign;
			d_loadresult[12]= load_sign_ext&sign;
			d_loadresult[11]= load_sign_ext&sign;
			d_loadresult[10]= load_sign_ext&sign;
			d_loadresult[9]= load_sign_ext&sign;
			d_loadresult[8]= load_sign_ext&sign;
        end
        2'b01:
        begin
            case (d_adr_one)
                1'b0:
					begin
						d_loadresult[15:0]=d_readdatain[31:16];
						sign = d_readdatain[31];
					end
                default:
					begin
						d_loadresult[15:0]=d_readdatain[15:0];
						sign = d_readdatain[15];
					end
            endcase
// peter milankov note sign extend is concat, do by hand
            //d_loadresult[31:16]={16{load_sign_ext&d_loadresult[15]}};
			d_loadresult[31]= load_sign_ext&sign;
			d_loadresult[30]= load_sign_ext&sign;
			d_loadresult[29]= load_sign_ext&sign;
			d_loadresult[28]= load_sign_ext&sign;
			d_loadresult[27]= load_sign_ext&sign;
			d_loadresult[26]= load_sign_ext&sign;
			d_loadresult[25]= load_sign_ext&sign;
			d_loadresult[24]= load_sign_ext&sign;
			d_loadresult[23]= load_sign_ext&sign;
			d_loadresult[22]= load_sign_ext&sign;
			d_loadresult[21]= load_sign_ext&sign;
			d_loadresult[20]= load_sign_ext&sign;
			d_loadresult[19]= load_sign_ext&sign;
			d_loadresult[18]= load_sign_ext&sign;
			d_loadresult[17]= load_sign_ext&sign;
			d_loadresult[16]= load_sign_ext&sign;
        end
        default:
            d_loadresult[31:0]=d_readdatain[31:0];
    endcase
end
*/
endmodule

/****************************************************************************
          logic unit
- note ALU must be able to increment PC for JAL type instructions

Operation Table
  op
  0     AND
  1     OR
  2     XOR
  3     NOR
****************************************************************************/
module logic_unit (
            opB, opA,
            op,
            result);
//parameter WIDTH=32;



input [31:0] opA;
input [31:0] opB;
input [1:0] op;
output [31:0] result;

reg [31:0] logic_result;

always@(opA or opB or op )
    case(op)
        2'b00:
            logic_result=opA&opB;
        2'b01:
            logic_result=opA|opB;
        2'b10:
            logic_result=opA^opB;
        2'b11:
            logic_result=~(opA|opB);
    endcase

assign result=logic_result;


endmodule

module pcadder(offset,pc, result);
//parameter PC_WIDTH=32;


input [31:0] pc;
input [31:0] offset;
output [31:0] result;

wire dum;
wire useless_inputs;
assign useless_inputs = |offset;
assign {dum,result} = pc + {offset[31:0],2'b0};

endmodule


module signext16 ( in, out);

input [15:0] in;
output [31:0] out;


assign out [30]= in[15];
assign out [31]= in[15];
assign out [29]= in[15];
assign out [28]= in[15];
assign out [27]= in[15];
assign out [26]= in[15];
assign out [25]= in[15];
assign out [24]= in[15];
assign out [23]= in[15];
assign out [22]= in[15];
assign out [21]= in[15];
assign out [20]= in[15];
assign out [19]= in[15];
assign out [18]= in[15];
assign out [17]= in[15];
assign out [16]= in[15];
assign out [15:0] = in [15:0];

endmodule


module merge26lo(in2, in1, out);
input [31:0] in1;
input [25:0] in2;
output [31:0] out;

//assign out[31:0]={in1[31:28],in2[25:0],2'b0};

assign out [31:28] = in1 [31:28];
assign out [27:2] = in2 [25:0];
assign out [1:0] = 2'b00;


wire useless_inputs;
assign useless_inputs = |in1 & |in2;
endmodule

/****************************************************************************
          Generic Register
****************************************************************************/
module lo_reg(clk,resetn,d,en,q);
//parameter WIDTH=32;


input clk;
input resetn;
input en;
input [31:0] d;
output [31:0] q;
reg [31:0] q;

always @(posedge clk )		
begin
	if (resetn==0)
		q<=0;
	else if (en==1)
		q<=d;
end

endmodule

/****************************************************************************
          Generic Register
****************************************************************************/
module hi_reg(clk,resetn,d,en,q);
//parameter WIDTH=32;


input clk;
input resetn;
input en;
input [31:0] d;
output [31:0] q;
reg [31:0] q;

always @(posedge clk )		//used to be asynchronous reset
begin
	if (resetn==0)
		q<=0;
	else if (en==1)
		q<=d;
end

endmodule

/****************************************************************************
          Generic Register
****************************************************************************/

//`define WIDTH 32
/*
module register(d,clk,resetn,en,q);
//parameter WIDTH=32;






input clk;
input resetn;
input en;
input [31:0] d;
output [31:0] q;
reg [31:0] q;

always @(posedge clk )		
begin
	if (resetn==0)
		q<=0;
	else if (en==1)
		q<=d;
end

endmodule
*/
module register_1bit(d,clk,resetn,en,q);
//parameter WIDTH=32;






input clk;
input resetn;
input en;
input  d;
output q;
reg q;

always @(posedge clk )		
begin
	if (resetn==0)
		q<=0;
	else if (en==1)
		q<=d;
end

endmodule


/****************************************************************************
          Generic Register - synchronous reset
****************************************************************************/
/*
module register_sync(d,clk,resetn,en,q);
//parameter WIDTH=32;

input clk;
input resetn;
input en;
input [31:0] d;
output [31:0] q;
reg [31:0] q;

always @(posedge clk)		//synchronous reset
begin
	if (resetn==0)
		q<=0;
	else if (en==1)
		q<=d;
end

endmodule
*/
/****************************************************************************
          Generic Pipelined Register

          - Special component, components starting with "pipereg" have
          their enables treated independently of instructrions that use them.
          - They are enabled whenever the stage is active and not stalled
****************************************************************************/
/*
module pipereg(clk,resetn,d,squashn,en,q);
//parameter WIDTH=32;
//`define WIDTH 32

input clk;
input resetn;
input en;
input squashn;
input [31:0] d;
output [31:0] q;
reg [31:0] q;

always @(posedge clk)   //synchronous reset
begin
  if (resetn==0 || squashn==0)
    q<=0;
  else if (en==1)
    q<=d;
end

endmodule
*/
module pipereg_w32(clk,resetn,d,squashn,en,q);
//parameter WIDTH=32;
//`define WIDTH 32

input clk;
input resetn;
input en;
input squashn;
input [31:0] d;
output [31:0] q;
reg [31:0] q;

always @(posedge clk)   //synchronous reset
begin
  if (resetn==0 || squashn==0)
    q<=0;
  else if (en==1)
    q<=d;
end

endmodule


module pipereg_w26(clk,resetn,d,squashn,en,q);
//parameter WIDTH=32;
//`define WIDTH 32

input clk;
input resetn;
input en;
input squashn;
input [25:0] d;
output [25:0] q;
reg [25:0] q;

always @(posedge clk)   //synchronous reset
begin
  if (resetn==0 || squashn==0)
    q<=0;
  else if (en==1)
    q<=d;
end

endmodule


module pipereg_w6(clk,resetn,d,squashn,en,q);
//parameter WIDTH=32;
//`define WIDTH 32

input clk;
input resetn;
input en;
input squashn;
input [31:0] d;
output [31:0] q;
reg [31:0] q;

always @(posedge clk)   //synchronous reset
begin
  if (resetn==0 || squashn==0)
    q<=0;
  else if (en==1)
  begin
    q[5:0]<=d;
	q[31:6] <= 0;
	
	end
end

endmodule


module pipereg_w5(clk,resetn,d,squashn,en,q);
//parameter WIDTH=32;
//`define WIDTH 32

input clk;
input resetn;
input en;
input squashn;
input [31:0] d;
output [31:0] q;
reg [31:0] q;

always @(posedge clk)   //synchronous reset
begin
  if (resetn==0 || squashn==0)
    q<=0;
  else if (en==1)
   begin
    q[4:0]<=d;
	q[31:5] <= 0;
	
	end
end

endmodule

module pipereg_w1(clk,resetn,d,squashn,en,q);
//parameter WIDTH=32;
//`define WIDTH 32

input clk;
input resetn;
input en;
input squashn;
input  d;
output  q;
reg q;

always @(posedge clk)   //synchronous reset
begin
  if (resetn==0 || squashn==0)
    q<=0;
  else if (en==1)
    q<=d;
end

endmodule

/****************************************************************************
          Generic Pipelined Register 2 -OLD: If not enabled, queues squash

          - This piperegister stalls the reset signal as well
*/
/*
module pipereg_full(d,clk,resetn,squashn,en,q);
//parameter WIDTH=32;

input clk;
input resetn;
input en;
input squashn;
input [31:0] d;
output [31:0] q;
reg [31:0] q;
reg squash_save;

  always @(posedge clk)   //synchronous reset
  begin
    if (resetn==0 || (squashn==0 && en==1) || (squash_save&en))
      q<=0;
    else if (en==1)
      q<=d;
  end

  always @(posedge clk)
  begin
    if (resetn==1 && squashn==0 && en==0)
      squash_save<=1;
    else
      squash_save<=0;
  end
endmodule
*/
/****************************************************************************/

/****************************************************************************
          One cycle Stall circuit
****************************************************************************/
module onecyclestall(request,clk,resetn,stalled);
input request;
input clk;
input resetn;
output stalled;

  reg T,Tnext;

  // State machine for Stalling 1 cycle
  always@(request or T)
  begin
    case(T) 
      1'b0: Tnext=request;
      1'b1: Tnext=0;
    endcase 
  end       
  always@(posedge clk)
    if (~resetn)
      T<=0; 
    else    
      T<=Tnext;
  assign stalled=(request&~T);
endmodule

/****************************************************************************

          Multi cycle Stall circuit - with wait signal

          - One FF plus one 2:1 mux to stall 1st cycle on request, then wait
          - this makes wait don't care for the first cycle
****************************************************************************/
/*
module multicyclestall(request, devwait,clk,resetn,stalled);
input request;
input devwait;
input clk;
input resetn;
output stalled;

  reg T;

  always@(posedge clk)
    if (~resetn)
      T<=0;
    else
      T<=stalled;

  assign stalled=(T) ? devwait : request;
endmodule
*/
/****************************************************************************
          One cycle - Pipeline delay register
****************************************************************************/
/*
module pipedelayreg(d,en,clk,resetn,squashn,dst,stalled,q);
//`define WIDTH 32
//parameter WIDTH=32;
input [31:0] d;
input [4:0] dst;
input en;
input clk;
input resetn;
input squashn;
output stalled;
output [31:0] q;

  reg [31:0] q;
  reg T,Tnext;

  // State machine for Stalling 1 cycle
  always@(en or T or dst)
  begin
    case(T) 
      0: Tnext=en&(|dst);
      1: Tnext=0;
    endcase 
  end       
  always@(posedge clk)
    if (~resetn)
      T<=0; 
    else    
      T<=Tnext;

  always @(posedge clk)   //synchronous reset
  begin
    if (resetn==0 || squashn==0)
      q<=0;
    else if (en==1)
      q<=d;
  end

  assign stalled=(en&~T&(|dst));
endmodule
*/

/****************************************************************************
          Fake Delay
****************************************************************************/
module fakedelay(clk,d,q);
//`define WIDTH 32
//parameter WIDTH=32;
input [31:0] d;
input clk;
output [31:0] q;

wire unused;
assign unused = clk;
assign q=d;

endmodule

/****************************************************************************
          Zeroer
****************************************************************************/
module zeroer(d,en,q);
//parameter WIDTH=32;
//`define WIDTH 32

input en;
input [4:0] d;
output [31:0] q;
assign q[4:0]= (en) ? d : 0;
assign q [31:05] = 0;

endmodule

/****************************************************************************
          NOP - used to hack position of multiplexors
****************************************************************************/
module nop(d,q);
//parameter WIDTH=32;
//`define WIDTH 32

input [31:0] d;
output [31:0] q;

  assign q=d;

endmodule

/****************************************************************************

          Const
****************************************************************************/

/****************************************************************************
          Branch detector
****************************************************************************/
/*
module branch_detector(opcode, func, is_branch);


input [5:0] opcode;
input [5:0] func;
output is_branch;

wire is_special;

assign is_special=!(|opcode);
assign is_branch=((!(|opcode[5:3])) && !is_special) || 
                  ((is_special)&&(func[5:3]==3'b001));

endmodule
*/
//`define WIDTH 32
module branchresolve ( rt, rs,en, eqz,gez,gtz,lez,ltz,ne, eq);
//parameter WIDTH=32;

input en;
input [31:0] rs;
input [31:0] rt;
output eq;
output ne;
output ltz;
output lez;
output gtz;
output gez;
output eqz;

assign eq=(en)&(rs==rt);
assign ne=(en)&~eq;
assign eqz=(en)&~(|rs);
assign ltz=(en)&rs[31];
assign lez=(en)&rs[31] | eqz;
assign gtz=(en)&(~rs[31]) & ~eqz;
assign gez=(en)&(~rs[31]);

endmodule


