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

📄 alu.v

📁 使用CPLD仿真8051核,内有源程序和说明,来之不易
💻 V
字号:
//////////////////////////////////////////////////////////////////////
//// 								  ////
//// alu for 8051 Core 						  ////
//// 								  ////
//// This file is part of the 8051 cores project 		  ////
//// http://www.opencores.org/cores/8051/ 			  ////
//// 								  ////
//// Description 						  ////
//// Implementation of aritmetic unit  according to 		  ////
//// 8051 IP core specification document. Uses divide.v and 	  ////
//// multiply.v							  ////
//// 								  ////
//// To Do: 							  ////
////  pc signed add                                               ////
//// 								  ////
//// Author(s): 						  ////
//// - Simon Teran, simont@opencores.org 			  ////
//// 								  ////
//////////////////////////////////////////////////////////////////////
//// 								  ////
//// Copyright (C) 2001 Authors and OPENCORES.ORG 		  ////
//// 								  ////
//// This source file may be used and distributed without 	  ////
//// restriction provided that this copyright statement is not 	  ////
//// removed from the file and that any derivative work contains  ////
//// the original copyright notice and the associated disclaimer. ////
//// 								  ////
//// This source file is free software; you can redistribute it   ////
//// and/or modify it under the terms of the GNU Lesser General   ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any   ////
//// later version. 						  ////
//// 								  ////
//// This source is distributed in the hope that it will be 	  ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 	  ////
//// PURPOSE. See the GNU Lesser General Public License for more  ////
//// details. 							  ////
//// 								  ////
//// You should have received a copy of the GNU Lesser General 	  ////
//// Public License along with this source; if not, download it   ////
//// from http://www.opencores.org/lgpl.shtml 			  ////
//// 								  ////
//////////////////////////////////////////////////////////////////////
//
// ver: 1
//


module alu (op_code, src1, src2, src3, srcCy, srcAc, des1, des2, desCy, desAc, desOv, bit_in);

input srcCy, srcAc, bit_in; input [3:0] op_code; input [7:0] src1, src2, src3;
output des1, des2, desCy, desAc, desOv;

  reg desCy, desAc, desOv;
  reg [7:0] des1, des2;
//
//add
//
  reg [4:0] add1, add2, add3, add4; reg [3:0] add5, add6, add7, add8; reg [1:0] add9, adda, addb, addc;

//
//sub
//
  reg [4:0] sub1, sub2, sub3, sub4; reg [3:0] sub5, sub6, sub7, sub8; reg [1:0] sub9, suba, subb, subc;

//
//mul
//
  wire [7:0] mulsrc1, mulsrc2;
  wire mulOv;

//
//div
//
wire [7:0] divsrc1,divsrc2;
wire divOv;

//
//da
//
reg [8:0] da1;

multiply mul1(.src1(src1), .src2(src2), .des1(mulsrc1), .des2(mulsrc2), .desOv(mulOv));
divide div1(.src1(src1), .src2(src2), .des1(divsrc1), .des2(divsrc2), .desOv(divOv));

always @(op_code or src1 or src2 or srcCy or srcAc or bit_in or src3)
begin

  case (op_code)
//operation add
    `ALU_ADD: begin
      add1= {1'b0,src1[3:0]};
      add2= {1'b0,src2[3:0]};
      add3= {3'b000,srcCy};
      add4= add1+add2+add3;

      add5={1'b0,src1[6:4]};
      add6={1'b0,src2[6:4]};
      add7={1'b0,1'b0,1'b0,add4[4]};
      add8=add5+add6+add7;

      add9={1'b0,src1[7]};
      adda={1'b0,src2[7]};
      addb={1'b0,add8[3]};
      addc=add9+adda+addb;

      des1={addc[0],add8[2:0],add4[3:0]};
      des2=src3+addc[1];  ///ti , tole se ni uredu...
      desCy=addc[1];
      desAc=add4[4];
      desOv=addc[1] ^ add8[3];

    end
//operation subtract
    `ALU_SUB: begin

      sub1={1'b1,src1[3:0]};
      sub2={1'b0,src2[3:0]};
      sub3={1'b0,1'b0,1'b0,srcCy};
      sub4=sub1-sub2-sub3;

      sub5={1'b1,src1[6:4]};
      sub6={1'b0,src2[6:4]};
      sub7={1'b0,1'b0,1'b0, !sub4[4]};
      sub8=sub5-sub6-sub7;

      sub9={1'b1,src1[7]};
      suba={1'b0,src2[7]};
      subb={1'b0,!sub8[3]};
      subc=sub9-suba-subb;

      des1={subc[0],sub8[2:0],sub4[3:0]};
      des2=8'bxxxx_xxxx;
      desCy=!subc[1];
      desAc=!sub4[4];
      desOv=!subc[1] ^ sub8[3];

    end
//operation multiply
    `ALU_MUL: begin
      des1=mulsrc2;
      des2=mulsrc1;
      desOv = mulOv;
      desCy = 1'b0;
      desAc = 1'bx;
    end
//operation divide
    `ALU_DIV: begin
      des1=divsrc2;
      des2=divsrc1;
      desOv=divOv;
      desAc=1'bx;
      desCy=1'b0;
    end
//operation decimal adjustment
    `ALU_DA: begin
      da1= {1'b0, src1};
      if (srcAc==1'b1 | da1[3:0]>4'b1001) da1= da1+ 9'b0_0000_0110;

      da1[8]= da1[8] | srcCy;

      if (da1[8]==1'b1) da1=da1+ 9'b0_0110_0000;
      des1=da1[7:0];
      des2=8'bxxxx_xxxx;
      desCy=da1[8];
      desAc=1'bx;
      desOv=1'bx;
    end
//operation not
// bit operation not
    `ALU_NOT: begin
      des1 = ~src1;
      des2=8'bxxxx_xxxx;
      desCy=!srcCy;
      desAc=1'bx;
      desOv=1'bx;
    end
//operation and
//bit operation and
    `ALU_AND: begin
      des1 = src1 & src2;
      des2=8'bxxxx_xxxx;
      desCy= srcCy & bit_in;
      desAc=1'bx;
      desOv=1'bx;
    end
//operation xor
// bit operation xor
    `ALU_XOR: begin
      des1 = src1 ^ src2;
      des2=8'bxxxx_xxxx;
      desCy= srcCy ^ bit_in;
      desAc=1'bx;
      desOv=1'bx;
    end
//operation or
// bit operation or
    `ALU_OR: begin
      des1 = src1 | src2;
      des2=8'bxxxx_xxxx;
      desCy= srcCy | bit_in;
      desAc=1'bx;
      desOv=1'bx;
    end
//operation rotate left
// bit operation cy= cy or (not ram)
    `ALU_RL: begin
      des1 = {src1[6:0], src1[7]};
      des2=8'bxxxx_xxxx;
      desCy= srcCy | !bit_in;
      desAc=1'bx;
      desOv=1'bx;
    end
//operation rotate left with carry and swap nibbles
    `ALU_RLC: begin
      des1 = {src1[6:0], srcCy};
      des2= {src1[3:0], src1[7:4]};
      desCy=src1[7];
      desAc=1'bx;
      desOv=1'bx;
    end
//operation rotate right
    `ALU_RR: begin
      des1 = {src1[0], src1[7:1]};
      des2=8'bxxxx_xxxx;
      desCy= srcCy & !bit_in;
      desAc=1'bx;
      desOv=1'bx;
    end
//operation rotate right with carry
    `ALU_RRC: begin
      des1 = {srcCy, src1[7:1]};
      des2=8'bxxxx_xxxx;
      desCy=src1[0];
      desAc=1'bx;
      desOv=1'bx;
    end
//operation pcs Add
    `ALU_PCS: begin
      {des1, des2}={src3,src2}+src1;
      desCy=1'bx;
      desAc=1'bx;
      desOv=1'bx;
    end
//operation exchange
//if carry = 0 exchange low order digit
    `ALU_XCH: begin
      if (srcCy)
      begin
        des1=src2;
        des2=src1;
      end else begin
        des1={src1[7:4],src2[3:0]};
        des2={src2[7:4],src1[3:0]};
      end
      desCy=1'bx;
      desAc=1'bx;
      desOv=1'bx;
    end
    default: begin
      des1=src1;
      des2=src2;
      desCy=srcCy;
      desAc=srcAc;
      desOv=1'bx;
    end
  endcase

end

//initial $monitor("time ",$time," sub1 ", sub1," sub2 ", sub2," sub3 ", sub3," sub4 ", sub4," sub5 ", sub5," sub6 ", sub6," sub7 ", sub7," sub8 ", sub8," sub9 ", sub9," suba ", suba," subb ", subb," subc ", subc, " des1 ",des1 );
//initial $monitor("time ",$time," des1 %h", des1, " src1 %h", src1, " src2 %h", src2, " alu_op ", op_code, " srcCy ", srcCy);


endmodule

⌨️ 快捷键说明

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