📄 dw8051_alu.v
字号:
// $Id: DW8051_alu.v,v 1.1 1996/07/25 17:42:24 gina Exp $//------------------------------------------------------------------------------//// This confidential and proprietary software may be used only// as authorized by a licensing agreement from Synopsys Inc.// In the event of publication, the following notice is applicable://// (C) COPYRIGHT 1996 SYNOPSYS INC.// ALL RIGHTS RESERVED//// The entire notice above must be reproduced on all authorized// copies.//// FILE: DW8051_alu.v//// AUTHOR: Ludwig Rieder//// ABSTRACT: DW8051 arithmetic logic unit (Verilog version)//// MODIFICATION HISTORY:// L.Rieder 28.05.96 Verilog version created//// Gina Ngo 11.20.96 Fixed star 38722: added header// Bala Needamangalam// May 20,98 Converted GTECH instantiations to HDL.// July 20,1999 Removed all DesignWare-Foundation // license checkout commands.//------------------------------------------------------------------------------`include "./DW8051/DW8051_package.inc"`include "./DW8051/DW8051_parameter.v"module DW8051_alu (clk, a, // a input b, // b input c, // c input ci, // carry in (CY) aci, // aux carry in (AC) ovi, // overflow in (CY) res, // result c_res, // result from input c co, // carry out (CY) aco, // aux carry out(AC) ovo, // overflow out (OV) zero, // result zero equal, // a=b bit_sts, // status of sel. bit bit_pos, // bit position (bit op) alu_op // alu operation ); input clk; input [7:0] a; input [7:0] b; input [7:0] c; input ci; input aci; input ovi; output [7:0] res; output [7:0] c_res; output co; output aco; output ovo; output zero; output equal; output bit_sts; input [2:0] bit_pos; input [5:0] alu_op;//------------------------------------------------------------------------------// DESCRIPTION//------------------------------------------------------------------------------//// alu_op codes://// bit 5 4 3 2 1 0 Operation// ------------------------------------------------// 0 0 0 0 0 0 Transparent// 0 0 0 0 0 1// 0 0 0 0 1 0 CPL// 0 0 0 0 1 1// 0 0 0 1 0 0 DA// 0 0 0 1 0 1// 0 0 0 1 1 0 SWAP// 0 0 0 1 1 1// 0 0 1 0 0 0 CLR// 0 0 1 0 0 1// 0 0 1 0 1 0 ANL// 0 0 1 0 1 1// 0 0 1 1 0 0 ORL// 0 0 1 1 0 1// 0 0 1 1 1 0 XRL// 0 0 1 1 1 1// 0 1 0 0 0 0 INC// 0 1 0 0 0 1 DEC// 0 1 0 0 1 0 CMP// 0 1 0 0 1 1// 0 1 0 1 0 0 ADD// 0 1 0 1 0 1 ADDC// 0 1 0 1 1 0 SUB// 0 1 0 1 1 1 SUBB// 0 1 1 0 0 0 RL// 0 1 1 0 0 1 RLC// 0 1 1 0 1 0 RR// 0 1 1 0 1 1 RRC// 0 1 1 1 0 0 MUL (based on ADD)// 0 1 1 1 0 1// 0 1 1 1 1 0 DIV (based on SUB)// 0 1 1 1 1 1 DIV shift right// --------------------// 1 x 0 0 0 0 CLR C// 1 x 0 0 0 1 CLR bit// 1 x 0 0 1 0 SETB C// 1 x 0 0 1 1 SETB bit// 1 x 0 1 0 0 CPL C// 1 x 0 1 0 1 CPL bit// 1 x 0 1 1 0 ANL C,bit// 1 x 0 1 1 1 ANL C,/bit// 1 x 1 x 0 0 ORL C,bit// 1 x 1 x 0 1 ORL C,/bit// 1 x 1 x 1 0 MOV C,bit// 1 x 1 x 1 1 MOV bit,C////------------------------------------------------------------------------------wire clk;wire [7:0] a;wire [7:0] b;wire [7:0] c;wire ci;wire aci;wire ovi;wire [2:0] bit_pos;wire [5:0] alu_op;wire [7:0] res;reg [7:0] c_res;wire co;wire aco;wire ovo;wire zero;wire equal;wire bit_sts;//---------------// local signals://---------------wire alu_op0_n; wire [7:0] cpl_res;wire cpl_ac;wire cpl_co;wire cpl_ov; wire [7:0] da_res;wire da_ac;wire da_co;wire da_ov;wire da_greater9_l;wire da_add_06;wire da_add_60;wire da_greater9_h;wire da_12,da_56;wire [7:0] da_add_0;wire [3:0] da_add_1;wire [8:0] da_carry_0;wire [4:0] da_carry_1;wire [7:0] da_add_res_0;wire [3:0] da_add_res_1; wire [7:0] swap_res;wire swap_ac;wire swap_co;wire swap_ov; wire [7:0] clr_res;wire clr_ac;wire clr_co;wire clr_ov; wire [7:0] anl_res;wire anl_ac;wire anl_co;wire anl_ov; wire [7:0] orl_res;wire orl_ac;wire orl_co;wire orl_ov; wire [7:0] xrl_res;wire xrl_ac;wire xrl_co;wire xrl_ov; // wire for adder/subtractor (ADD,ADDC,SUBB):wire as_ci;wire as_carry0;wire [8:0] asid_carry;wire [7:0] as_a; // a for add, not a for subwire [7:0] as_b; // B for add, not B for subwire [7:0] asid_a;wire [7:0] asid_b;wire [7:0] asid_res;wire as_ac;wire as_co;wire as_ov; wire [7:0] aeqb;wire [7:0] lt1;wire [7:0] lt2;wire [8:0] lt;wire cmp_ac;wire cmp_co;wire cmp_ov; wire [7:0] mul_res;wire [7:0] mul_c_res;wire mul_ac;wire mul_co;wire mul_ov_l;wire mul_ov_h;wire mul_ov; wire [8:0] div_t_res;wire [7:0] div_res;reg div_res8;wire div_res8_n;wire [7:0] div_c_res;wire div_ac;wire div_co;wire div_ov_l;wire div_ov_h;wire div_ov; wire [7:0] rl_res;wire rl_ac;wire rl_co;wire rl_ov; wire [7:0] rr_res;wire rr_ac;wire rr_co;wire rr_ov; reg [7:0] lo_res;reg [7:0] hi_res;reg lo_ac;reg hi_ac;reg lo_co;reg hi_co;reg lo_ov;reg hi_ov;wire [7:0] arith_res;wire arith_ac;wire arith_ov;wire arith_co; wire bit_pos_0n;wire bit_pos_1n;wire bit_pos_2n;wire [7:0] bit_mask;reg sel_bit; // selected bitwire mod_bit; // modified bitreg mod_bit_l;reg mod_bit_h;wire bit_co;reg bit_co_l;reg bit_co_h;wire [7:0] bit_res; // result of bit op wire clrc_co;wire clrc_bit;wire clrb_co;wire clrb_bit;wire setbc_co;wire setbc_bit;wire setbb_co;wire setbb_bit;wire cplc_co;wire cplc_bit;wire cplb_co;wire cplb_bit;wire anlcb_co;wire anlcb_bit;wire anlcbn_co;wire anlcbn_bit;wire orlcb_co;wire orlcb_bit;wire orlcbn_co;wire orlcbn_bit;wire movcb_co;wire movcb_bit;wire movbc_co;wire movbc_bit; wire [7:0] tmp_res; wire [7:0] bit_co_vector_l;wire [3:0] bit_co_vector_h;wire [7:0] mod_bit_vector_l;wire [3:0] mod_bit_vector_h;wire [7:0] ac_vector_l;wire [7:0] ac_vector_h;wire [7:0] co_vector_l;wire [7:0] co_vector_h;wire [7:0] ov_vector_l;wire [7:0] ov_vector_h;//------------------------------------------------------------------------------// alu_op inversions needed later:assign alu_op0_n = ~alu_op[0];//-----// CPL://----- assign cpl_res = ~a; assign cpl_ac = aci; // no flags affected: assign cpl_co = ci; assign cpl_ov = ovi;//----// DA://---- // Straight implementation of the DA instruction description // in the Intel 8051 User's Manual. assign {da_carry_0[8],da_add_res_0[7:0]} = ((a[3:0] > 9) || (aci == 1)) ? (a[7:0] + 8'h06) : a[7:0]; assign {da_carry_1[4],da_add_res_1[3:0]} = ((ci == 1) || (da_add_res_0[7:4] > 9) || (da_carry_0[8] == 1)) ? (da_add_res_0[7:4] + 4'h6): da_add_res_0[7:4]; assign da_res = {da_add_res_1[3:0], da_add_res_0[3:0]}; // flags: co affected, ac,ov not affected: assign da_ac = aci; assign da_co = ci | da_carry_0[8] | da_carry_1[4] ; assign da_ov = ovi;//------// SWAP://------ assign swap_res[3:0] = a[7:4]; assign swap_res[7:4] = a[3:0]; // no flags affected: assign swap_ac = aci; assign swap_co = ci; assign swap_ov = ovi;//-----// CLR://----- assign clr_res = 'b0; // no flags affected: assign clr_ac = aci; assign clr_co = ci; assign clr_ov = ovi;//-----------// ANL (AND)://----------- assign anl_res = a & b; // no flags affected: assign anl_ac = aci; assign anl_co = ci; assign anl_ov = ovi;//----------// ORL (OR)://---------- assign orl_res = a | b; // no flags affected: assign orl_ac = aci; assign orl_co = ci; assign orl_ov = ovi;//-----------// XRL (XOR)://----------- assign xrl_res = a ^ b; // no flags affected: assign xrl_ac = aci; assign xrl_co = ci; assign xrl_ov = ovi;//-----------------------------------------// ADD,ADDC,SUBB,INC and DEC is implemented// as a mix of DW01_addsub(rpl) and// DW01_incdec(rpl)://----------------------------------------- // alu_op(0) determines if addition with/without carry: assign as_ci = ci & alu_op[0]; // alu_op(1) determines if addition/subtraction: assign as_carry0 = as_ci ^ alu_op[1]; // if (inc/dec) then asid_carry=1(inc), asid_carry=0(dec) // else asid_carry=as_carry assign asid_carry[0] = (alu_op[2]) ? as_carry0 : alu_op0_n; // ci is active high // asid_carry is active low inside carry chain for subtraction // asid_carry is active high inside carry chain for addition assign as_a = {alu_op[1],alu_op[1],alu_op[1],alu_op[1], alu_op[1],alu_op[1],alu_op[1],alu_op[1]} ^ a ; assign asid_a = (alu_op[2]) ? as_a : a; assign asid_b = (alu_op[2] )? b : ({alu_op[0],alu_op[0], alu_op[0],alu_op[0], alu_op[0],alu_op[0], alu_op[0],alu_op[0]}); assign {asid_carry[4],asid_res[3:0]} = asid_a[3:0] + asid_b[3:0] + {3'b000,asid_carry[0]}; assign {asid_carry[7],asid_res[6:4]} = asid_a[6:4] + asid_b[6:4] + {2'b00,asid_carry[4]}; assign {asid_carry[8],asid_res[7]} = asid_a[7] + asid_b[7] + asid_carry[7]; // flags: ac, co and ov affected // carry out is always active high: assign as_ac = asid_carry[4] ^ alu_op[1]; assign as_co = asid_carry[8] ^ alu_op[1]; assign as_ov = asid_carry[7] ^ asid_carry[8];//-----// CMP://-----// assign lt[0] = 0; assign aeqb = ~(a ^ b);// assign lt1 = a | ~b ;// assign lt2 = ~(aeqb & lt);// assign lt[8:1] = ~(lt1[7:0] & lt2[7:0]); // flags: carry affected, ac,ov unchanged assign cmp_ac = aci;// assign cmp_co = lt [8];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -