forked from Github_Repos/cvw
		
	Added start of fma
This commit is contained in:
		
							parent
							
								
									e295785b45
								
							
						
					
					
						commit
						a9f9cfa5b6
					
				
							
								
								
									
										10
									
								
								pipelined/src/fma/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								pipelined/src/fma/Makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
TARGET ?= fma
 | 
			
		||||
 | 
			
		||||
$(TARGET): $(TARGET).c Makefile
 | 
			
		||||
	gcc -c -I../../../addins/SoftFloat-3e/source/include  -O2 -o $(TARGET).o $(TARGET).c
 | 
			
		||||
	gcc -L../../../addins/SoftFloat-3e/build/Linux-x86_64-GCC \
 | 
			
		||||
		   -o $(TARGET) $(TARGET).o softfloat.a \
 | 
			
		||||
 | 
			
		||||
clean: 
 | 
			
		||||
	rm $(TARGET).o
 | 
			
		||||
	rm $(TARGET)
 | 
			
		||||
							
								
								
									
										52
									
								
								pipelined/src/fma/div.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								pipelined/src/fma/div.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,52 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "softfloat.h"
 | 
			
		||||
#include "softfloat_types.h"
 | 
			
		||||
 | 
			
		||||
int float_rounding_mode = 0;
 | 
			
		||||
 | 
			
		||||
union dp {
 | 
			
		||||
  unsigned short x[4];
 | 
			
		||||
  double y;
 | 
			
		||||
} X;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    uint8_t rounding_mode;
 | 
			
		||||
    uint8_t exceptions;
 | 
			
		||||
 | 
			
		||||
    uint64_t n, d, result;
 | 
			
		||||
    float64_t   d_n, d_d, d_result;
 | 
			
		||||
 | 
			
		||||
    n = 0x3feffffffefffff6;
 | 
			
		||||
    d = 0xffeffffffffffffe;
 | 
			
		||||
    //n = 0x00000000400001ff;
 | 
			
		||||
    //d = 0x3ffffdfffffffbfe;    
 | 
			
		||||
 | 
			
		||||
    d_n.v = n;
 | 
			
		||||
    d_d.v = d;
 | 
			
		||||
 | 
			
		||||
    softfloat_roundingMode = rounding_mode;
 | 
			
		||||
    softfloat_exceptionFlags = 0;
 | 
			
		||||
    softfloat_detectTininess = softfloat_tininess_beforeRounding;
 | 
			
		||||
 | 
			
		||||
    d_result = f64_div(d_n, d_d);
 | 
			
		||||
 | 
			
		||||
    //result = d_result.v;    
 | 
			
		||||
    //exceptions = softfloat_exceptionFlags & 0x1f;
 | 
			
		||||
 | 
			
		||||
    X.x[3] = (d_result.v & 0xffff000000000000) >> 48;
 | 
			
		||||
    X.x[2] = (d_result.v & 0x0000ffff00000000) >> 32;    
 | 
			
		||||
    X.x[1] = (d_result.v & 0x00000000ffff0000) >> 16;
 | 
			
		||||
    X.x[0] = (d_result.v & 0x000000000000ffff);
 | 
			
		||||
 | 
			
		||||
    printf("Number = %.4x\n", X.x[3]);
 | 
			
		||||
    printf("Number = %.4x\n", X.x[2]);
 | 
			
		||||
    printf("Number = %.4x\n", X.x[1]);
 | 
			
		||||
    printf("Number = %.4x\n", X.x[0]);
 | 
			
		||||
    printf("Number = %1.25lg\n", X.y);    
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								pipelined/src/fma/fma.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								pipelined/src/fma/fma.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,47 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "softfloat.h"
 | 
			
		||||
#include "softfloat_types.h"
 | 
			
		||||
 | 
			
		||||
int float_rounding_mode = 0;
 | 
			
		||||
 | 
			
		||||
union sp {
 | 
			
		||||
  unsigned short x[2];
 | 
			
		||||
  float y;
 | 
			
		||||
} X;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    uint8_t rounding_mode;
 | 
			
		||||
    uint8_t exceptions;
 | 
			
		||||
 | 
			
		||||
    uint32_t multiplier, multiplicand, addend, result;
 | 
			
		||||
    float32_t f_multiplier, f_multiplicand, f_addend, f_result;
 | 
			
		||||
 | 
			
		||||
    multiplier = 0xbf800000;
 | 
			
		||||
    multiplicand = 0xbf800000;
 | 
			
		||||
    addend = 0xffaaaaaa;
 | 
			
		||||
 | 
			
		||||
    f_multiplier.v = multiplier;
 | 
			
		||||
    f_multiplicand.v = multiplicand;
 | 
			
		||||
    f_addend.v = addend;
 | 
			
		||||
 | 
			
		||||
    softfloat_roundingMode = rounding_mode;
 | 
			
		||||
    softfloat_exceptionFlags = 0;
 | 
			
		||||
    softfloat_detectTininess = softfloat_tininess_beforeRounding;
 | 
			
		||||
 | 
			
		||||
    f_result = f32_mulAdd(f_multiplier, f_multiplicand, f_addend);
 | 
			
		||||
 | 
			
		||||
    result = f_result.v;    
 | 
			
		||||
    exceptions = softfloat_exceptionFlags & 0x1f;
 | 
			
		||||
 | 
			
		||||
    printf("%x\n", f_result.v);
 | 
			
		||||
 | 
			
		||||
    // Print out SP number
 | 
			
		||||
    X.x[1] = (f_result.v & 0xffff0000) >> 16;
 | 
			
		||||
    X.x[0] = (f_result.v & 0x0000ffff);
 | 
			
		||||
    printf("Number = %f\n", X.y);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										121
									
								
								pipelined/src/fma/fma16.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								pipelined/src/fma/fma16.sv
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,121 @@
 | 
			
		||||
// fma16.sv
 | 
			
		||||
// David_Harris@hmc.edu 26 February 2022
 | 
			
		||||
// 16-bit floating-point multiply-accumulate
 | 
			
		||||
 | 
			
		||||
// Operation: general purpose multiply, add, fma, with optional negation
 | 
			
		||||
//   If mul=1, p = x * y.  Else p = x.
 | 
			
		||||
//   If add=1, result = p + z.  Else result = p.
 | 
			
		||||
//   If negp or negz = 1, negate p or z to handle negations and subtractions
 | 
			
		||||
//   fadd: mul = 0, add = 1, negp = negz = 0
 | 
			
		||||
//   fsub: mul = 0, add = 1, negp = 0, negz = 1
 | 
			
		||||
//   fmul: mul = 1, add = 0, negp = 0, negz = 0
 | 
			
		||||
//   fma:  mul = 1, add = 1, negp = 0, negz = 0
 | 
			
		||||
 | 
			
		||||
module fma16(
 | 
			
		||||
  input  logic [15:0] x, y, z,
 | 
			
		||||
  input  logic        add, mul, negp, negz,
 | 
			
		||||
  input  logic [1:0]  roundmode,  // 00: rz, 01: rne, 10: rp, 11: rn
 | 
			
		||||
  output logic [15:0] result);
 | 
			
		||||
 
 | 
			
		||||
  logic [10:0] xm, ym, zm;
 | 
			
		||||
  logic [4:0] xe, ye, ze;
 | 
			
		||||
  logic       xs, ys, zs;
 | 
			
		||||
  logic       zs1; // sign before optional negation
 | 
			
		||||
  logic       ps;  // sign of product
 | 
			
		||||
 | 
			
		||||
  unpack unpack(x, y, z, xm, ym, zm, xe, ye, ze, xs, ys, zs1);  // unpack inputs
 | 
			
		||||
  signadj signadj(negp, negz, xs, ys, zs1, ps, zs);             // handle negations
 | 
			
		||||
  mult mult(mul, xm, ym, xe, ye, pm, pe);                       // p = x * y
 | 
			
		||||
  add add(add, pm, zm, pe, ze, ps, zs, rm, re, rs);             // r = z + p
 | 
			
		||||
  postproc post(roundmode, rm, re, rs, result);                 // normalize, round, pack
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module mult(
 | 
			
		||||
  input  logic        mul,
 | 
			
		||||
  input  logic [10:0] xm, ym,
 | 
			
		||||
  input  logic [4:0]  xe, ye,
 | 
			
		||||
  input  logic        xs, ys,
 | 
			
		||||
  output logic [21:0] pm,
 | 
			
		||||
  output logic [5:0]  pe);
 | 
			
		||||
 | 
			
		||||
  // only multiply if mul = 1
 | 
			
		||||
  assign pm = mul ? xm * ym : xm;       // multiply mantiassas 
 | 
			
		||||
  assign pe = mul ? xe + ye : xe;  
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module add(
 | 
			
		||||
  input  logic        add,
 | 
			
		||||
  input  logic [21:0] pm, 
 | 
			
		||||
  input  logic [10:0] zm,
 | 
			
		||||
  input  logic [5:0]  pe, 
 | 
			
		||||
  input  logic [4:0]  ze,
 | 
			
		||||
  input  logic        ps, zs,
 | 
			
		||||
  output logic [22:0] rm,
 | 
			
		||||
  output logic [6:0]  re,
 | 
			
		||||
  output logic        rs);
 | 
			
		||||
 | 
			
		||||
  logic [22:0] arm;
 | 
			
		||||
  logic [6:0]  are;
 | 
			
		||||
  logic        ars;
 | 
			
		||||
 | 
			
		||||
  alignshift as(pe, ze, zm, zmaligned);
 | 
			
		||||
  condneg cnp(pm, ps, pmn);
 | 
			
		||||
  condneg cnz(zm, zs, zmn);
 | 
			
		||||
  
 | 
			
		||||
  // add or pass product through
 | 
			
		||||
  assign rm = add ? arm : pm;
 | 
			
		||||
  assign re = add ? are : pe;
 | 
			
		||||
  assign rs = add ? ars : ps;
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
module postproc(
 | 
			
		||||
  input  logic [1:0] roundmode,
 | 
			
		||||
  input  logic [22:0] rm,
 | 
			
		||||
  input  logic [6:0]  re,
 | 
			
		||||
  input  logic        rs,
 | 
			
		||||
  output logic [15:0] result);
 | 
			
		||||
 | 
			
		||||
  // add special case handling for zeros, NaN, Infinity
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module signadj(
 | 
			
		||||
  input  logic negx, negz,
 | 
			
		||||
  input  logic xs, ys, zs1,
 | 
			
		||||
  output logic ps, zs);
 | 
			
		||||
 | 
			
		||||
  assign ps = xs ^ ys ^ negx; // sign of product
 | 
			
		||||
  assign zs = zs1 ^ negz; // 
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module unpack(
 | 
			
		||||
  input  logic [15:0] x, y, z,
 | 
			
		||||
  output logic [10:0] xm, ym, zm,
 | 
			
		||||
  output logic [4:0]  xe, ye, ze,
 | 
			
		||||
  output logic        xs, ys, zs);
 | 
			
		||||
 | 
			
		||||
  unpacknum upx(x, xm, xe, xs);
 | 
			
		||||
  unpacknum upy(y, ym, ye, ys);
 | 
			
		||||
  unpacknum upz(z, zm, ze, zs);
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module unpacknum(
 | 
			
		||||
  input logic  [15:0] num,
 | 
			
		||||
  output logic [10:0] m,
 | 
			
		||||
  output logic [4:0]  e,
 | 
			
		||||
  output logic        s);
 | 
			
		||||
 | 
			
		||||
  logic [9:0] f;  // fraction without leading 1
 | 
			
		||||
  logic [4:0] eb; // biased exponent
 | 
			
		||||
 | 
			
		||||
  assign {f, eb, s} = num; // pull bit fields out of floating-point number
 | 
			
		||||
  assign m = {1'b1, f}; // prepend leading 1 to fraction
 | 
			
		||||
  assign e = eb - 15;   // remove bias from exponent
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Tests:
 | 
			
		||||
// Every permutation for x, y, z of 
 | 
			
		||||
//    mantissa = {1.0, 1.0000000001, 1.1, 1.1111111110, 1.1111111111}
 | 
			
		||||
//    biased exponent = {1, 2, 14, 15, 16, 21, 29, 30}
 | 
			
		||||
//    sign = {0, 1}
 | 
			
		||||
//    special case: [normal, 0, INF, NaN]
 | 
			
		||||
							
								
								
									
										31
									
								
								pipelined/src/fma/fma16_testgen.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										31
									
								
								pipelined/src/fma/fma16_testgen.py
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,31 @@
 | 
			
		||||
#!/usr/bin/python3
 | 
			
		||||
 | 
			
		||||
# fma16_testgen.py
 | 
			
		||||
# David_Harris@hmc.edu 26 February 2022
 | 
			
		||||
# Generate test cases for 16-bit FMA 
 | 
			
		||||
  
 | 
			
		||||
def makeVal(val):
 | 
			
		||||
 | 
			
		||||
def makeCase(x, y, z, mul, add, msg):
 | 
			
		||||
    xval = makeVal(x);
 | 
			
		||||
    yval = makeVal(y);
 | 
			
		||||
    zval = makeVal(z);
 | 
			
		||||
    mode = mul*2+add; # convert to hexadecimal code
 | 
			
		||||
    expected = makeExpected(x, y, z, mul, add);
 | 
			
		||||
    print(xval,"_", yval, "_", zval, "_", mode, "_", expected, " //", msg);
 | 
			
		||||
 | 
			
		||||
def makeMulCase(x, y, msg):
 | 
			
		||||
  makeCase(x, y, "0", 1, 0, msg)
 | 
			
		||||
 | 
			
		||||
################################
 | 
			
		||||
## Main program
 | 
			
		||||
################################
 | 
			
		||||
 | 
			
		||||
# Directed cases
 | 
			
		||||
makeMulCase("1", "1", "1 x 1");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Corner cases
 | 
			
		||||
 | 
			
		||||
# Random cases
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								pipelined/src/fma/softfloat.a
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pipelined/src/fma/softfloat.a
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user