multiclass VPseudoVSQR_V {
foreach m = MxListF in {
defvar mx = m.MX;
- defvar sews = SchedSEWSetF<m.MX>.val;
+ defvar sews = SchedSEWSet<m.MX, /*isF*/ 1>.val;
let VLMul = m.value in
foreach e = sews in {
multiclass VPseudoVFDIV_VV_VF {
foreach m = MxListF in {
defvar mx = m.MX;
- defvar sews = SchedSEWSetF<mx>.val;
+ defvar sews = SchedSEWSet<mx, /*isF*/ 1>.val;
foreach e = sews in {
defvar WriteVFDivV_MX_E = !cast<SchedWrite>("WriteVFDivV_" # mx # "_E" # e);
defvar ReadVFDivV_MX_E = !cast<SchedRead>("ReadVFDivV_" # mx # "_E" # e);
foreach f = FPList in {
foreach m = f.MxList in {
defvar mx = m.MX;
- defvar sews = SchedSEWSetF<mx>.val;
+ defvar sews = SchedSEWSet<mx, /*isF*/ 1>.val;
foreach e = sews in {
defvar WriteVFDivF_MX_E = !cast<SchedWrite>("WriteVFDivF_" # mx # "_E" # e);
defvar ReadVFDivV_MX_E = !cast<SchedRead>("ReadVFDivV_" # mx # "_E" # e);
foreach f = FPList in {
foreach m = f.MxList in {
defvar mx = m.MX;
- defvar sews = SchedSEWSetF<mx>.val;
+ defvar sews = SchedSEWSet<mx, /*isF*/ 1>.val;
foreach e = sews in {
defvar WriteVFDivF_MX_E = !cast<SchedWrite>("WriteVFDivF_" # mx # "_E" # e);
defvar ReadVFDivV_MX_E = !cast<SchedRead>("ReadVFDivV_" # mx # "_E" # e);
multiclass VPseudoVWRED_VS {
foreach m = MxListWRed in {
defvar mx = m.MX;
- foreach e = SchedSEWSet<mx, 1>.val in {
+ foreach e = SchedSEWSet<mx, /*isF*/ 0, /*isWidening*/ 1>.val in {
defvar WriteVIWRedV_From_MX_E = !cast<SchedWrite>("WriteVIWRedV_From_" # mx # "_E" # e);
defm _VS : VPseudoTernaryWithTailPolicy_E<V_M1.vrclass, m.vrclass, V_M1.vrclass, m, e>,
Sched<[WriteVIWRedV_From_MX_E, ReadVIWRedV, ReadVIWRedV,
multiclass VPseudoVFRED_VS {
foreach m = MxListF in {
defvar mx = m.MX;
- foreach e = SchedSEWSetF<mx>.val in {
+ foreach e = SchedSEWSet<mx, /*isF*/ 1>.val in {
defvar WriteVFRedV_From_MX_E = !cast<SchedWrite>("WriteVFRedV_From_" # mx # "_E" # e);
defm _VS : VPseudoTernaryWithTailPolicy_E<V_M1.vrclass, m.vrclass, V_M1.vrclass, m, e>,
Sched<[WriteVFRedV_From_MX_E, ReadVFRedV, ReadVFRedV, ReadVFRedV,
multiclass VPseudoVFREDO_VS {
foreach m = MxListF in {
defvar mx = m.MX;
- foreach e = SchedSEWSetF<mx>.val in {
+ foreach e = SchedSEWSet<mx, /*isF*/ 1>.val in {
defvar WriteVFRedOV_From_MX_E = !cast<SchedWrite>("WriteVFRedOV_From_" # mx # "_E" # e);
defm _VS : VPseudoTernaryWithTailPolicy_E<V_M1.vrclass, m.vrclass, V_M1.vrclass, m, e>,
Sched<[WriteVFRedOV_From_MX_E, ReadVFRedOV, ReadVFRedOV,
multiclass VPseudoVFWRED_VS {
foreach m = MxListFWRed in {
defvar mx = m.MX;
- foreach e = SchedSEWSetF<mx, 1>.val in {
+ foreach e = SchedSEWSet<mx, /*isF*/ 1, /*isWidening*/ 1>.val in {
defvar WriteVFWRedV_From_MX_E = !cast<SchedWrite>("WriteVFWRedV_From_" # mx # "_E" # e);
defm _VS : VPseudoTernaryWithTailPolicy_E<V_M1.vrclass, m.vrclass, V_M1.vrclass, m, e>,
Sched<[WriteVFWRedV_From_MX_E, ReadVFWRedV, ReadVFWRedV,
// Used for widening floating-point Reduction as it doesn't contain MF8.
defvar SchedMxListFWRed = SchedMxListF;
-// For widening instructions, SEW will not be 64.
-class SchedSEWSet<string mx, bit isWidening = 0> {
+class SchedSEWSet<string mx, bit isF = 0, bit isWidening = 0> {
+ assert !or(!not(isF), !ne(mx, "MF8")), "LMUL shouldn't be MF8 for floating-point";
defvar t = !cond(!eq(mx, "M1"): [8, 16, 32, 64],
!eq(mx, "M2"): [8, 16, 32, 64],
!eq(mx, "M4"): [8, 16, 32, 64],
!eq(mx, "MF2"): [8, 16, 32],
!eq(mx, "MF4"): [8, 16],
!eq(mx, "MF8"): [8]);
- list<int> val = !if(isWidening, !listremove(t, [64]), t);
-}
-
-// For floating-point instructions, SEW won't be 8.
-class SchedSEWSetF<string mx, bit isWidening = 0> {
- defvar t = !cond(!eq(mx, "M1"): [16, 32, 64],
- !eq(mx, "M2"): [16, 32, 64],
- !eq(mx, "M4"): [16, 32, 64],
- !eq(mx, "M8"): [16, 32, 64],
- !eq(mx, "MF2"): [16, 32],
- !eq(mx, "MF4"): [16]);
- list<int> val = !if(isWidening, !listremove(t, [64]), t);
+ // For floating-point instructions, SEW won't be 8.
+ defvar remove8 = !if(isF, !listremove(t, [8]), t);
+ // For widening instructions, SEW will not be 64.
+ defvar remove64 = !if(isWidening, !listremove(remove8, [64]), remove8);
+ list<int> val = remove64;
}
// Helper function to get the largest LMUL from MxList
// Helper function to get the smallest SEW that can be used with LMUL mx
// Precondition: MxList is sorted in ascending LMUL order and SchedSEWSet<mx>
class SmallestSEW<string mx, bit isF = 0> {
- int r = !head(!if(isF, SchedSEWSetF<mx>.val, SchedSEWSet<mx>.val));
+ int r = !head(SchedSEWSet<mx, isF>.val);
}
// Creates WriteRes for (name, mx, resources) tuple
bit isWidening = 0> {
def name # "_WorstCase" : SchedWrite;
foreach mx = MxList in {
- foreach sew = !if(isF, SchedSEWSetF<mx, isWidening>.val,
- SchedSEWSet<mx, isWidening>.val) in
+ foreach sew = SchedSEWSet<mx, isF, isWidening>.val in
def name # "_" # mx # "_E" # sew : SchedWrite;
}
}
bit isWidening = 0> {
def name # "_WorstCase" : SchedRead;
foreach mx = MxList in {
- foreach sew = !if(isF,SchedSEWSetF<mx, isWidening>.val,
- SchedSEWSet<mx, isWidening>.val) in
+ foreach sew = SchedSEWSet<mx, isF, isWidening>.val in
def name # "_" # mx # "_E" # sew : SchedRead;
}
}
if !exists<SchedWrite>(name # "_WorstCase") then
def : WriteRes<!cast<SchedWrite>(name # "_WorstCase"), resources>;
foreach mx = MxList in {
- foreach sew = !if(isF,SchedSEWSetF<mx, isWidening>.val,
- SchedSEWSet<mx, isWidening>.val) in
+ foreach sew = SchedSEWSet<mx, isF, isWidening>.val in
if !exists<SchedWrite>(name # "_" # mx # "_E" # sew) then
def : WriteRes<!cast<SchedWrite>(name # "_" # mx # "_E" # sew), resources>;
}
if !exists<SchedRead>(name # "_WorstCase") then
def : ReadAdvance<!cast<SchedRead>(name # "_WorstCase"), val, writes>;
foreach mx = MxList in {
- foreach sew = !if(isF,SchedSEWSetF<mx, isWidening>.val,
- SchedSEWSet<mx, isWidening>.val) in
+ foreach sew = SchedSEWSet<mx, isF, isWidening>.val in
if !exists<SchedRead>(name # "_" # mx # "_E" # sew) then
def : ReadAdvance<!cast<SchedRead>(name # "_" # mx # "_E" # sew), val, writes>;
}