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

📄 thumb_2_nnarm.v

📁 若干VHDL语言的源代码
💻 V
📖 第 1 页 / 共 2 页
字号:
                   		cti[7],cti[2:0],	//op1 and target
                   		8'b00000000,		//just extend
                   		cti[6],cti[5:3]};	//op2 
			//cmp
                   2'b01 : t2a <= {2'b00,		//always 00
                   		1'b0,			//op2 is a register
                   		4'b1010,		//cmp op
                   		1'b1,			//set condition code
                   		cti[7],cti[2:0],	//op1
                   		4'h0,			//no target
				8'h00,			//just extend
				cti[6],cti[5:3]};	//op2
			//mov
                   2'b10 : t2a <= {2'b00,		//always 00
                   		1'b0,			//op2 is register
                   		4'b1101,		//mov
                   		1'b0,			// do not set condition code
                   		4'b0000,		//no op1
                   		cti[7],cti[2:0],	//target 
                   		8'b00000000,		//just extend
                   		cti[6],cti[5:3]};	//op2 to move to target
			//bx
                   2'b11 : t2a <= {20'b0001_0010_1111_1111_1111,
                                     4'b0001,cti[6],cti[5:3]};
                 endcase
          
                            //\/\/\/\/\/\/\\

              else             //ALU Operations
               case(cti[9:6])
               	//lsl
                4'b0010 : t2a <= {13'b000_1101_1_0000_0,cti[2:0],1'b0 ,	//mov lsl
                              cti[5:3],1'b0,cti[8],cti[6],2'b10,cti[2:0]};
                //lsr
                4'b0011 : t2a <= {13'b000_1101_1_0000_0,cti[2:0],1'b0 ,	//mov lsr
                              cti[5:3],1'b0,cti[8],cti[6],2'b10,cti[2:0]};
                //asr
                4'b0100 : t2a <= {13'b000_1101_1_0000_0,cti[2:0],1'b0 ,	//mov asr
                              cti[5:3],1'b0,cti[8],cti[6],2'b10,cti[2:0]};
                //ror
                4'b0111 : t2a <= {13'b000_1101_1_0000_0,cti[2:0],1'b	0 ,	//mov ror
                              cti[5:3],1'b0,cti[8],cti[6],2'b10,cti[2:0]};
                //tst
                4'b1000 : t2a <= {9'b000_1000_1_0,cti[2:0],4'b0000    ,
                              9'b000000000,cti[5:3]                     };
                //neg
                4'b1001 : t2a <= {9'b001_0011_1_0,cti[5:3],1'b0       ,
                              cti[2:0],12'h000                          };
                //cmp
                4'b1010 : t2a <= {9'b000_1010_1_0,cti[2:0],4'b0000    ,	
                              9'b000000000,cti[5:3]                     };
                //cmn
                4'b1011 : t2a <= {9'b000_1011_1_0,cti[2:0],4'b0000    ,
                              9'b000000000,cti[5:3]                     };
                //mul
                4'b1101 : t2a <= {9'b000_0000_1_0,cti[2:0],5'b00000   ,
                              cti[2:0],5'b10010,cti[5:3]                };
                //mvn	
                4'b1111 : t2a <= {13'b000_1111_1_0000_0,cti[2:0]      ,
                     	         9'b00000000_0,cti[5:3]                    };
                //op code same as normal arm instruction
                default : t2a <= {3'b000,cti[9:6],2'b10,cti[2:0],1'b0 ,	
                              cti[2:0],9'b000000000,cti[5:3]            }; //Mian: AND,EOR,ADC,SBC,ORR,BIC
               endcase
            end 

                    //+++++++++++++++++++++//

   3'b011  : begin      // Load/Store with Immediate Offset    
             if(cti[12]==1'b1) //transfer byte
                t2a <= {2'b01,				//always 01
                	1'b0,				//offset is immediate
                	1'b1,				//pre index
                	1'b1,				//up , add offset to base
                	cti[12],			//byte or word
                	1'b0,				//no write back
                	cti[11],			//load or store
                	1'b0,cti[5:3]   ,		//base register
                        1'b0,cti[2:0],			//store source or load target
                        5'b00000,2'b00,cti[10:6]}; 	//offset
             else		//transfer word
                t2a <= {5'b01011,cti[12],1'b0,cti[11],1'b0,cti[5:3]   ,
                        1'b0,cti[2:0],5'b00000,cti[10:6],2'b00          };//same as byte access, but must shift offset left 2 bit because word align
             end

                    //+++++++++++++++++++++//

   3'b100  : begin  
              if(cti[12]==1'b0)  //SP-relative Load/Store 

                t2a <= {2'b01,			//always 01
                	1'b0,			//offset is immediate
                	1'b1,			//pre index
                	1'b1,			//up add offset
                	1'b0,			//word transfer
                	1'b0,			//no write back
                	cti[11],		//load or store
                	4'b1101,		//base is R13(SP)
                	1'b0,cti[10:8],		//store source or load target
                        2'b00,cti[7:0],2'b00};	//word offset
              else //Load/Store Halfword

                t2a <= {3'b000,			//always 000
                	2'b11,			//pre index and up add offset
                	1'b1,			//always 1
                	1'b0,			//no write back
                	cti[11],		//load or store
                	1'b0,cti[5:3],		//base register
                	1'b0,cti[2:0],		//store source or load target
                	2'b00,cti[10:9],	//high 4 bit of offset
                	4'b1011,		//unsigned half word
                	cti[8:6],1'b0  };	//low 4 bit of offset
             end

                    //+++++++++++++++++++++//

   3'b101  : begin          
              if(cti[12]==1'b1) 

                begin 
                  if(cti[10]==1'b1) //Push/Pop Registers 
                  
                   t2a <= {3'b100,		//multiple register transfer
                          (~cti[11]),	//when load(1) post index, store(0) pre index
                          cti[11],	//when load(1) up,when store(0) down
                          1'b0,		//do not load PSR
                          1'b1,		//write back
                          cti[11],	//load or store
			  4'b1101,	//base is SP
			  (cti[11] & cti[8]), //when load  PC is loaded from MEM depending upon PC/LR bit (cti[8])
                          (~cti[11] & cti[8]),//when Store LR is stored to   MEM depending upon PC/LR bit (cti[8])
			  6'b000000,cti[7:0]};
                  
                  
//changed in ver 0.2
/*
                    begin
                      if(cti[11]==1'b1)	//ldm
                        t2a <= {3'b100,		//multiple register transfer
                        	(~cti[11]),	//when load(1) post index, store(0) pre index
                        	cti[11],	//when load(1) up,when store(0) down
                        	1'b0,		//do not load PSR
                        	1'b1,		//write back
                        	cti[11],	//load or store
				4'b1101,	//base is SP
				cti[8],1'b0,6'b000000,cti[7:0]}; //if load top stack to PC?
                      else		//stm
                        t2a <= {3'b100,		//always 100 for multiple register transfer
                        	(~cti[11]),
                        	cti[11],
                        	2'b01,
                        	cti[11],
				4'b1101,
				1'b0,cti[8], 6'b000000,cti[7:0]}; //store as LR?
                    end
*/

                  else //Add Offset to Stack Pointer
                    t2a <= {2'b00,		//always 00 for data processing
                    		1'b1,		//offset is immediate
                    		1'b0,(~cti[7]),cti[7],1'b0,//add or sub
				1'b0,			//do not set condition code
				4'b1101,		//op1 is SP
				4'b1101,		//target is SP
				4'b1111,		//ror 30 bit equal to lsl 2 bit
				1'b0,cti[6:0]};		//offset
                end

              else //Load Address
              begin
                t2a <= {2'b00,			//always 00
                	1'b1,			// immediate
                	4'b0100,		//add op
                	1'b0,			//do not set condition code
                	2'b11,(~cti[11]),1'b1,	//PC or SP
                	1'b0,cti[10:8],		//target register
                        4'b1111,cti[7:0]}; 	//ror 30 bit equal to lsl 2 bit
                ClearBit1=1'b1;		//ssy add 2001 7 19
              end
            end

                    //+++++++++++++++++++++//

   3'b110  : begin         
              if(cti[12]==1'b1) 

                  begin
                   if(& cti[11:8]) //SWI
                     t2a <= {4'b1111,16'h0000,cti[7:0]    }     ;
                   else            //Conditional Branch
                     t2a <= {4'b1010,{16{cti[7]}},cti[7:0]}     ;// ? {15{cti[7]}},cti[7:1]
                                                                 //Mian: This is not true conversion to ARM. Because in 
                                                                 //ARM branches are Word Aligned i.e [1:0] == 00
                                                                 //But in Thumb branches are Halfword aligned i.e [0] == 0 
                                                                 //So when Branch inst executes in Thumb, use (offset << 1), instead
                                                                 //(offset << 2) as in ARM state.
                  end

              else
                  begin
                    if(cti[11]==1'b1) //Multiple Load 
                                      //changed in ver 0.2
                       t2a <= {6'b100010,wb_check,cti[11],1'b0 ,
                                    cti[10:8],8'h00,cti[7:0]        };//only when the base is not in the list, can you write back that register

//wb_check replaced following case changed in ver 0.2
/*
                     case(cti[10:8])
                      3'b000 : t2a <= {6'b100010,~cti[0],cti[11],1'b0 ,
                                       cti[10:8],8'h00,cti[7:0]        };
                      3'b001 : t2a <= {6'b100010,~cti[1],cti[11],1'b0 ,
                                       cti[10:8],8'h00,cti[7:0]        };
                      3'b010 : t2a <= {6'b100010,~cti[2],cti[11],1'b0 ,
                                       cti[10:8],8'h00,cti[7:0]        };
                      3'b011 : t2a <= {6'b100010,~cti[3],cti[11],1'b0 ,
                                       cti[10:8],8'h00,cti[7:0]        };
                      3'b100 : t2a <= {6'b100010,~cti[4],cti[11],1'b0 ,
                                       cti[10:8],8'h00,cti[7:0]        };
                      3'b101 : t2a <= {6'b100010,~cti[5],cti[11],1'b0 ,
                                       cti[10:8],8'h00,cti[7:0]        };
                      3'b110 : t2a <= {6'b100010,~cti[6],cti[11],1'b0 ,
                                       cti[10:8],8'h00,cti[7:0]        };
                      3'b111 : t2a <= {6'b100010,~cti[7],cti[11],1'b0 ,
                                       cti[10:8],8'h00,cti[7:0]        };
                     endcase
*/

                    else  //Multiple Store
                      t2a <= {6'b100010,1'b1,cti[11],1'b0,
                                   cti[10:8],8'h00,cti[7:0]};
                  end
               end
               
                    //+++++++++++++++++++++//


   3'b111  : begin   
              if(cti[12]==1'b1) //Long Branch =  NO Operation 
              begin
              	if(cti[11]==1'b0)	//the high 11 bits of offset
              	begin
                 t2a <= {28'b000_1101_0_0000_0000_00000_00_0_0000}; 
                                          //MOV r0,r0 i.e No Operation
                 Next_LongBranchWithLinkOff=cti[10:0];
                 Next_AddressOfFirstHalf={in_AddressGoWithInstruction[`AddressBusWidth-1:1],1'b1};	//indicate there is a valid long branch with link
                end
                else
                begin
                 t2a <= {4'b1011,2'b00,LongBranchWithLinkOff,cti[10:0]};//generate a bl with two 11bits offset, you must shift left 1 bit (not 2 bit as normal bl)to get real offset
                 Next_LongBranchWithLinkOff=LongBranchWithLinkOff;	//preserve the high bits because the later stage may not being able to go
                 Next_AddressOfFirstHalf=AddressOfFirstHalf;
                end
              end
              else //UnConditional Branch	
                 t2a <= {4'b1010,{13{cti[10]}},cti[10:0]} ;//?
                                                           //Mian: This is not true conversion to ARM. Because in 
                                                           //ARM branches are Word Aligned i.e [1:0] == 00
                                                           //But in Thumb branches are Halfword aligned i.e [0] == 0 
                                                           //So when Branch inst executes in Thumb, use (offset << 1), instead
                                                           //(offset << 2) as in ARM state.  
              end
               
                    //+++++++++++++++++++++//

   default : t2a <= {28'b000_1101_0_0000_0000_00000_00_0_0000}; //MOV R0,R0 


 endcase
	if(in_ChangePC==1'b1 || in_MEMChangePC==1'b1)
	begin
		Next_LongBranchWithLinkOff=11'b0000_0000_000;
		Next_AddressOfFirstHalf=`AddressBusZero;
	end
end
//-----------------------------------------------------------//
//                Joining The Condition and Opcode           // 
//-----------------------------------------------------------//

  assign arm_inst = {cond,t2a} ;

//ssy add 2001 7 20
always	@(posedge clock or negedge reset)
begin
	if(reset==1'b0)
	begin
		LongBranchWithLinkOff=11'b0000_0000_000;
		AddressOfFirstHalf=`AddressBusZero;
	end
	else
	begin
		LongBranchWithLinkOff=Next_LongBranchWithLinkOff;
		AddressOfFirstHalf=Next_AddressOfFirstHalf;
	end
end

endmodule

⌨️ 快捷键说明

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