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

📄 arm10.v

📁 arm10_verilog.rar是基于arm10的verilog代码
💻 V
📖 第 1 页 / 共 5 页
字号:
				end			    end			end		    end		end	    end	endtask	//Software Interrupts (SWI)	task swi;		     begin		//Store next Instruction (PC = PC+4)		inst_result[0] = r15;		result_dest[0] = 5'h18;		result_valid[0] = 1'b1;		//Store the CPSR in SPSR_svc		psr_result[0] = CPSR;		psr_dest[0] = 3'h2;		psr_valid[0] = 1'b1;		//Set SVC Mode and disable IRQ		psr_result[1] = {PSR0[31:8],1'b1,PSR0[6],6'b010011};		psr_dest[1] = 3'h0;		psr_valid[1] = 1'b1;		//Set the PC to the SWI Vector		next_pc = 32'h00000008;		//Don't increment PC on next 		pc_touched = 1'b1;	    end	endtask	//Branch Instructions	task br;		    reg [31:0] twosC;		//2's Comp of Offset, if (-)	    reg [31:0] offset;		//holds the shifted, s-ext offset	    begin		offset = {{6{ir[23]}},ir[23:0],2'b00};				//Store PC if Link bit set		//Actually storing PC + 4		if (ir[24] == 1'b1)		  begin		    inst_result[0] = r15+4;		    result_dest[0] = map(4'hE);		    result_valid[0] = 1'b1;		  end		//Calculate offset (if negative) and 		//update the PC		if (offset[31] == 1'b1) begin		    twosC = ~(offset) + 1;		    next_pc = r15 - twosC + 8;		    pc_touched = 1'b1;		end		else begin		    next_pc = r15 + offset + 8;		    pc_touched = 1'b1;		end	    end	endtask			//Store Half-Word Instructions	task strh;			    reg [31:0] data;		//data to store	    reg [31:0] addr;		//address to store	    reg [31:0] base;		//address in base register	    reg [31:0] reg_offset;	//offset in register	    reg [31:0] temp;		//necessary for writing only					//a half word.  	    begin		data = reg_decode(map(Rd));		base = reg_decode(map(Rn));		reg_offset = reg_decode(map(Rm));		//Calculate the Destination Address		//Register Offset		if (ir[22] == 1'b0) begin		    if (ir[23] == 1'b1) 		//add offset			addr = base + reg_offset;		    else				//sub offset			addr = base - reg_offset;		end		//Immediate Offset		else begin		    if (ir[23] == 1'b1)			//add offset			addr = base + 				{{24{1'b0}},ir[11:8],ir[3:0]};		    else				//sub offset			addr = base -                                {{24{1'b0}},ir[11:8],ir[3:0]};		end			//perform the store		if (ir[24] == 1'b1)			//pre-index		begin		    addr_bus = addr;		    data_bus = {2{data[15:0]}};		end		else 					//post-index		begin		    addr_bus = base;		    data_bus = {2{data[15:0]}};		end					//Perform Write-back, if necessary		if ((ir[24] == 1'b0)||(ir[21] == 1'b1))		  begin		    inst_result[0] = addr;		    result_dest[0] = map(Rn);		    result_valid[0] = 1'b1;		  end		/*Simulate a Smart Memory System		  Problem with my memory is that its word-addressable		  This causes problems when trying to write only a 		  half-word, or byte.  To write a half word, I have 		  to read the memory location, overwrite the specified		  half-word, and then write the data.*/			temp = mem[addr_bus[31:2]];		case ({BIGEND,addr_bus[1]})			2'b00,2'b11:		//word boundary			    temp = {temp[31:16],data_bus[15:0]};			2'b01,2'b10:		//half-word boundary			    temp = {data_bus[31:16],temp[15:0]};		endcase		data_bus = temp;		$save_store();		    		mem[addr_bus[31:2]] = temp;	    end	endtask	//Store Single Data Instruction	task strw;		    reg [32:0] shifted_offset;	//holds shifted offset            reg [31:0] data;            //data to store            reg [31:0] addr;            //address to store	    reg [31:0] base;		//base address	    reg [31:0] reg_offset;	//offset value            reg [31:0] temp;		//necessary for byte-addressing            begin                data = reg_decode(map(Rd));        		//Read data8		base = reg_decode(map(Rn));		reg_offset = reg_decode(map(Rm));		//Read Offset		shifted_offset = shift(reg_offset);		//Shift Offset                //Calculate the Destination Address                //Shifted Register Offset                if (ir[25] == 1'b1) begin                    if (ir[23] == 1'b1)                 //add offset                        addr = base + shifted_offset[31:0];                       else                                //sub offset                        addr = base - shifted_offset[31:0];                end                //Immediate Offset                else begin                    if (ir[23] == 1'b1)                 //add offset                        addr = base + {{20{1'b0}},ir[11:0]};                            else                                //sub offset                          addr = base - {{20{1'b0}},ir[11:0]};                end                               //perform the store		case ({ir[24],ir[22]})		    //Post Indexing, Store Word		    2'b00: begin 			addr_bus = base;			data_bus = data;		    end		    //Post Indexing, Store Byte		    2'b01: begin			addr_bus = base;			data_bus = {4{data[7:0]}};		    end		    //Pre Indexing, Store Word		    2'b10: begin			addr_bus = addr;			data_bus = data;		    end		    //Pre Indexing, Store Byte		    2'b11: begin			addr_bus = addr;			data_bus = {4{data[7:0]}};		    end		endcase			                //Perform Write-back, if necessary                if ((ir[24] == 1'b0)||(ir[21] == 1'b1))		  begin		    inst_result[0] = addr;		    result_dest[0] = map(Rn);		    result_valid[0] = 1'b1;		  end		/*Simulate the Memory System		  I defined the memory system to be word 		  addressable, so to write a byte, first		  the data must be read from memory.  The		  correct byte must be overwritten, then		  the data written back.*/		temp = mem[addr_bus[31:2]];		if (ir[22] == 1'b0)	//store word		    temp = data_bus;		else begin		//store byte		    case ({BIGEND,addr_bus[1:0]})			3'b000,3'b111:				temp = {temp[31:8],data_bus[7:0]};			3'b001,3'b110:				temp = {temp[31:16],data_bus[15:8],temp[7:0]};			3'b010,3'b101:				temp = {temp[31:24],data_bus[23:16],temp[15:0]};			3'b011,3'b100:				temp = {data_bus[31:24],temp[23:0]};		    endcase		end			data_bus = temp;		$save_store();	    			    		mem[addr_bus[31:2]] = temp;            end        endtask	//Store Multiple Data Words	task stm;			    reg [31:0] low_addr;		//lowest address	    reg [31:0] high_addr;		//higest address	    reg [31:0] addr;			//store to address	    reg [3:0]  reg_index;		//Register index	    reg        pre_inc_addr;		//Pre-Increment	    integer inc_dec;			//holds +/- 4	    integer int_Rn;			//Integer equiv. of Rn	    integer i;					    integer j; 	begin	    low_addr = reg_decode(map(Rn));		//set Base Pointer	    high_addr = low_addr;		//initialize High Address	    reg_index = 4'h0;			//reset index	    int_Rn = Rn;			//set int_Rn to Rn	    //Increment or decrement	    if (ir[23] == 1'b1)			//Up?		inc_dec = 4;	    else				//Down?		inc_dec = -4;	    //Calculate High and Low Addresses                       for (i = 0; i <= 15; i = i+1) begin                if ((ir[i] == 1'b1) && (ir[23] == 1'b0))                    low_addr = low_addr + inc_dec;                if ((ir[i] == 1) && (ir[23] == 1'b1))                    high_addr = high_addr + inc_dec;            end		    //Initialize Store Address, Always store	    //From lowest address to Highest Address	    addr = low_addr;	    //If Pre-Inc or Post-Dec - Need to 	    //Increment Low Address before the store            if (((ir[24] == 1'b1) && (ir[23] == 1'b1))               ||((ir[24] == 1'b0) && (ir[23] == 1'b0)))	        addr = addr + 4;	    // Perform the store	    for (j = 0; j <= 15; j = j+1) begin                //Write-Back performed after First Store                //If Incrementing -> high_addr, else -> low_addr                if ((j == 1) && (ir[21] == 1))		  begin		    //leaving this write, because it is necessary to		    //write the base back.  Putting in the delay, so that		    //it will not screw up the checker.  Checker should 		    //not see this reg change until the next instruction.		    //Therefore, if the clock cycle changes length, 		    //the delay must be changed suitably.		    #75;		    write_reg(map(Rn),(ir[23] ? high_addr : low_addr));		   end		if (ir[j] == 1'b1) begin		    if (ir[22] == 1'b1)		      //only transfer USR bank registers		      begin			mem[addr[31:2]] = reg_decode({1'b0, reg_index});			addr_bus = addr;			data_bus = reg_decode({1'b0, reg_index});			$save_store();		      end	            else			//transfer <mode> registers		      begin			mem[addr[31:2]] = reg_decode(map(reg_index));			addr_bus = addr;			data_bus = reg_decode(map(reg_index));			$save_store();		      end                    //Increment address unless not supposed to                    if ((j != 15)||(ir[24] != 1'b1))                        addr = addr + 4;  		end		reg_index = reg_index + 1;	    end	end    endtask	//Load Multiple Data Words	task ldm;	    reg [31:0] low_addr;		//lowest load address	    reg [31:0] high_addr;		//highest address	    reg [31:0] addr;			//store address            reg [3:0]  reg_index;               //Register index	    reg        r15_set;			//R15 in list?            integer inc_dec;                    //holds +/- 4	    integer int_Rn;			//integer equiv. of Rn            integer i;            integer j;        begin            low_addr = reg_decode(map(Rn));		//set Base Pointer	    high_addr = low_addr;		//initialize high address	    addr = low_addr;			//initialize             reg_index = 4'h0;                   //reset index	    r15_set = ir[15];			      	    int_Rn = Rn;                   //Increment or decrement            if (ir[23] == 1'b1)                 //Up?                  inc_dec = 4;            else                                //Down?                inc_dec = -4;		    //Calculate the Highest & Lowest Addresses	    high_addr = low_addr;            for (i = 0; i <= 15; i = i+1) begin                if ((ir[i] == 1'b1) && (ir[23] == 1'b0))                    low_addr = low_addr + inc_dec;		if ((ir[i] == 1) && (ir[23] == 1'b1))		    high_addr = high_addr + inc_dec;            end                     //Initialize Store Address, Always store            //From lowest address to Highest Address            addr = low_addr;            //If Pre-Inc or Post-Dec - Need to            //Increment Low Address before the store            if (((ir[24] == 1'b1) && (ir[23] == 1'b1))               ||((ir[24] == 1'b0) && (ir[23] == 1'b0)))                addr = addr + 4;	    //Perform the Load Operation            for (j = 0; j <= 15; j = j+1) begin		//Write-Back performed after First Load		//If Incrementing -> high_addr, else -> low_addr 		if ((j == 1) && (ir[21] == 1))		  begin		    //leaving this write, because it is necessary to		    //write the base back.  Putting in the delay, so that		    //it will not screw up the checker.  Checker should 		    //not see this reg change until the next instruction.		    //Therefore, if the clock cycle changes length, 		    //the delay must be changed suitably.		    #75;		    write_reg(map(Rn),(ir[23] ? high_addr : low_addr));		  end                if (ir[j] == 1'b1) begin		    //IF S & R15, SPSR->CPSR		    if ((j == 15) && (ir[22] == 1))		      begin			psr_result[0] = psr_decode(mappsr(1'b1));			psr_dest[0] = 3'h0;			psr_valid[0] = 1'b1;		      end		    //IF S & !R15, Load to User Bank Registers	            if ((ir[22] == 1'b1)&&(r15_set == 1'b0))                        //only transfer USR bank registers		      begin			inst_result[j] = mem[addr[31:2]];			result_dest[j] = {1'b0, reg_index};			result_valid[j] = 1'b1;			data_bus = mem[addr[31:2]];			addr_bus = addr;		      end                    else                        //transfer <mode> registers		      begin			inst_result[j] = mem[addr[31:2]];			result_dest[j] = map(reg_index);			result_valid[j] = 1'b1;			data_bus = mem[addr[31:2]];			addr_bus = addr;		      end		    /

⌨️ 快捷键说明

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