2022-06-01 23:34:29 +00:00
`include " wally-config.vh "
2021-04-04 18:09:13 +00:00
module fctrl (
2021-07-24 18:59:57 +00:00
input logic [ 6 : 0 ] Funct7D , // bits 31:25 of instruction - may contain percision
input logic [ 6 : 0 ] OpD , // bits 6:0 of instruction
input logic [ 4 : 0 ] Rs2D , // bits 24:20 of instruction
input logic [ 2 : 0 ] Funct3D , // bits 14:12 of instruction - may contain rounding mode
input logic [ 2 : 0 ] FRM_REGW , // rounding mode from CSR
2022-05-03 11:56:31 +00:00
input logic [ 1 : 0 ] STATUS_FS , // is FPU enabled?
2021-07-24 18:59:57 +00:00
output logic IllegalFPUInstrD , // Is the instruction an illegal fpu instruction
output logic FRegWriteD , // FP register write enable
output logic FDivStartD , // Start division or squareroot
2022-06-13 22:47:51 +00:00
output logic [ 1 : 0 ] FResSelD , // select result to be written to fp register
2021-07-29 03:49:21 +00:00
output logic [ 2 : 0 ] FOpCtrlD , // chooses which opperation to do - specifics shown at bottom of module and in each unit
2022-06-13 22:47:51 +00:00
output logic [ 1 : 0 ] PostProcSelD ,
2022-06-02 19:50:28 +00:00
output logic [ `FMTBITS - 1 : 0 ] FmtD , // precision - single-0 double-1
2021-07-24 18:59:57 +00:00
output logic [ 2 : 0 ] FrmD , // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude
output logic FWriteIntD // is the result written to the integer register
) ;
2021-04-04 18:09:13 +00:00
2022-06-13 22:47:51 +00:00
`define FCTRLW 11
2021-06-28 22:53:58 +00:00
logic [ `FCTRLW - 1 : 0 ] ControlsD ;
2022-06-13 22:47:51 +00:00
//*** will putting x for don't cares reduce area in synthisis???
2021-06-28 22:53:58 +00:00
// FPU Instruction Decoder
always_comb
2022-05-03 11:56:31 +00:00
if ( STATUS_FS = = 2 'b00 ) // FPU instructions are illegal when FPU is disabled
2022-06-14 23:58:39 +00:00
ControlsD = `FCTRLW 'b0 _0_00_xx_0xx_0_1 ;
2022-05-03 11:56:31 +00:00
else case ( OpD )
2022-06-13 22:47:51 +00:00
// FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr
2021-06-28 22:53:58 +00:00
7 'b0000111 : case ( Funct3D )
2022-06-14 23:58:39 +00:00
3 'b010 : ControlsD = `FCTRLW 'b1 _0_10_xx_0xx_0_0 ; // flw
3 'b011 : ControlsD = `FCTRLW 'b1 _0_10_xx_0xx_0_0 ; // fld
default : ControlsD = `FCTRLW 'b0 _0_00_xx_0xx_0_1 ; // non-implemented instruction
2021-06-28 22:53:58 +00:00
endcase
7 'b0100111 : case ( Funct3D )
2022-06-28 21:33:31 +00:00
3 'b010 : ControlsD = `FCTRLW 'b0 _0_10_xx_0xx_0_0 ; // fsw
3 'b011 : ControlsD = `FCTRLW 'b0 _0_10_xx_0xx_0_0 ; // fsd
2022-06-14 23:58:39 +00:00
default : ControlsD = `FCTRLW 'b0 _0_00_xx_0xx_0_1 ; // non-implemented instruction
2021-06-28 22:53:58 +00:00
endcase
2022-06-13 22:47:51 +00:00
7 'b1000011 : ControlsD = `FCTRLW 'b1 _0_01_10_000_0_0 ; // fmadd
7 'b1000111 : ControlsD = `FCTRLW 'b1 _0_01_10_001_0_0 ; // fmsub
7 'b1001011 : ControlsD = `FCTRLW 'b1 _0_01_10_010_0_0 ; // fnmsub
7 'b1001111 : ControlsD = `FCTRLW 'b1 _0_01_10_011_0_0 ; // fnmadd
2021-06-28 22:53:58 +00:00
7 'b1010011 : casez ( Funct7D )
2022-06-13 22:47:51 +00:00
7 'b00000 ? ? : ControlsD = `FCTRLW 'b1 _0_01_10_110_0_0 ; // fadd
7 'b00001 ? ? : ControlsD = `FCTRLW 'b1 _0_01_10_111_0_0 ; // fsub
7 'b00010 ? ? : ControlsD = `FCTRLW 'b1 _0_01_10_100_0_0 ; // fmul
2022-06-14 23:58:39 +00:00
7 'b00011 ? ? : ControlsD = `FCTRLW 'b1 _0_01_01_xx0_1_0 ; // fdiv
7 'b01011 ? ? : ControlsD = `FCTRLW 'b1 _0_01_01_xx1_1_0 ; // fsqrt
2021-06-28 22:53:58 +00:00
7 'b00100 ? ? : case ( Funct3D )
2022-06-14 23:58:39 +00:00
3 'b000 : ControlsD = `FCTRLW 'b1 _0_00_xx_000_0_0 ; // fsgnj
3 'b001 : ControlsD = `FCTRLW 'b1 _0_00_xx_001_0_0 ; // fsgnjn
3 'b010 : ControlsD = `FCTRLW 'b1 _0_00_xx_010_0_0 ; // fsgnjx
default : ControlsD = `FCTRLW 'b0 _0_00_xx_0xx_0_1 ; // non-implemented instruction
2021-06-28 22:53:58 +00:00
endcase
7 'b00101 ? ? : case ( Funct3D )
2022-06-14 23:58:39 +00:00
3 'b000 : ControlsD = `FCTRLW 'b1 _0_00_xx_110_0_0 ; // fmin
3 'b001 : ControlsD = `FCTRLW 'b1 _0_00_xx_101_0_0 ; // fmax
default : ControlsD = `FCTRLW 'b0 _0_00_xx_0xx_0_1 ; // non-implemented instruction
2021-06-28 22:53:58 +00:00
endcase
7 'b10100 ? ? : case ( Funct3D )
2022-06-14 23:58:39 +00:00
3 'b010 : ControlsD = `FCTRLW 'b0 _1_00_xx_010_0_0 ; // feq
3 'b001 : ControlsD = `FCTRLW 'b0 _1_00_xx_001_0_0 ; // flt
3 'b000 : ControlsD = `FCTRLW 'b0 _1_00_xx_011_0_0 ; // fle
default : ControlsD = `FCTRLW 'b0 _0_00_xx_0xx__0_1 ; // non-implemented instruction
2021-06-28 22:53:58 +00:00
endcase
2022-06-14 23:58:39 +00:00
7 'b11100 ? ? : if ( Funct3D = = 3 'b001 ) ControlsD = `FCTRLW 'b0 _1_10_xx_000_0_0 ; // fclass
else if ( Funct3D [ 1 : 0 ] = = 2 'b00 ) ControlsD = `FCTRLW 'b0 _1_11_xx_000_0_0 ; // fmv.x.w to int reg
else if ( Funct3D [ 1 : 0 ] = = 2 'b01 ) ControlsD = `FCTRLW 'b0 _1_11_xx_000_0_0 ; // fmv.x.d to int reg
else ControlsD = `FCTRLW 'b0 _0_00_xx_0xx_0_1 ; // non-implemented instruction
2022-06-13 22:47:51 +00:00
7 'b1101000 : case ( Rs2D [ 1 : 0 ] )
2 'b00 : ControlsD = `FCTRLW 'b1 _0_01_00_101_0_0 ; // fcvt.s.w w->s
2 'b01 : ControlsD = `FCTRLW 'b1 _0_01_00_100_0_0 ; // fcvt.s.wu wu->s
2 'b10 : ControlsD = `FCTRLW 'b1 _0_01_00_111_0_0 ; // fcvt.s.l l->s
2 'b11 : ControlsD = `FCTRLW 'b1 _0_01_00_110_0_0 ; // fcvt.s.lu lu->s
2021-06-28 22:53:58 +00:00
endcase
2021-07-11 22:06:33 +00:00
7 'b1100000 : case ( Rs2D [ 1 : 0 ] )
2022-06-13 22:47:51 +00:00
2 'b00 : ControlsD = `FCTRLW 'b0 _1_01_00_001_0_0 ; // fcvt.w.s s->w
2 'b01 : ControlsD = `FCTRLW 'b0 _1_01_00_000_0_0 ; // fcvt.wu.s s->wu
2 'b10 : ControlsD = `FCTRLW 'b0 _1_01_00_011_0_0 ; // fcvt.l.s s->l
2 'b11 : ControlsD = `FCTRLW 'b0 _1_01_00_010_0_0 ; // fcvt.lu.s s->lu
2021-06-28 22:53:58 +00:00
endcase
2022-06-14 23:58:39 +00:00
7 'b1111000 : ControlsD = `FCTRLW 'b1 _0_00_xx_011_0_0 ; // fmv.w.x to fp reg
2022-06-13 22:47:51 +00:00
7 'b0100000 : ControlsD = `FCTRLW 'b1 _0_01_00_000_0_0 ; // fcvt.s.d
2021-07-11 22:06:33 +00:00
7 'b1101001 : case ( Rs2D [ 1 : 0 ] )
2022-06-13 22:47:51 +00:00
2 'b00 : ControlsD = `FCTRLW 'b1 _0_01_00_101_0_0 ; // fcvt.d.w w->d
2 'b01 : ControlsD = `FCTRLW 'b1 _0_01_00_100_0_0 ; // fcvt.d.wu wu->d
2 'b10 : ControlsD = `FCTRLW 'b1 _0_01_00_111_0_0 ; // fcvt.d.l l->d
2 'b11 : ControlsD = `FCTRLW 'b1 _0_01_00_110_0_0 ; // fcvt.d.lu lu->d
2021-06-28 22:53:58 +00:00
endcase
2021-07-11 22:06:33 +00:00
7 'b1100001 : case ( Rs2D [ 1 : 0 ] )
2022-06-13 22:47:51 +00:00
2 'b00 : ControlsD = `FCTRLW 'b0 _1_01_00_001_0_0 ; // fcvt.w.d d->w
2 'b01 : ControlsD = `FCTRLW 'b0 _1_01_00_000_0_0 ; // fcvt.wu.d d->wu
2 'b10 : ControlsD = `FCTRLW 'b0 _1_01_00_011_0_0 ; // fcvt.l.d d->l
2 'b11 : ControlsD = `FCTRLW 'b0 _1_01_00_010_0_0 ; // fcvt.lu.d d->lu
2021-06-28 22:53:58 +00:00
endcase
2022-06-14 23:58:39 +00:00
7 'b1111001 : ControlsD = `FCTRLW 'b1 _0_00_xx_011_0_0 ; // fmv.d.x to fp reg
2022-06-13 22:47:51 +00:00
7 'b0100001 : ControlsD = `FCTRLW 'b1 _0_01_00_001_0_0 ; // fcvt.d.s
2022-06-14 23:58:39 +00:00
default : ControlsD = `FCTRLW 'b0 _0_00_xx_0xx_0_1 ; // non-implemented instruction
2021-06-28 22:53:58 +00:00
endcase
2022-06-14 23:58:39 +00:00
default : ControlsD = `FCTRLW 'b0 _0_00_xx_0xx_0_1 ; // non-implemented instruction
2021-06-28 22:53:58 +00:00
endcase
2021-07-24 18:59:57 +00:00
2021-06-28 22:53:58 +00:00
// unswizzle control bits
2022-06-13 22:47:51 +00:00
assign { FRegWriteD , FWriteIntD , FResSelD , PostProcSelD , FOpCtrlD , FDivStartD , IllegalFPUInstrD } = ControlsD ;
2021-04-04 18:09:13 +00:00
2021-07-24 18:59:57 +00:00
// rounding modes:
// 000 - round to nearest, ties to even
// 001 - round twords 0 - round to min magnitude
// 010 - round down - round twords negitive infinity
// 011 - round up - round twords positive infinity
// 100 - round to nearest, ties to max magnitude - round to nearest, ties away from zero
// 111 - dynamic - choose FRM_REGW as rounding mode
2021-06-28 22:53:58 +00:00
assign FrmD = & Funct3D ? FRM_REGW : Funct3D ;
2021-05-01 02:18:01 +00:00
2021-06-28 22:53:58 +00:00
// Precision
2021-07-24 18:59:57 +00:00
// 0-single
// 1-double
2022-06-01 23:34:29 +00:00
2022-06-02 19:50:28 +00:00
if ( `FPSIZES = = 1 )
assign FmtD = 0 ;
2022-06-01 23:34:29 +00:00
else if ( `FPSIZES = = 2 ) begin
logic [ 1 : 0 ] FmtTmp ;
2022-06-28 21:33:31 +00:00
assign FmtTmp = ( ( Funct7D [ 6 : 3 ] = = 4 'b0100 ) & OpD [ 4 ] ) ? Rs2D [ 1 : 0 ] : ( ~ OpD [ 6 ] & ( & OpD [ 2 : 0 ] ) ) ? { ~ Funct3D [ 1 ] , ~ ( Funct3D [ 1 ] ^ Funct3D [ 0 ] ) } : Funct7D [ 1 : 0 ] ;
2022-06-06 16:06:04 +00:00
assign FmtD = ( `FMT = = FmtTmp ) ;
2022-06-01 23:34:29 +00:00
end
else if ( `FPSIZES = = 3 | `FPSIZES = = 4 )
2022-06-20 22:53:13 +00:00
assign FmtD = ( ( Funct7D [ 6 : 3 ] = = 4 'b0100 ) & OpD [ 4 ] ) ? Rs2D [ 1 : 0 ] : Funct7D [ 1 : 0 ] ;
2021-07-24 18:59:57 +00:00
2022-06-13 22:47:51 +00:00
// Final Res Sel:
// fp int
// 00 other cmp
// 01 postproc cvt
// 10 store class
// 11 mv
2021-06-28 22:53:58 +00:00
2022-06-13 22:47:51 +00:00
// post processing Sel:
// 00 cvt
// 01 div
// 10 fma
2021-06-28 22:53:58 +00:00
2022-06-13 22:47:51 +00:00
// Other Sel:
// Ctrl signal = {FOpCtrl[2], &FOpctrl[1:0]}
// 000 - sign 00
// 001 - negate sign 00
// 010 - xor sign 00
// 011 - mv to fp 01
// 110 - min 10
// 101 - max 10
2021-06-28 22:53:58 +00:00
2022-06-13 22:47:51 +00:00
// OpCtrl:
// Fma: {not multiply-add?, negate prod?, negate Z?}
// 000 - fmadd
// 001 - fmsub
// 010 - fnmsub
// 011 - fnmadd
// 100 - mul
// 110 - add
// 111 - sub
// Div:
// 0 - ???
// 1 - ???
// Cvt Int: {Int to Fp?, 64 bit int?, signed int?}
// Cvt Fp: output format
// 10 - to half
// 00 - to single
// 01 - to double
// 11 - to quad
// Cmp: {equal?, less than?}
// 010 - eq
// 001 - lt
// 011 - le
// 110 - min
// 101 - max
// Sgn:
// 00 - sign
// 01 - negate sign
// 10 - xor sign
2021-06-28 22:53:58 +00:00
2021-06-21 00:24:09 +00:00
2021-04-04 18:09:13 +00:00
endmodule