⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ex.v

📁 arm9_fpga2_verilog是一个可以综合的用verilog写的arm9的ip软核
💻 V
📖 第 1 页 / 共 3 页
字号:
               (ldm) || (swap && !second_ex)) ? 1'b1 : 1'b0;  //Recognize a load to the PCassign load_pc_ex = load & (((Rd_ex == 5'h0F) & write_Pc_Rd) |                            ((Rn_ex == 5'h0F) & double_ex & write_Pc_Rn));  //Determine whether or not inst access data in next cycleassign DnMREQ = ~((inst_type_ex == `LDRW) |		  (inst_type_ex == `LDRH) |		  (inst_type_ex == `LDM)  |		  (inst_type_ex == `SWAP) |		  (store_ex == 1'b1) 	  |		  (cop_mem_ld == 1'b1)	  |		  (cop_mem_st == 1'b1));/*------------------------------------------------------------------------        Component Instantiations------------------------------------------------------------------------*/// instantiate alualu xalu (.op1(alu_op1), .shifted_op2(alu_op2), .control(opcode),		.C(C), .result({upper_mult,alu_result}),		.flags(alu_flags));// instantiate shiftershifter xshift (.op1(op2), .shift_amount(shift_amount), 		.shift_type(shift_type), .C(C),		.result(shifted_op2), .shift_c_out(shift_c_out));// instantiate multmult xmult (.enable(multiply), .op1(op1), .op2(op2), .a(acc),		.l(alu_opcode[2]), .u(alu_opcode[1]), .nWAIT(nWAIT),		.nGCLK(nGCLK), .acc_op1(acc_op1), .acc_op2(acc_op2), 		.hold_next(hold_next_ex), .reset(mult_res), 		.sum({upper_mult,alu_result}));// instantiate mapspsrmapspsr	xmapspsr (.mode(CPSR[4:0]), .spsr_index(spsr_index));/*------------------------------------------------------------------------        Combinational Always Blocks------------------------------------------------------------------------*///Mux the SPSR's to give current onealways @(spsr_index or CPSR or spsr_fiq or spsr_svc 		or spsr_abt or spsr_irq or spsr_und)    begin	case (spsr_index)  //synopsys full_case parallel_case                3'h0: current_spsr = spsr_fiq;                3'h1: current_spsr = spsr_svc;                3'h2: current_spsr = spsr_abt;                3'h3: current_spsr = spsr_irq;                3'h4: current_spsr = spsr_und;		default: current_spsr = CPSR;	endcase    end//Set up the cond_failed signalalways @(condition or C or Z or N or V)    begin	 case (condition) //synopsys full_case parallel_case             `EQ: cond_failed_ex <= !(Z);             `NE: cond_failed_ex <= !(~Z);             `CS: cond_failed_ex <= !(C);             `CC: cond_failed_ex <= !(~C);             `MI: cond_failed_ex <= !(N);             `PL: cond_failed_ex <= !(~N);             `VS: cond_failed_ex <= !(V);             `VC: cond_failed_ex <= !(~V);             `HI: cond_failed_ex <= !(C & ~Z);             `LS: cond_failed_ex <= !(~C | Z);             `GE: cond_failed_ex <= !((N && V)||(~N && ~V));             `LT: cond_failed_ex <= !((N && ~V)||(~N && V));             `GT: cond_failed_ex <= !(~Z && ((N && V)||(~N && ~V)));             `LE: cond_failed_ex <= !(Z || ((N && ~V)||(~N && V)));             `AL: cond_failed_ex <= 1'b0;	     `NV: cond_failed_ex <= 1'b1;        endcase    end//Set up the signal which muxes out the current CPSR or the //next CPSR to the mode bits and sets up all but the flags of the//next CPSR valuealways @(CPSR or nRESET or inst_exception or swi or exc_code_ex 	  or exception_ex)    begin	if (~nRESET)	  cpsr_const[31:8] = 24'h0;        else	  cpsr_const[31:8] = {4'h0,CPSR[27:8]};	if (~nRESET)	    cpsr_const[7:0] = 8'b11010011;	else 	  begin	     if (exception_ex)		begin		    case (exc_code_ex)	//synopsys full_case parallel_case                        2'b00: cpsr_const[7:0] = {1'b1,CPSR[6],6'b010111};                  	2'b01: cpsr_const[7:0] = {2'b11,6'b010001};                  	2'b10: cpsr_const[7:0] = {1'b1,CPSR[6],6'b010010};                  	2'b11: cpsr_const[7:0] = {1'b1,CPSR[6],6'b010111};		    endcase		end	     else		cpsr_const[7:0] = {1'b1,CPSR[6],2'b01,!swi,3'b011};	  end    endalways @(nRESET or exception_ex or inst_exception or cpsr_const	  or msr or alu_opcode or Rn_ex or CPSR or shifted_op2	  or ldm or r15_inlist or alu or rd_pc or s 	  or current_spsr)    begin	if (~nRESET | exception_ex | inst_exception)	    next_cpsr[27:0] = cpsr_const;		else 	  begin	    case ({(msr & ~alu_opcode[1] & Rn_ex[0] & (CPSR[4:0] != `USR)),		   ((ldm & r15_inlist & alu_opcode[1]) | (alu & rd_pc & s))}) //synopsys full_case parallel_case		    2'b01: next_cpsr[27:0] = current_spsr[27:0];		    2'b10: next_cpsr[27:0] = shifted_op2[27:0];		  default: next_cpsr[27:0] = CPSR[27:0];	    endcase	  end    end//Set a signal that indicates the flags should not be modified//wire no_flags = ~nRESET | und | cond_failed_ex | swi | exception_ex;wire no_flags = ~nRESET | und | cond_failed_ex | swi;//Determine which flags from ALU to usealways @(alu_opcode or alu_flags or shift_c_out or CPSR)    begin	case (alu_opcode)	//synopsys full_case parallel_case	    `AND, `EOR, `TST, `TEQ,	    `ORR, `MOV, `BIC, `MVN:                     flags_from_alu = {alu_flags[3:2],shift_c_out,CPSR[28]};	    default: flags_from_alu = alu_flags;	endcase    end//Mux the Flags known earlyalways @(alu or s or rd_pc or ldm or alu_opcode or r15_inlist or alu	  or msr or shifted_op2 or current_spsr or flags_from_alu	  or CPSR)    begin	case ({(alu & s & !rd_pc), 	       ((ldm & alu_opcode[1] & r15_inlist) | (alu & s & rd_pc)),	       (msr & !alu_opcode[1])}) //synopsys full_case parallel_case	    3'b001: early_flags = shifted_op2[31:28];	    3'b010: early_flags = current_spsr[31:28];	    3'b100: early_flags = flags_from_alu;	   default: early_flags = CPSR[31:28];	endcase    end//Mux the Flags to the D-Input to CPSRalways @(multiply or s or hold_next_ex or mult_flags 	  or CPSR or early_flags 	  or inst_exception or nRESET or cpsr_const)    begin        if (~nRESET | inst_exception)            next_cpsr[31:28] = cpsr_const[31:28];	else if (multiply & s & !hold_next_ex)	    next_cpsr[31:28] = {mult_flags,CPSR[29:28]};	else	    next_cpsr[31:28] = early_flags;    end//Set up a Mux for modifying only the flags, or the//entire SPSR using shifted_op2 as a sourcealways @(Rn_ex or shifted_op2 or current_spsr)     begin	case (Rn_ex[0]) //synopsys full_case parallel_case	    1'b0: flg_all_spsr <= {shifted_op2[31:28],current_spsr[27:0]};	    1'b1: flg_all_spsr <= shifted_op2;	endcase    end//Set up the next SPSR Value. Only Modified by MSR instructions//or exceptions.always @(CPSR or msr or nRESET or mode or alu_opcode or und	    or current_spsr or cond_failed_ex or shifted_op2 	    or spsr_index or latched_nRESET or flg_all_spsr 	    or swi or exception_ex or exc_code_ex)    begin	if ((!nRESET & latched_nRESET) | swi)	  begin	    next_spsr <= CPSR;	    write_spsr_index <= 3'h1;	//spsr_svc	  end	else if (exception_ex)	  begin	    case (exc_code_ex) //synopsys full_case parallel_case		2'b00: begin			next_spsr <= CPSR;			write_spsr_index <= 3'h2;		       end		2'b01: begin			next_spsr <= CPSR;			write_spsr_index <= 3'h0;		       end		2'b10: begin			next_spsr <= CPSR;			write_spsr_index <= 3'h3;		       end		2'b11: begin			next_spsr <= CPSR;			write_spsr_index <= 3'h2;		       end	    endcase		  end	else if (und)	  begin	    next_spsr <= CPSR;	    write_spsr_index <= 3'h4;	//spsr_und	  end        else if (msr && (mode != `USR) && (mode != `SYS)                         && !cond_failed_ex && alu_opcode[1])	  begin	    next_spsr <= flg_all_spsr;	    write_spsr_index <= spsr_index;	  end	else	  begin	    next_spsr <= current_spsr;	    write_spsr_index <= spsr_index;	  end    end		//Mux the SPSR/CPSR for MRS Instructions//For MRS instructions ir[22]=0 for CPSR, ir[22]=1 for SPSR//ir[22] = alu_opcode[1].always @(CPSR or alu_opcode or current_spsr)    begin	if (!alu_opcode[1])			//Use CPSR	    psr <= CPSR;	else					//Use SPSR	    psr <= current_spsr;		//If no SPSR, current_spsr    end						//will be the CPSR//Create the Incrementwire iabort = exception_ex & (exc_code_ex == 2'h3);wire dabort = exception_ex & (exc_code_ex == 2'h0);always @(mul_first_ex or double_me or alu_opcode or ldm or stm 		or branch or cop_mem_ex or inst_exception 		or op2 or iabort or dabort)    begin	casex ({(inst_exception | branch | iabort | dabort), (ldm | stm), 		mul_first_ex, double_me, cop_mem_ex, 		alu_opcode[3:2]}) //synopsys full_case parallel_case	    //Must Decrement PC by 4 for exceptions/BL	    7'b1??????: increment = {5'b11111,~dabort,2'h0};	    //Must Increment Op1 by 4 for COP/Pre-Inc/Auto-Inc	    7'b????1??,	    7'b??1??11,	    7'b?100???: increment = 8'h04;	    //For LDM/STM Pre-Decrement, Just want Op2	    //For LDM/STM Post-Decrement, Want Op2 + 4            7'b??1??00, 	    7'b??1??10: increment =~(op2[7:0])+{5'h00,~alu_opcode[3],2'h0} + 1;	    //Must Increment addr by 8 for LDM/STM of two words	    7'b?101???: increment = 8'h08;		    default:    increment = 8'h00;	endcase    end//Mux the address to be incrementedalways @(op1 or mul_first_ex or branch or addr_me or und or swi or		exception_ex)    begin	if (und | swi | branch | mul_first_ex | exception_ex)	    addr_2b_inc = op1;	else	    addr_2b_inc = addr_me;    end//Mux the Mult/ALU resultsalways @(str or alu_result or op2 or mrs or psr or mcr_ex or 		stm or aux_data_ex or swap or inst_exception)    begin	if ((stm) | str | swap)			//STORE            ex_result = aux_data_ex;	else if (inst_exception | mcr_ex)	//UND/SWI            ex_result = op2;        else if (mrs)				//MRS            ex_result = psr;        else					//ALU/MULT            ex_result = alu_result;    end//Mux the Store Addralways @(ldm or stm or branch or cop_mem_ex or ldc_stc or		ex_enbar or inc_add or alu_result or op1 or alu_opcode)    begin 	if (ldm || stm || (cop_mem_ex & ldc_stc & !ex_enbar))	    store_addr <= inc_add;       	//Auto-Inc'd Addr	else if (alu_opcode[3])			//Pre Indexed	    store_addr <= alu_result;	else					//Post Indexed	    store_addr <= op1;    end//Mux the Base Addralways @(multiply or mult_result or stm or mul_first_ex or inst_exception		or op1 or alu_result or inc_add or branch or exception_ex)    begin	if (branch | inst_exception | exception_ex)	//PC + 8 - 4	    base_ex <= inc_add;	else if (multiply)                   	//Upperhalf of MULL result	    base_ex <= mult_result[63:32];	else if (stm & !mul_first_ex)		//STM Data	    base_ex <= op1;	else					//Updated Base Value	    base_ex <= alu_result;    end//Mux the opcode to the alu.  If LD/St instruction,//Opcode becomes add or subtract, depending on the U bit.//ADD=0100, SUB=0010, Opcode is 0100 for Branch since//PC offset is 2sCalways @(ldr or str or alu_opcode or u or branch or ldm or stm		or cop_mem_ex or swap or multiply)    begin	if (ldr | str | swap | ldm | stm | cop_mem_ex)            opcode <= {1'b0,u,~u,1'b0};	//ADD/SUB	else if (branch | multiply)	    opcode <= 4'h4;	//ADD	else	    opcode <= alu_opcode;    end//Mux the outgoing mode of processor.  This is necessary because//a mode change does not take place until the instruction enters the//ME stage.  By this time, the previous instruction will have decoded//and used the wrong set of registers.  Therefore, mode must be//forwarded to the ID stage for instructions that change the mode.assign mode = (~cpsr_disable) ? next_cpsr[4:0] : CPSR[4:0];	 /*------------------------------------------------------------------------        Sequential Logic Blocks------------------------------------------------------------------------*/	//This block controls the was_disabled bit.  //Its there because the CPSR and SPSR registers must//be disabled for one cycle longer than the input registers//of the ex stage//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET)    begin	if (~nRESET)	    was_disabled <= 1'b0;	else if (nWAIT)	    was_disabled <= ex_enbar & ~hold_next_ex;    end//This block controls the Op1 latch//If an instruction requires 2 cycles, OP1 is only//latched on the second cycle if the inst is an MLA/MLALwire op_disable = ~(~ex_enbar & (~id_second | (multiply & acc)));//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET)  begin    if (~nRESET)      op1 <= 32'h00000000;    else if (nWAIT)      begin	if (~op_disable)          op1 <= op1_in;      end  end//This block controls the Op2 latch//If an instruction requires 2 cycles, OP2 is only

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -