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

📄 alu.v

📁 一个支持精简指令的16位的risc cpu
💻 V
字号:
 //Operations:
//   3'b100: C3 = A not B\
//   3'b101: C3 = A OR  B | logic instructions
//   3'b110: C3 = A AND B/

//   3'b000: C3 = A <<  B   \   
//   3'b010: C3 = A >>  B   | shift  
//   3'b001: C3 = A ASR B   | instructions   
                               
//   3'b011: C3 = A + B     \ arithmetic 
//   3'b111: C3 = A - B     | instructions    

module alu (C3_BUS, A_BUS, B_BUS, ALU_OPCODE,CP, WORK_EX);
output [15:0] C3_BUS;         // result bus
//output	zero; 
input  [15:0] A_BUS,          // operand bus A   
              B_BUS;          // operand bus B                         
input  [ 2:0] ALU_OPCODE;     // opcode    
input         CP,             // processor clock 
              WORK_EX;        // work enable

reg    [15:0] C3_BUS;         // result
//reg	zero;
wire   [15:0] A_BUS,          // operand bus A     
              B_BUS;          // operand bus B    
wire   [ 2:0] ALU_OPCODE;     // opcode        
wire          CP,             // processor clock        
              WORK_EX;        // work enable
    
reg    [15:0] ALU_AREG,       // operand register A     
              ALU_BREG;       // operand register B       
reg    [ 2:0] ALU_OREG;       // opcode register    
wire   [15:0] ARITH_RES,      // result of ARITHMETIC  
              LOGIC_RES,      // result of LOGIC  
              SHIFT_RES;      // result of SHIFT 

arithmetic ARITHMETIC (ARITH_RES, ALU_AREG, ALU_BREG, ALU_OREG);
                        
logic LOGIC (LOGIC_RES, ALU_AREG, ALU_BREG, ALU_OREG);

shift SHIFT (SHIFT_RES, ALU_AREG, ALU_BREG[4:0], ALU_OREG); 

// Read inputs with rising clock edge,                    
// if work enable                                                              
     
always @(posedge CP)
begin                                                     
    if (WORK_EX) 
	begin                               
        ALU_AREG =  A_BUS;                                                
        ALU_BREG =  B_BUS;                                                
        ALU_OREG =  ALU_OPCODE; 
	//zero = (| LOGIC_RES ) || (| SHIFT_RES ) || (| ARITH_RES );
   	end                                                                          
end 

always @(ARITH_RES or LOGIC_RES or SHIFT_RES or ALU_OREG) 
begin                
    casex(ALU_OREG[2:0])                                                          
      3'b10x: C3_BUS = LOGIC_RES;           // logic operations 
      3'b110: C3_BUS = LOGIC_RES;           // logic operations                   
      3'b00x: C3_BUS = SHIFT_RES;           // shift operations  
      3'b010: C3_BUS = SHIFT_RES;           // shift operations                 
      3'bx11: C3_BUS = ARITH_RES;           // arithmetic operations              
    endcase
end

endmodule 






// arithmetic: execution of arithmetic operations           
//                                                                               
// Operations:                                                                   
//   3'b011: RESULT = A_IN + B_IN         
//   3'b111: RESULT = A_IN - B_IN                                                 
module arithmetic ( RESULT,A_IN, B_IN, OP_IN);                                  
                                                                                 
output [15:0] RESULT;         // output result                                 
input  [15:0] A_IN,           // input operand A            
              B_IN;           // input operand B                               
input  [2:0]  OP_IN;          // input opcode                                  
reg    [15:0] RESULT;         // result                                        
wire   [15:0] A_IN,           // operand A  
              B_IN;           // operand B         
wire   [2:0]  OP_IN;          // opcode                                        
reg    [15:0] B_EFF;          // operand B to be added effectively
             
always @(B_IN or OP_IN)                                                        
    B_EFF = B_IN ^ {16{OP_IN[2]}};
                                          
always @(A_IN or B_EFF or OP_IN[2])                                               
    RESULT = A_IN + B_EFF + OP_IN[2];
  
endmodule // arithmetic                                                          




                                                                              
// logic: execution of logic operations      
//                                                                               
// Operations:                                                                   
//   3'b101: RESULT = A AND B              
//   3'b110: RESULT = A OR  B                                                     
//   3'b100: RESULT =  not B           
//                                                                               
//----------------------------------------------------------------------------   
                                                                                 
module logic (RESULT,A_IN, B_IN, OP_IN);      
                                                                                 
output [15:0] RESULT;         // output result          
input  [15:0] A_IN,           // input operand A                               
              B_IN;           // input operand B                               
input  [ 2:0] OP_IN;          // input opcode                    
reg    [15:0] RESULT;         // result                                        
wire   [15:0] A_IN,           // operand A                                     
              B_IN;           // operand B                                     
wire   [2:0]  OP_IN;          // opcode      
//wire   [15:0] result;

//assign  result = RESULT;
//assign  result = ~A_IN ;                               
                                                                                 
always @(A_IN or B_IN or OP_IN) 
begin                                          
    case(OP_IN)                                                                  
      3'b101: RESULT = A_IN & B_IN;   // AND                                      
      3'b110: RESULT = A_IN | B_IN;   // OR                                       
    endcase              
end                                                                            
                                                                                 
endmodule // logic                                                               
                       

    
                                                                                 
//----------------------------------------------------------------------------   
//                                                                               
// shift: execute shift operations                                               
//                                                                               
// Operations:                                                                   
//   3'b000: RESULT = A <<  B    left shift   
//   3'b010: RESULT = A >>  B    right shift                                      
//   3'b001: RESULT = A ASR B    right shift (sign maintaining)           
        
module shift (RESULT,A_IN, B_IN, OP_IN);                                 
                                                                                 
output [15:0] RESULT;         // output result                                 
input  [15:0] A_IN;           // input operand A     
input  [ 4:0] B_IN;           // input operand B                               
input  [ 2:0] OP_IN;          // input opcode                                  
                                                                                 
reg    [15:0] RESULT;         // result
reg	[15:0] SIGN_mask;                                       
wire   [15:0] A_IN;           // operand A                                     
wire   [ 4:0] B_IN;           // operand B                                     
wire   [ 2:0] OP_IN;          // opcode     

always @ (A_IN or B_IN or OP_IN)
begin
	if(OP_IN == 3'b000)
	  RESULT <= A_IN << B_IN;
	else if(OP_IN == 3'b010)
	  RESULT <= A_IN >> B_IN;
	else if(OP_IN == 3'b001)
	 begin
		SIGN_mask <= ~({16{A_IN[15]}} >> B_IN);
		RESULT <= SIGN_mask | A_IN;
	 end
end

endmodule

⌨️ 快捷键说明

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