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

Subversion Repositories ft816float

[/] [ft816float/] [trunk/] [rtl/] [verilog/] [fpZLUnit.v] - Rev 84

Go to most recent revision | Compare with Previous | Blame | View Log

`timescale 1ns / 1ps
// ============================================================================
//        __
//   \\__/ o\    (C) 2007-2019  Robert Finch, Waterloo
//    \  __ /    All rights reserved.
//     \/_//     robfinch<remove>@finitron.ca
//       ||
//
//	fpZLUnit.v
//		- zero latency floating point unit
//		- instructions can execute in a single cycle without
//		  a clock
//		- parameterized width
//		- IEEE 754 representation
//
//
// 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 3 of the License, or     
// (at your option) any later version.                                      
//                                                                          
// This source file 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 General Public License for more details.                             
//                                                                          
// You should have received a copy of the GNU General Public License        
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
//                                                                          
//	fabs	- get absolute value of number
//	fnabs	- get negative absolute value of number
//	fneg	- negate number
//	fmov	- copy input to output
//	fsign	- get sign of number (set number to +1,0, or -1)
//	fman	- get mantissa (set exponent to zero)
//  fcmp
//
// ============================================================================
 
`define FLOAT   4'h1
`define FLT1		4'h1
`define FLT2		4'h2
`define FLT3		4'h3
`define FANDI		4'hE
`define FORI		4'hF
 
`define FMAX		5'h10
`define FMIN		5'h11
`define FCMP    5'h06
`define FMOV    5'h00
`define FNEG    5'h04
`define FABS    5'h05
`define FSIGN   5'h06
`define FMAN    5'h07
`define FNABS   5'h08
`define FCVTSD  5'h09
`define F32TO80	5'h0A
`define ISNAN		5'h0E
`define CPYSGN	5'h0F	// FLT2
`define FINITE	5'h0F	// FLT1
//`define FCVTSQ  6'h1B
`define FCVTDS  5'h19
`define FSLT		5'h10
`define FSGE		5'h11
`define FSLE		5'h12
`define FSGT		5'h13
`define FSEQ		5'h14
`define FSNE		5'h15
`define FSUN		5'h16
`define F80TO32	5'h1A
`define UNORD		5'h1F
 
module fpZLUnit
#(parameter WID=80)
(
  input [3:0] op4,
  input [4:0] func5,
  input [39:0] ir,
	input [WID+3:0] a,
	input [WID+3:0] b,	// for fcmp
	input [WID+3:0] c,	// for fcmp
	output reg [WID+3:0] o,
	output reg nanx
);
`include "fpSize.sv"
 
//wire [1:0] prec = ir[25:24];
 
wire nanxab,nanxac,nanxbc;
wire nana;
wire [EMSB:0] expa;
wire [FMSB:0] ma;
wire xinfa;
wire [4:0] cmp_o, cmpac_o, cmpbc_o;
 
// Zero is being passed for b in some cases so the NaN must come from a if
// present.
fp_cmp_unit #(WID+4) u1 (.a(a), .b(b), .o(cmp_o), .nanx(nanxab) );
fp_cmp_unit #(WID+4) u2 (.a(a), .b(c), .o(cmpac_o), .nanx(nanxac) );
fp_cmp_unit #(WID+4) u3 (.a(b), .b(c), .o(cmpbc_o), .nanx(nanxbc) );
fpDecomp #(WID+4) u4 (.i(a), .sgn(), .exp(expa), .man(ma), .fract(), .xz(), .mz(), .vz(), .inf(), .xinf(xinfa), .qnan(), .snan(), .nan(nana));
wire [127:0] sq_o;
//fcvtsq u2 (a[31:0], sq_o);
wire [79:0] sdo;
fs2d u5 (a[43:4], sdo);
wire [39:0] dso;
fd2s u6 (a, dso);
wire [79:0] f32to80o;
wire [31:0] f80to32o;
F32ToF80 u7 (a[35:4], f32to80o);
F80ToF32 u8 (a[WID+3:4], f32to80o);
 
always @*
  case(op4)
  `FLT1:
    case(func5)
    `FABS:   begin o <= {1'b0,a[WID-2:0]}; nanx <= nanxab; end
    `FNABS:  begin o <= {1'b1,a[WID-2:0]}; nanx <= nanxab; end
    `FNEG:   begin o <= {~a[WID-1],a[WID-2:0]};	nanx <= nanxab; end
    `FMOV:   begin o <= a; nanx <= nanxab; end
    `FSIGN:  begin o <= (a[WID-2:0]==0) ? 0 : {a[WID-1],1'b0,{EMSB{1'b1}},{FMSB+1{1'b0}}}; nanx <= 1'b0; end
    `FMAN:   begin o <= {a[WID-1],1'b0,{EMSB{1'b1}},a[FMSB:0]}; nanx <= 1'b0; end
    //`FCVTSQ:    o <= sq_o;
    `FCVTSD: begin o <= {sdo,4'h0}; nanx <= nanxab; end
    `FCVTDS: begin o <= {{40{dso[39]}},dso,4'h0}; nanx <= nanxab; end
    `F32TO80: begin o <= {f32to80o,4'h0}; nanx <= nanxab; end
    `F80TO32: begin o <= {f80to32o,4'h0}; nanx <= nanxab; end
    `ISNAN:	 begin o <= nana; end
    `FINITE:	begin o <= !xinfa; end
    `UNORD:		begin o <= nanxab; end
    default: o <= 0;
    endcase
  `FLT2:
    case(func5)
    `FCMP:   begin o <= {cmp_o,4'h0}; nanx <= nanxab; end
    `FSLT:	 begin o <=  {cmp_o[1],4'h0}; nanx <= nanxab; end
    `FSGE:	 begin o <= {~cmp_o[1],4'h0}; nanx <= nanxab; end
    `FSLE:	 begin o <=  {cmp_o[2],4'h0}; nanx <= nanxab; end
    `FSGT:	 begin o <= ~{cmp_o[2],4'h0}; nanx <= nanxab; end
    `FSEQ:	 begin o <=  {cmp_o[0],4'h0}; nanx <= nanxab; end
    `FSNE:	 begin o <= ~{cmp_o[0],4'h0}; nanx <= nanxab; end
    `FSUN:	 begin o <=  {cmp_o[4],4'h0}; nanx <= nanxab; end
    `CPYSGN:	begin o <= {b[WID+3],a[WID+2:0]}; end
    default: o <= 0;
    endcase
  `FLT3:
  	case(func5)
	  `FMAX:	
	  	begin
	  	  o <= ~cmp_o[2] & ~cmpac_o[2] ? a : ~cmpbc_o[2] ? b : c;
				nanx <= nanxab|nanxac|nanxbc;
	  	end
	  `FMIN:
	  	begin
	  	 	o <=  cmp_o[1] & cmpac_o[1] ? a : cmpbc_o[2] ? b : c;
				nanx <= nanxab|nanxac|nanxbc;
	  	end
    default: o <= 0;
  	endcase
  `FANDI:
  	begin
  	case(ir[32:31])
  	2'd0:		o <= {a[23: 4] & {{58{1'b1}},ir[39:33],ir[30:16],4'h0}};
  	2'd1:		o <= a[43:24] & {{36{1'b1}},ir[39:33],ir[30:16],{20{1'b1}}};
  	2'd2:		o <= a[63:44] & {{14{1'b1}},ir[39:33],ir[30:16],{40{1'b1}}};
  	2'd3:		o <= a[83:64] & {ir[39:33],ir[30:16],{60{1'b1}}};
  	endcase
  	nanx <= 1'b0;
  	end
  `FORI:
  	begin
  	case(ir[32:31])
  	2'd0:		o <= {a[23: 4] & {{58{1'b0}},ir[39:33],ir[30:16],4'h0}};
  	2'd1:		o <= a[43:24] & {{36{1'b0}},ir[39:33],ir[30:16],{20{1'b0}}};
  	2'd2:		o <= a[63:44] & {{14{1'b0}},ir[39:33],ir[30:16],{40{1'b0}}};
  	2'd3:		o <= a[83:64] & {ir[39:33],ir[30:16],{60{1'b0}}};
  	endcase
  	nanx <= 1'b0;
  	end
	default:	o <= 0;
	endcase
 
endmodule
 

Go to most recent revision | 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.