2022-07-07 23:01:33 +00:00
///////////////////////////////////////////
2022-09-20 10:57:57 +00:00
// fctrl.sv
2022-07-07 23:01:33 +00:00
//
// Written: me@KatherineParry.com
// Modified: 7/5/2022
//
2023-01-11 20:27:00 +00:00
// Purpose: floating-point control unit
2022-07-07 23:01:33 +00:00
//
2023-01-12 12:35:44 +00:00
// Documentation: RISC-V System on Chip Design Chapter 13
//
2023-01-11 23:15:08 +00:00
// A component of the CORE-V-WALLY configurable RISC-V project.
2022-07-07 23:01:33 +00:00
//
2023-01-10 19:35:20 +00:00
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
2022-07-07 23:01:33 +00:00
//
2023-01-10 19:35:20 +00:00
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
2022-07-07 23:01:33 +00:00
//
2023-01-10 19:35:20 +00:00
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
2022-07-07 23:01:33 +00:00
//
2023-01-10 19:35:20 +00:00
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
2022-07-07 23:01:33 +00:00
////////////////////////////////////////////////////////////////////////////////////////////////
2022-06-01 23:34:29 +00:00
`include " wally-config.vh "
2021-04-04 18:09:13 +00:00
module fctrl (
2023-01-12 04:02:30 +00:00
input logic clk ,
input logic reset ,
// input control signals
2023-03-24 22:32:25 +00:00
input logic StallE , StallM , StallW , // stall signals
input logic FlushE , FlushM , FlushW , // flush signals
input logic IntDivE , // is inteteger division
input logic [ 2 : 0 ] FRM_REGW , // rounding mode from CSR
input logic [ 1 : 0 ] STATUS_FS , // is FPU enabled?
input logic FDivBusyE , // is the divider busy
// intruction
input logic [ 31 : 0 ] InstrD , // the full instruction
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 , Funct3E , // bits 14:12 of instruction - may contain rounding mode
// input mux selections
output logic XEnD , YEnD , ZEnD , // enable inputs
output logic XEnE , YEnE , ZEnE , // enable inputs
// opperation mux selections
output logic FCvtIntE , FCvtIntW , // convert to integer opperation
output logic [ 2 : 0 ] FrmM , // FP rounding mode
output logic [ `FMTBITS - 1 : 0 ] FmtE , FmtM , // FP format
output logic [ 2 : 0 ] OpCtrlE , OpCtrlM , // Select which opperation to do in each component
output logic FpLoadStoreM , // FP load or store instruction
output logic [ 1 : 0 ] PostProcSelE , PostProcSelM , // select result in the post processing unit
output logic [ 1 : 0 ] FResSelE , FResSelM , FResSelW , // Select one of the results that finish in the memory stage
2023-01-12 04:02:30 +00:00
// register control signals
2023-03-24 22:32:25 +00:00
output logic FRegWriteE , FRegWriteM , FRegWriteW , // FP register write enable
output logic FWriteIntE , FWriteIntM , // Write to integer register
output logic [ 4 : 0 ] Adr1D , Adr2D , Adr3D , // adresses of each input
output logic [ 4 : 0 ] Adr1E , Adr2E , Adr3E , // adresses of each input
2023-01-12 04:02:30 +00:00
// other control signals
2023-02-21 17:32:17 +00:00
output logic IllegalFPUInstrD , // Is the instruction an illegal fpu instruction
2023-03-24 22:32:25 +00:00
output logic FDivStartE , IDivStartE // Start division or squareroot
2021-07-24 18:59:57 +00:00
) ;
2021-04-04 18:09:13 +00:00
2022-12-19 17:09:48 +00:00
`define FCTRLW 12
2023-01-12 04:02:30 +00:00
2023-03-24 22:32:25 +00:00
logic [ `FCTRLW - 1 : 0 ] ControlsD ; // control signals
logic FRegWriteD ; // FP register write enable
logic FDivStartD ; // start division/sqrt
logic FWriteIntD ; // integer register write enable
logic [ 2 : 0 ] OpCtrlD ; // Select which opperation to do in each component
logic [ 1 : 0 ] PostProcSelD ; // select result in the post processing unit
logic [ 1 : 0 ] FResSelD ; // Select one of the results that finish in the memory stage
logic [ 2 : 0 ] FrmD , FrmE ; // FP rounding mode
logic [ `FMTBITS - 1 : 0 ] FmtD ; // FP format
2023-03-28 17:21:33 +00:00
logic [ 1 : 0 ] Fmt , Fmt2 ; // format - before possible reduction
2023-03-24 22:32:25 +00:00
logic SupportedFmt ; // is the format supported
2023-03-28 17:21:33 +00:00
logic SupportedFmt2 ; // is the source format supported for fp -> fp
2023-03-24 22:32:25 +00:00
logic FCvtIntD , FCvtIntM ; // convert to integer opperation
2022-08-23 18:08:02 +00:00
2021-06-28 22:53:58 +00:00
// FPU Instruction Decoder
2022-08-23 18:08:02 +00:00
assign Fmt = Funct7D [ 1 : 0 ] ;
2023-03-28 17:21:33 +00:00
assign Fmt2 = Rs2D [ 1 : 0 ] ; // source format for fcvt fp->fp
2023-01-12 04:02:30 +00:00
2022-08-23 18:08:02 +00:00
assign SupportedFmt = ( Fmt = = 2 'b00 | ( Fmt = = 2 'b01 & `D_SUPPORTED ) |
( Fmt = = 2 'b10 & `ZFH_SUPPORTED ) | ( Fmt = = 2 'b11 & `Q_SUPPORTED ) ) ;
2023-03-28 17:21:33 +00:00
assign SupportedFmt2 = ( Fmt2 = = 2 'b00 | ( Fmt2 = = 2 'b01 & `D_SUPPORTED ) |
( Fmt2 = = 2 'b10 & `ZFH_SUPPORTED ) | ( Fmt2 = = 2 'b11 & `Q_SUPPORTED ) ) ;
2023-01-12 04:02:30 +00:00
// decode the instruction
2023-03-30 19:57:14 +00:00
// FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr_FCvtInt
always_comb
2022-05-03 11:56:31 +00:00
if ( STATUS_FS = = 2 'b00 ) // FPU instructions are illegal when FPU is disabled
2023-04-12 20:07:30 +00:00
ControlsD = `FCTRLW 'b0 _0_00_00_000_0_1_0 ;
2022-08-23 18:08:02 +00:00
else if ( OpD ! = 7 'b0000111 & OpD ! = 7 'b0100111 & ~ SupportedFmt )
2023-04-12 20:07:30 +00:00
ControlsD = `FCTRLW 'b0 _0_00_00_000_0_1_0 ; // for anything other than loads and stores, check for supported format
2023-03-30 19:57:14 +00:00
else begin
2023-04-12 20:07:30 +00:00
ControlsD = `FCTRLW 'b0 _0_00_00_000_0_1_0 ; // default: non-implemented instruction
2023-03-29 04:13:48 +00:00
/* verilator lint_off CASEINCOMPLETE */ // default value above has priority so no other default needed
case ( OpD )
2023-03-30 19:57:14 +00:00
7 'b0000111 : case ( Funct3D )
2023-04-12 20:07:30 +00:00
3 'b010 : ControlsD = `FCTRLW 'b1 _0_10_00_0xx_0_0_0 ; // flw
3 'b011 : if ( `D_SUPPORTED ) ControlsD = `FCTRLW 'b1 _0_10_00_0xx_0_0_0 ; // fld
3 'b100 : if ( `Q_SUPPORTED ) ControlsD = `FCTRLW 'b1 _0_10_00_0xx_0_0_0 ; // flq
3 'b001 : if ( `ZFH_SUPPORTED ) ControlsD = `FCTRLW 'b1 _0_10_00_0xx_0_0_0 ; // flh
2023-03-30 19:57:14 +00:00
endcase
7 'b0100111 : case ( Funct3D )
2023-04-12 20:07:30 +00:00
3 'b010 : ControlsD = `FCTRLW 'b0 _0_10_00_0xx_0_0_0 ; // fsw
3 'b011 : if ( `D_SUPPORTED ) ControlsD = `FCTRLW 'b0 _0_10_00_0xx_0_0_0 ; // fsd
3 'b100 : if ( `Q_SUPPORTED ) ControlsD = `FCTRLW 'b0 _0_10_00_0xx_0_0_0 ; // fsq
3 'b001 : if ( `ZFH_SUPPORTED ) ControlsD = `FCTRLW 'b0 _0_10_00_0xx_0_0_0 ; // fsh
2023-03-30 19:57:14 +00:00
endcase
7 'b1000011 : ControlsD = `FCTRLW 'b1 _0_01_10_000_0_0_0 ; // fmadd
7 'b1000111 : ControlsD = `FCTRLW 'b1 _0_01_10_001_0_0_0 ; // fmsub
7 'b1001011 : ControlsD = `FCTRLW 'b1 _0_01_10_010_0_0_0 ; // fnmsub
7 'b1001111 : ControlsD = `FCTRLW 'b1 _0_01_10_011_0_0_0 ; // fnmadd
7 'b1010011 : casez ( Funct7D )
7 'b00000 ? ? : ControlsD = `FCTRLW 'b1 _0_01_10_110_0_0_0 ; // fadd
7 'b00001 ? ? : ControlsD = `FCTRLW 'b1 _0_01_10_111_0_0_0 ; // fsub
7 'b00010 ? ? : ControlsD = `FCTRLW 'b1 _0_01_10_100_0_0_0 ; // fmul
7 'b00011 ? ? : ControlsD = `FCTRLW 'b1 _0_01_01_xx0_1_0_0 ; // fdiv
7 'b01011 ? ? : if ( Rs2D = = 5 'b0000 ) ControlsD = `FCTRLW 'b1 _0_01_01_xx1_1_0_0 ; // fsqrt
7 'b00100 ? ? : case ( Funct3D )
2023-04-12 20:07:30 +00:00
3 'b000 : ControlsD = `FCTRLW 'b1 _0_00_00_000_0_0_0 ; // fsgnj
3 'b001 : ControlsD = `FCTRLW 'b1 _0_00_00_001_0_0_0 ; // fsgnjn
3 'b010 : ControlsD = `FCTRLW 'b1 _0_00_00_010_0_0_0 ; // fsgnjx
2023-03-30 19:57:14 +00:00
endcase
7 'b00101 ? ? : case ( Funct3D )
2023-04-12 20:07:30 +00:00
3 'b000 : ControlsD = `FCTRLW 'b1 _0_00_00_110_0_0_0 ; // fmin
3 'b001 : ControlsD = `FCTRLW 'b1 _0_00_00_101_0_0_0 ; // fmax
2023-03-30 19:57:14 +00:00
endcase
7 'b10100 ? ? : case ( Funct3D )
2023-04-12 20:07:30 +00:00
3 'b010 : ControlsD = `FCTRLW 'b0 _1_00_00_010_0_0_0 ; // feq
3 'b001 : ControlsD = `FCTRLW 'b0 _1_00_00_001_0_0_0 ; // flt
3 'b000 : ControlsD = `FCTRLW 'b0 _1_00_00_011_0_0_0 ; // fle
2023-03-30 19:57:14 +00:00
endcase
7 'b11100 ? ? : if ( Funct3D = = 3 'b001 & Rs2D = = 5 'b00000 )
2023-04-12 20:07:30 +00:00
ControlsD = `FCTRLW 'b0 _1_10_00_000_0_0_0 ; // fclass
2023-03-30 19:57:14 +00:00
else if ( Funct3D = = 3 'b000 & Rs2D = = 5 'b00000 )
2023-04-12 20:07:30 +00:00
ControlsD = `FCTRLW 'b0 _1_11_00_000_0_0_0 ; // fmv.x.w / fmv.x.d to int register
2023-03-30 19:57:14 +00:00
7 'b111100 ? : if ( Funct3D = = 3 'b000 & Rs2D = = 5 'b00000 )
2023-04-12 20:07:30 +00:00
ControlsD = `FCTRLW 'b1 _0_00_00_011_0_0_0 ; // fmv.w.x / fmv.d.x to fp reg
2023-03-30 19:57:14 +00:00
7 'b0100000 : if ( Rs2D [ 4 : 2 ] = = 3 'b000 & SupportedFmt2 & Rs2D [ 1 : 0 ] ! = 2 'b00 )
ControlsD = `FCTRLW 'b1 _0_01_00_000_0_0_0 ; // fcvt.s.(d/q/h)
7 'b0100001 : if ( Rs2D [ 4 : 2 ] = = 3 'b000 & SupportedFmt2 & Rs2D [ 1 : 0 ] ! = 2 'b01 )
ControlsD = `FCTRLW 'b1 _0_01_00_001_0_0_0 ; // fcvt.d.(s/h/q)
2023-03-31 15:29:10 +00:00
// coverage off
// Not covered in testing because rv64gc does not support half or quad precision
2023-03-30 19:57:14 +00:00
7 'b0100010 : if ( Rs2D [ 4 : 2 ] = = 3 'b000 & SupportedFmt2 & Rs2D [ 1 : 0 ] ! = 2 'b10 )
ControlsD = `FCTRLW 'b1 _0_01_00_010_0_0_0 ; // fcvt.h.(s/d/q)
7 'b0100011 : if ( Rs2D [ 4 : 2 ] = = 3 'b000 & SupportedFmt2 & Rs2D [ 1 : 0 ] ! = 2 'b11 )
ControlsD = `FCTRLW 'b1 _0_01_00_011_0_0_0 ; // fcvt.q.(s/h/d)
2023-03-31 15:29:10 +00:00
// coverage on
2023-03-30 19:57:14 +00:00
7 'b1101000 : case ( Rs2D )
5 'b00000 : ControlsD = `FCTRLW 'b1 _0_01_00_101_0_0_0 ; // fcvt.s.w w->s
5 'b00001 : ControlsD = `FCTRLW 'b1 _0_01_00_100_0_0_0 ; // fcvt.s.wu wu->s
5 'b00010 : ControlsD = `FCTRLW 'b1 _0_01_00_111_0_0_0 ; // fcvt.s.l l->s
5 'b00011 : ControlsD = `FCTRLW 'b1 _0_01_00_110_0_0_0 ; // fcvt.s.lu lu->s
endcase
7 'b1100000 : case ( Rs2D )
5 'b00000 : ControlsD = `FCTRLW 'b0 _1_01_00_001_0_0_1 ; // fcvt.w.s s->w
5 'b00001 : ControlsD = `FCTRLW 'b0 _1_01_00_000_0_0_1 ; // fcvt.wu.s s->wu
5 'b00010 : ControlsD = `FCTRLW 'b0 _1_01_00_011_0_0_1 ; // fcvt.l.s s->l
5 'b00011 : ControlsD = `FCTRLW 'b0 _1_01_00_010_0_0_1 ; // fcvt.lu.s s->lu
endcase
7 'b1101001 : case ( Rs2D )
5 'b00000 : ControlsD = `FCTRLW 'b1 _0_01_00_101_0_0_0 ; // fcvt.d.w w->d
5 'b00001 : ControlsD = `FCTRLW 'b1 _0_01_00_100_0_0_0 ; // fcvt.d.wu wu->d
5 'b00010 : ControlsD = `FCTRLW 'b1 _0_01_00_111_0_0_0 ; // fcvt.d.l l->d
5 'b00011 : ControlsD = `FCTRLW 'b1 _0_01_00_110_0_0_0 ; // fcvt.d.lu lu->d
endcase
7 'b1100001 : case ( Rs2D )
5 'b00000 : ControlsD = `FCTRLW 'b0 _1_01_00_001_0_0_1 ; // fcvt.w.d d->w
5 'b00001 : ControlsD = `FCTRLW 'b0 _1_01_00_000_0_0_1 ; // fcvt.wu.d d->wu
5 'b00010 : ControlsD = `FCTRLW 'b0 _1_01_00_011_0_0_1 ; // fcvt.l.d d->l
5 'b00011 : ControlsD = `FCTRLW 'b0 _1_01_00_010_0_0_1 ; // fcvt.lu.d d->lu
endcase
2023-03-31 15:29:10 +00:00
// coverage off
// Not covered in testing because rv64gc does not support half or quad precision
2023-03-30 19:57:14 +00:00
7 'b1101010 : case ( Rs2D )
5 'b00000 : ControlsD = `FCTRLW 'b1 _0_01_00_101_0_0_0 ; // fcvt.h.w w->h
5 'b00001 : ControlsD = `FCTRLW 'b1 _0_01_00_100_0_0_0 ; // fcvt.h.wu wu->h
5 'b00010 : ControlsD = `FCTRLW 'b1 _0_01_00_111_0_0_0 ; // fcvt.h.l l->h
5 'b00011 : ControlsD = `FCTRLW 'b1 _0_01_00_110_0_0_0 ; // fcvt.h.lu lu->h
endcase
7 'b1100010 : case ( Rs2D )
5 'b00000 : ControlsD = `FCTRLW 'b0 _1_01_00_001_0_0_1 ; // fcvt.w.h h->w
5 'b00001 : ControlsD = `FCTRLW 'b0 _1_01_00_000_0_0_1 ; // fcvt.wu.h h->wu
5 'b00010 : ControlsD = `FCTRLW 'b0 _1_01_00_011_0_0_1 ; // fcvt.l.h h->l
5 'b00011 : ControlsD = `FCTRLW 'b0 _1_01_00_010_0_0_1 ; // fcvt.lu.h h->lu
endcase
7 'b1101011 : case ( Rs2D )
5 'b00000 : ControlsD = `FCTRLW 'b1 _0_01_00_101_0_0_0 ; // fcvt.q.w w->q
5 'b00001 : ControlsD = `FCTRLW 'b1 _0_01_00_100_0_0_0 ; // fcvt.q.wu wu->q
5 'b00010 : ControlsD = `FCTRLW 'b1 _0_01_00_111_0_0_0 ; // fcvt.q.l l->q
5 'b00011 : ControlsD = `FCTRLW 'b1 _0_01_00_110_0_0_0 ; // fcvt.q.lu lu->q
endcase
7 'b1100011 : case ( Rs2D )
5 'b00000 : ControlsD = `FCTRLW 'b0 _1_01_00_001_0_0_1 ; // fcvt.w.q q->w
5 'b00001 : ControlsD = `FCTRLW 'b0 _1_01_00_000_0_0_1 ; // fcvt.wu.q q->wu
5 'b00010 : ControlsD = `FCTRLW 'b0 _1_01_00_011_0_0_1 ; // fcvt.l.q q->l
5 'b00011 : ControlsD = `FCTRLW 'b0 _1_01_00_010_0_0_1 ; // fcvt.lu.q q->lu
endcase
2023-03-31 15:29:10 +00:00
// coverage on
2023-03-30 19:57:14 +00:00
endcase
2023-03-29 04:13:48 +00:00
endcase
end
2023-03-30 20:07:39 +00:00
/* verilator lint_on CASEINCOMPLETE */
2021-07-24 18:59:57 +00:00
2021-06-28 22:53:58 +00:00
// unswizzle control bits
2022-12-19 17:09:48 +00:00
assign # 1 { FRegWriteD , FWriteIntD , FResSelD , PostProcSelD , OpCtrlD , FDivStartD , IllegalFPUInstrD , FCvtIntD } = 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
2023-01-12 04:02:30 +00:00
// 00 - single
// 01 - double
// 10 - half
// 11 - quad
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-12-23 20:24:20 +00:00
// Enables indicate that a source register is used and may need stalls. Also indicate special cases for infinity or NaN.
2022-12-23 20:21:47 +00:00
// When disabled infinity and NaN on source registers are ignored by the unpacker and thus special case logic.
2022-12-23 20:24:20 +00:00
// X - all except int->fp, store, load, mv int->fp
assign XEnD = ~ ( ( ( FResSelD = = 2 'b10 ) & ~ FWriteIntD ) | // load/store
2023-04-13 23:27:53 +00:00
( ( FResSelD = = 2 'b00 ) & FRegWriteD & ( OpCtrlD = = 3 'b011 ) ) | // mv int to float - There was an issue here, this condition was not refering to mv int -> fp // ((FResSelD==2'b11)&FRegWriteD)|
2022-12-23 20:24:20 +00:00
( ( FResSelD = = 2 'b01 ) & ( PostProcSelD = = 2 'b00 ) & OpCtrlD [ 2 ] ) ) ; // cvt int to float
2022-12-23 20:21:47 +00:00
2022-12-23 20:24:20 +00:00
// Y - all except cvt, mv, load, class, sqrt
2023-04-13 23:27:53 +00:00
assign YEnD = ~ ( ( ( FResSelD = = 2 'b10 ) & ( FWriteIntD | FRegWriteD ) ) | // load or class
( ( FResSelD = = 2 'b00 ) & FRegWriteD & ( OpCtrlD = = 3 'b011 ) ) | // mv int to float as above // previously mv both ways - Another issue here, previously (FResSelD==2'b11)| does not cover mv both way int-> fp and fp-> int
( ( FResSelD = = 2 'b11 ) & ( PostProcSelD = = 2 'b00 ) ) | // mv float to int // mv both ways
2022-12-23 20:24:20 +00:00
( ( FResSelD = = 2 'b01 ) & ( ( PostProcSelD = = 2 'b00 ) | ( ( PostProcSelD = = 2 'b01 ) & OpCtrlD [ 0 ] ) ) ) ) ; // cvt both or sqrt
2022-12-23 18:47:18 +00:00
2023-04-12 20:07:30 +00:00
// Removed (FResSelD==2'b11)| removed to avoid redundancy
2022-12-23 20:24:20 +00:00
// Z - fma ops only
2023-04-12 20:07:30 +00:00
assign ZEnD = ( PostProcSelD = = 2 'b10 ) & ( ~ OpCtrlD [ 2 ] | OpCtrlD [ 1 ] ) ; // fma, add, sub // Removed &(FResSelD==2'b01) because it' redundant, Changed all the xx PostProcSelD to 00 to avoid unnecessary contention errors.
2023-04-13 23:27:53 +00:00
2022-07-20 21:57:23 +00:00
2023-01-12 04:02:30 +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
2023-01-12 04:02:30 +00:00
// post processing Sel:
// 00 cvt
// 01 div
// 10 fma
2021-06-28 22:53:58 +00:00
2023-01-12 04:02:30 +00:00
// Other Sel:
// Ctrl signal = {OpCtrl[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
2023-01-12 04:02:30 +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 - div
// 1 - sqrt
// 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
2022-12-23 18:47:18 +00:00
2023-01-12 04:02:30 +00:00
// rename input adresses for readability
2022-12-23 18:47:18 +00:00
assign Adr1D = InstrD [ 19 : 15 ] ;
assign Adr2D = InstrD [ 24 : 20 ] ;
assign Adr3D = InstrD [ 31 : 27 ] ;
2022-07-20 02:27:39 +00:00
// D/E pipleine register
2023-02-21 17:32:17 +00:00
flopenrc # ( 13 + `FMTBITS ) DECtrlReg3 ( clk , reset , FlushE , ~ StallE ,
{ FRegWriteD , PostProcSelD , FResSelD , FrmD , FmtD , OpCtrlD , FWriteIntD , FCvtIntD } ,
{ FRegWriteE , PostProcSelE , FResSelE , FrmE , FmtE , OpCtrlE , FWriteIntE , FCvtIntE } ) ;
2022-12-23 18:47:18 +00:00
flopenrc # ( 15 ) DEAdrReg ( clk , reset , FlushE , ~ StallE , { Adr1D , Adr2D , Adr3D } , { Adr1E , Adr2E , Adr3E } ) ;
2022-09-29 23:30:25 +00:00
flopenrc # ( 1 ) DEFDivStartReg ( clk , reset , FlushE , ~ StallE | FDivBusyE , FDivStartD , FDivStartE ) ;
2022-12-23 20:21:47 +00:00
flopenrc # ( 3 ) DEEnReg ( clk , reset , FlushE , ~ StallE , { XEnD , YEnD , ZEnD } , { XEnE , YEnE , ZEnE } ) ;
2023-01-11 19:06:37 +00:00
// Integer division on FPU divider
if ( `M_SUPPORTED & `IDIV_ON_FPU ) assign IDivStartE = IntDivE ;
else assign IDivStartE = 0 ;
2022-09-29 23:30:25 +00:00
2022-07-20 02:27:39 +00:00
// E/M pipleine register
2023-02-21 17:32:17 +00:00
flopenrc # ( 13 + int ' ( `FMTBITS ) ) EMCtrlReg ( clk , reset , FlushM , ~ StallM ,
{ FRegWriteE , FResSelE , PostProcSelE , FrmE , FmtE , OpCtrlE , FWriteIntE , FCvtIntE } ,
{ FRegWriteM , FResSelM , PostProcSelM , FrmM , FmtM , OpCtrlM , FWriteIntM , FCvtIntM } ) ;
2023-01-11 20:18:06 +00:00
2023-01-12 04:02:30 +00:00
// renameing for readability
2023-01-11 20:18:06 +00:00
assign FpLoadStoreM = FResSelM [ 1 ] ;
2022-07-20 02:27:39 +00:00
// M/W pipleine register
2022-12-19 17:09:48 +00:00
flopenrc # ( 4 ) MWCtrlReg ( clk , reset , FlushW , ~ StallW ,
{ FRegWriteM , FResSelM , FCvtIntM } ,
{ FRegWriteW , FResSelW , FCvtIntW } ) ;
2023-03-30 20:17:15 +00:00
2021-04-04 18:09:13 +00:00
endmodule