OpenCores
URL https://opencores.org/ocsvn/amber/amber/trunk

Subversion Repositories amber

[/] [amber/] [trunk/] [hw/] [vlog/] [amber23/] [a23_alu.v] - Diff between revs 2 and 15

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 2 Rev 15
Line 1... Line 1...
 
//////////////////////////////////////////////////////////////////
 
//                                                              //
 
//  Arithmetic Logic Unit (ALU) for Amber 2 Core                //
 
//                                                              //
 
//  This file is part of the Amber project                      //
 
//  http://www.opencores.org/project,amber                      //
 
//                                                              //
 
//  Description                                                 //
 
//  Supported functions: 32-bit add and subtract, AND, OR,      //
 
//  XOR, NOT, Zero extent 8-bit numbers                         //
 
//                                                              //
 
//  Author(s):                                                  //
 
//      - Conor Santifort, csantifort.amber@gmail.com           //
 
//                                                              //
 
//////////////////////////////////////////////////////////////////
 
//                                                              //
 
// Copyright (C) 2010 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                     //
 
//                                                              //
 
//////////////////////////////////////////////////////////////////
 
 
 
 
 
module a23_alu (
 
 
 
input       [31:0]          i_a_in,
 
input       [31:0]          i_b_in,
 
input                       i_barrel_shift_carry,
 
input                       i_status_bits_carry,
 
input       [8:0]           i_function,
 
 
 
output      [31:0]          o_out,
 
output      [3:0]           o_flags
 
);
 
 
 
wire     [31:0]         a, b, b_not;
 
wire     [31:0]         and_out, or_out, xor_out;
 
wire     [31:0]         sign_ex8_out, sign_ex_16_out;
 
wire     [31:0]         zero_ex8_out, zero_ex_16_out;
 
wire     [32:0]         fadder_out;
 
wire                    swap_sel;
 
wire                    not_sel;
 
wire     [1:0]          cin_sel;
 
wire                    cout_sel;
 
wire     [3:0]          out_sel;
 
wire                    carry_in;
 
wire                    carry_out;
 
wire                    overflow_out;
 
wire                    fadder_carry_out;
 
 
 
assign  { swap_sel, not_sel, cin_sel, cout_sel, out_sel } = i_function;
 
 
 
 
 
// ========================================================
 
// A Select
 
// ========================================================
 
assign a     = (swap_sel ) ? i_b_in : i_a_in ;
 
 
 
// ========================================================
 
// B Select
 
// ========================================================
 
assign b     = (swap_sel ) ? i_a_in : i_b_in ;
 
 
 
// ========================================================
 
// Not Select
 
// ========================================================
 
assign b_not     = (not_sel ) ? ~b : b ;
 
 
 
// ========================================================
 
// Cin Select
 
// ========================================================
 
assign carry_in  = (cin_sel==2'd0 ) ? 1'd0                   :
 
                   (cin_sel==2'd1 ) ? 1'd1                   :
 
                                      i_status_bits_carry    ;  // add with carry
 
 
 
// ========================================================
 
// Cout Select
 
// ========================================================
 
assign carry_out = (cout_sel==1'd0 ) ? fadder_carry_out     :
 
                                       i_barrel_shift_carry ;
 
 
 
// For non-addition/subtractions that incorporate a shift 
 
// operation, C is set to the last bit
 
// shifted out of the value by the shifter.
 
 
 
 
 
// ========================================================
 
// Overflow out
 
// ========================================================
 
// Only assert the overflow flag when using the adder
 
assign  overflow_out    = out_sel == 4'd1 &&
 
                            // overflow if adding two positive numbers and get a negative number
 
                          ( (!a[31] && !b_not[31] && fadder_out[31]) ||
 
                            // or adding two negative numbers and get a positive number
 
                            (a[31] && b_not[31] && !fadder_out[31])     );
 
 
 
 
 
// ========================================================
 
// ALU Operations
 
// ========================================================
 
 
 
`ifdef XILINX_FPGA
 
 
 
    // XIlinx Spartan 6 DSP module
 
    `ifdef XILINX_SPARTAN6_FPGA
 
        xs6_addsub_n #(.WIDTH(33))
 
    `endif
 
    `ifdef XILINX_VIRTEX6_FPGA
 
        xv6_addsub_n #(.WIDTH(33))
 
    `endif
 
        u_xx_addsub_33(
 
        .i_a    ( {1'd0,a}      ),
 
        .i_b    ( {1'd0,b_not}  ),
 
        .i_cin  ( carry_in      ),
 
        .i_sub  ( 1'd0          ),
 
        .o_sum  ( fadder_out    ),
 
        .o_co   (               )
 
    );
 
 
 
`else
 
assign fadder_out       = { 1'd0,a} + {1'd0,b_not} + {32'd0,carry_in};
 
`endif
 
 
 
assign fadder_carry_out = fadder_out[32];
 
assign and_out          = a & b_not;
 
assign or_out           = a | b_not;
 
assign xor_out          = a ^ b_not;
 
assign zero_ex8_out     = {24'd0,  b_not[7:0]};
 
assign zero_ex_16_out   = {16'd0,  b_not[15:0]};
 
assign sign_ex8_out     = {{24{b_not[7]}},  b_not[7:0]};
 
assign sign_ex_16_out   = {{16{b_not[15]}}, b_not[15:0]};
 
 
 
// ========================================================
 
// Out Select
 
// ========================================================
 
assign o_out = out_sel == 4'd0 ? b_not            :
 
               out_sel == 4'd1 ? fadder_out[31:0] :
 
               out_sel == 4'd2 ? zero_ex_16_out   :
 
               out_sel == 4'd3 ? zero_ex8_out     :
 
               out_sel == 4'd4 ? sign_ex_16_out   :
 
               out_sel == 4'd5 ? sign_ex8_out     :
 
               out_sel == 4'd6 ? xor_out          :
 
               out_sel == 4'd7 ? or_out           :
 
                                 and_out          ;
 
 
 
assign o_flags       = {  o_out[31],      // negative
 
                         |o_out == 1'd0,  // zero
 
                         carry_out,       // carry
 
                         overflow_out     // overflow
 
                         };
 
 
 
 
 
endmodule
 
 
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.