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

Subversion Repositories oc54x

[/] [oc54x/] [trunk/] [rtl/] [verilog/] [oc54_alu.v] - Rev 5

Compare with Previous | Blame | View Log

/////////////////////////////////////////////////////////////////////
////                                                             ////
////  OpenCores54 DSP, ALU                                       ////
////                                                             ////
////  Author: Richard Herveille                                  ////
////          richard@asics.ws                                   ////
////          www.asics.ws                                       ////
////                                                             ////
/////////////////////////////////////////////////////////////////////
////                                                             ////
//// Copyright (C) 2002 Richard Herveille                        ////
////                    richard@asics.ws                         ////
////                                                             ////
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
////                                                             ////
/////////////////////////////////////////////////////////////////////
 
//
// Xilinx Virtex-E WC: 617 CLB slices @ 58MHz
//
 
//  CVS Log														     
//																     
//  $Id: oc54_alu.v,v 1.1.1.1 2002-04-10 09:34:40 rherveille Exp $														     
//																     
//  $Date: 2002-04-10 09:34:40 $														 
//  $Revision: 1.1.1.1 $													 
//  $Author: rherveille $													     
//  $Locker:  $													     
//  $State: Exp $														 
//																     
// Change History:												     
//               $Log: not supported by cvs2svn $											 
 
`include "timescale.v"
`include "oc54_alu_defines.v"
 
module oc54_alu (
	clk, ena, inst,
	seli, doublet,
	a, b, s, t, cb,
	bp_a, bp_b,	bp_ar, bp_br,
	c16, sxm, ci, tci, 
	co, tco,
	result
	);
 
//
// parameters
//
 
//
// inputs & outputs
//
input         clk;
input         ena;
input  [ 6:0] inst;              // instruction
input  [ 1:0] seli;              // input selection
input         doublet;           // {T, T}
input  [39:0] a, b, s;           // accumulators + shifter inputs
input  [15:0] t, cb;             // TREG + c-bus input
input  [39:0] bp_ar, bp_br;      // bypass a register, bypass b register
input         bp_a, bp_b;        // bypass select
input         c16, sxm;          // dual-mode, sign-extend-mode, 
input         ci, tci;           // carry in, tc-in
output        co, tco;           // carry out, overflow, zero, tc-out
output [39:0] result;
 
reg        co, tco;
reg [39:0] result;
 
//
// variables
//
reg [39:0] iresult;
reg        itco, ico;
reg [39:0] x;
 
wire [39:0] y;
 
reg dc16, dci, dtci;
 
reg [6:0] dinst;
 
 
//
// module body
//
 
//
// generate input selection, barrel-shifter has 1cycle delay
//
always@(posedge clk)
	if (ena)
		case(seli) // synopsis full_case parallel_case
			2'b00 : 
				if (doublet)
					x <= #1 { {39-31{1'b0}}, t, t}; // is this correct ??
				else
					x <= #1 { {39-15{sxm ? t[15] : 1'b0}}, t};
			2'b01 : x <= #1 bp_a ? bp_ar : a;
			2'b10 : x <= #1 bp_b ? bp_br : b;
			2'b11 : x <= #1 { {39-15{sxm ? cb[15] : 1'b0}}, cb}; 
		endcase
 
assign y = s; // second input from barrel-shifter
 
//
// delay control signals
//
always@(posedge clk)
	if (ena)
		begin
			dc16   <= #1 c16;
			dci    <= #1 ci;
			dtci   <= #1 tci;
			dinst  <= #1 inst;
		end
 
//
// generate ALU
//
always@(dinst or x or y or dc16 or dtci or dci)
begin
 
	ico     = dci;
	itco    = dtci;
	iresult = x;
 
	case(dinst) // synopsis full_case parallel_case
		//
		// Arithmetic instructions
		//
		`ABS : // absolute value
			begin
				if (x[39])
					iresult = (~x) + 1'b1;
				else
					iresult = x;
 
					ico     = ~|(iresult);
			end
 
		`ADD : // ALSO ADDC, ADDS. For ADD, ADDS ci = 1'b0;
			begin
				iresult = x + y + dci;
				ico     = iresult[32];
			end
 
		`MAX : // ALSO MIN. MAX: x==accA, y==accB, MIN: x==accB, y ==accA
			begin
					ico     = (x > y);
					iresult = (x > y) ? x : y;
			end
 
		`NEG :
			begin
					iresult = (~x) + 1'b1;
					ico     = ~|(iresult);
			end
 
		`SUB : // ALSO SUBB, SUBS. For SUB, SUBS ci = 1'b1;
			begin
				iresult = x - y - ~dci;
				ico     = iresult[32];
			end
 
		`SUBC : // subtract conditional (for division)
			begin
				// FIXME: Is this correct ?? How does SUBC affect the carry bit ?
				iresult = x - y;
				ico     = iresult[32];
 
				if ( iresult > 0 )
//					iresult = (iresult << 1) + 1'b1;
					iresult = ({x[38:0], 1'b0}) + 1'b1;
				else
//					iresult = x << 1;
					iresult = {x[38:0], 1'b0};
			end
 
 
		//
		// Dual Precision Arithmetic instructions
		//
		`DADD :
			if (dc16)  // dual add          result_hi/lo = x_hi/lo + y_hi/lo
				begin
					iresult[39:16] = x[31:16] + y[31:16];
					iresult[15: 0] = x[15: 0] + y[15: 0]; 
				end
			else      // 32bit add         result = x + y
					{ico, iresult} = x + y;
 
		`DSUB :
			if (dc16) // dual subtract     result_hi/lo = x_hi/lo - y_hi/lo
				begin
					iresult[39:16] = x[31:16] - y[31:16];
					iresult[15: 0] = x[15: 0] - y[15: 0]; 
				end
			else     // 32bit subtract    result = x - y
				begin
					iresult = x - y;
					ico     = iresult[32];
				end
 
		`DRSUB : // ALSO DSUBT: make sure x = {T, T}
			if (dc16)	// dual reverse sub. result_hi/lo = y_hi/lo - x_hi/lo
				begin
					iresult[39:16] = y[31:16] - x[31:16];
					iresult[15: 0] = y[15: 0] - x[15: 0]; 
				end
			else     // 32bit reverse sub.result = y - x
				begin
					iresult = y - x;
					ico     = iresult[32];
				end
 
		`DSUBADD : // DSADT: make  sure x = {T, T}
			if (dc16)
				begin
						iresult[39:16] = y[31:16] - x[31:16];
						iresult[15: 0] = y[15: 0] + x[15: 0]; 
				end
			else
				begin
					iresult = y - x;
					ico     = iresult[32];
				end
 
		`DADDSUB : // DADST: make sure x = {T, T}
			if (dc16)
				begin
						iresult[39:16] = y[31:16] + x[31:16];
						iresult[15: 0] = y[15: 0] - x[15: 0]; 
				end
			else
				begin
					iresult = x + y;
					ico     = iresult[32];
				end
 
		//
		// logical instructions
		//
		`NOT : // CMPL
					iresult = ~x;
 
		`AND :
					iresult = x & y;
 
		`OR :
					iresult = x | y;
 
		`XOR :
					iresult = x ^ y;
 
		//
		// shift instructions
		//
		`ROL :
			begin
					iresult[39:32] = 8'h0;
					iresult[31: 0] = {x[30:0], dci};
					ico            = x[31];
			end
 
		`ROLTC :
			begin
					iresult[39:32] = 8'h0;
					iresult[31: 0] = {x[30:0], dtci};
					ico            = x[31];
			end
 
		`ROR :
			begin
					iresult[39:32] = 8'h0;
					iresult[31: 0] = {dci, x[31:1]};
					ico            = x[0];
			end
 
		`SHFT_CMP :
			if (x[31] & x[30])
				begin
//					iresult = x << 1;
					iresult = {x[38:0], 1'b0};
					itco    = 1'b0;
				end
			else
				begin
					iresult = x;
					itco    = 1'b1;
				end
 
		//
		// bit test and compare instructions
		//
		`BITF :
					itco = ~|( x[15:0] & y[15:0] );
 
		`BTST : // BIT, BITT y=Smem, x=imm or T
					itco = y[ ~x[3:0] ]; // maybe do ~x at a higher level ??
 
		`CMP_EQ	: // ALSO CMPM. for CMPM [39:16]==0
					itco = ~|(x ^ y);
		`CMP_LT :
					itco = x < y;
		`CMP_GT :
					itco = x > y;
		`CMP_NEQ :
					itco = |(x ^ y);
 
		//
		// NOP
		//
		default :
			begin
				ico     = dci;
				itco    = dtci;
				iresult = x;
			end
	endcase				
end
 
 
//
// generate registers
//
 
// result
always@(posedge clk)
	if (ena)
		result <= #1 iresult;
 
// tco, co
always@(posedge clk)
	if (ena)
		begin
			tco <= #1 itco;
			co  <= #1 ico;
		end
 
endmodule
 
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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