@@ -127,9 +127,10 @@ class MicroOpEncoding<T extends MicroOp> {
127127 required this .constructor,
128128 });
129129
130- int encode (T op, Mxlen mxlen) => struct (mxlen).encode (op.toMap ());
130+ BigInt encode (T op, Mxlen mxlen) => struct (mxlen).bigEncode (op.toMap ());
131131
132- T decode (int value, Mxlen mxlen) => constructor (struct (mxlen).decode (value));
132+ T decode (BigInt value, Mxlen mxlen) =>
133+ constructor (struct (mxlen).bigDecode (value));
133134}
134135
135136/// {@category microcode}
@@ -270,6 +271,8 @@ enum MicroOpMemSize {
270271 final int bytes;
271272
272273 int get bits => bytes * 8 ;
274+
275+ static const int width = 2 ;
273276}
274277
275278/// {@category microcode}
@@ -300,9 +303,9 @@ class WriteCsrMicroOp extends MicroOp {
300303
301304 static BitStruct struct (Mxlen mxlen) => BitStruct ({
302305 'funct' : MicroOp .functRange,
303- 'field' : const BitRange (5 , 8 ),
304- 'source' : const BitRange (9 , 12 ),
305- 'offset' : BitRange (13 , 13 + mxlen.size),
306+ 'field' : const BitRange (5 , 7 ),
307+ 'source' : const BitRange (8 , 10 ),
308+ 'offset' : BitRange (11 , 11 + mxlen.size),
306309 });
307310}
308311
@@ -339,9 +342,9 @@ class ReadRegisterMicroOp extends MicroOp {
339342
340343 static BitStruct struct (Mxlen mxlen) => BitStruct ({
341344 'funct' : MicroOp .functRange,
342- 'source' : const BitRange (5 , 8 ),
343- 'offset' : BitRange (9 , 9 + mxlen.size),
344- 'valueOffset' : BitRange (9 + mxlen.size, 9 + (mxlen.size * 2 )),
345+ 'source' : const BitRange (5 , 7 ),
346+ 'offset' : BitRange (8 , 8 + mxlen.size - 1 ),
347+ 'valueOffset' : BitRange (8 + mxlen.size, 8 + (mxlen.size * 2 ) - 1 ),
345348 });
346349}
347350
@@ -382,10 +385,10 @@ class WriteRegisterMicroOp extends MicroOp {
382385
383386 static BitStruct struct (Mxlen mxlen) => BitStruct ({
384387 'funct' : MicroOp .functRange,
385- 'field' : const BitRange (5 , 8 ),
386- 'source' : const BitRange (9 , 12 ),
387- 'offset' : BitRange (13 , 13 + mxlen.size),
388- 'valueOffset' : BitRange (13 + mxlen.size, 13 + (mxlen.size * 2 )),
388+ 'field' : const BitRange (5 , 7 ),
389+ 'source' : const BitRange (8 , 10 ),
390+ 'offset' : BitRange (11 , 11 + mxlen.size - 1 ),
391+ 'valueOffset' : BitRange (11 + mxlen.size, 11 + (mxlen.size * 2 ) - 1 ),
389392 });
390393}
391394
@@ -417,9 +420,9 @@ class ModifyLatchMicroOp extends MicroOp {
417420
418421 static BitStruct struct (Mxlen _) => BitStruct ({
419422 'funct' : MicroOp .functRange,
420- 'field' : const BitRange (5 , 8 ),
421- 'source' : const BitRange (9 , 12 ),
422- 'replace' : BitRange .single (13 ),
423+ 'field' : const BitRange (5 , 7 ),
424+ 'source' : const BitRange (8 , 10 ),
425+ 'replace' : BitRange .single (11 ),
423426 });
424427}
425428
@@ -451,9 +454,9 @@ class AluMicroOp extends MicroOp {
451454
452455 static BitStruct struct (Mxlen _) => BitStruct ({
453456 'funct' : MicroOp .functRange,
454- 'alu' : const BitRange (5 , 10 ),
455- 'a' : const BitRange (11 , 14 ),
456- 'b' : const BitRange (15 , 18 ),
457+ 'alu' : const BitRange (5 , 9 ),
458+ 'a' : const BitRange (10 , 12 ),
459+ 'b' : const BitRange (13 , 15 ),
457460 });
458461}
459462
@@ -497,11 +500,11 @@ class BranchIfMicroOp extends MicroOp {
497500
498501 static BitStruct struct (Mxlen mxlen) => BitStruct ({
499502 'funct' : MicroOp .functRange,
500- 'condition' : const BitRange (5 , 10 ),
501- 'target' : const BitRange (11 , 14 ),
502- 'hasField' : const BitRange .single (15 ),
503- 'offsetField' : const BitRange (16 , 19 ),
504- 'offset' : BitRange (20 , 20 + mxlen.size),
503+ 'condition' : const BitRange (5 , 7 ),
504+ 'target' : const BitRange (8 , 10 ),
505+ 'hasField' : const BitRange .single (11 ),
506+ 'offsetField' : const BitRange (12 , 14 ),
507+ 'offset' : BitRange (15 , 15 + mxlen.size - 1 ),
505508 });
506509}
507510
@@ -559,11 +562,11 @@ class UpdatePCMicroOp extends MicroOp {
559562 'source' : const BitRange (5 , 8 ),
560563 'hasSource' : const BitRange .single (9 ),
561564 'hasField' : const BitRange .single (10 ),
562- 'offsetField' : const BitRange (11 , 14 ),
563- 'offsetSource' : const BitRange (15 , 17 ),
564- 'absolute' : const BitRange .single (18 ),
565- 'align' : const BitRange .single (19 ),
566- 'offset' : BitRange (20 , 20 + mxlen.size),
565+ 'offsetField' : const BitRange (11 , 13 ),
566+ 'offsetSource' : const BitRange (14 , 16 ),
567+ 'absolute' : const BitRange .single (17 ),
568+ 'align' : const BitRange .single (18 ),
569+ 'offset' : BitRange (19 , 19 + mxlen.size - 1 ),
567570 });
568571}
569572
@@ -604,10 +607,10 @@ class MemLoadMicroOp extends MicroOp {
604607
605608 static BitStruct struct (Mxlen _) => BitStruct ({
606609 'funct' : MicroOp .functRange,
607- 'base' : const BitRange (5 , 8 ),
608- 'dest' : const BitRange (9 , 12 ),
609- 'size' : const BitRange (13 , 14 ),
610- 'unsigned' : BitRange .single (15 ),
610+ 'base' : const BitRange (5 , 7 ),
611+ 'dest' : const BitRange (8 , 10 ),
612+ 'size' : const BitRange (11 , 12 ),
613+ 'unsigned' : BitRange .single (13 ),
611614 });
612615}
613616
@@ -643,9 +646,9 @@ class MemStoreMicroOp extends MicroOp {
643646
644647 static BitStruct struct (Mxlen _) => BitStruct ({
645648 'funct' : MicroOp .functRange,
646- 'base' : const BitRange (5 , 8 ),
647- 'src' : const BitRange (9 , 12 ),
648- 'size' : const BitRange (13 , 14 ),
649+ 'base' : const BitRange (5 , 7 ),
650+ 'src' : const BitRange (8 , 10 ),
651+ 'size' : const BitRange (11 , 12 ),
649652 });
650653}
651654
@@ -672,10 +675,8 @@ class TrapMicroOp extends MicroOp {
672675 Map <String , int > toMap () => {
673676 'funct' : funct,
674677 'machine' : kindMachine.index,
675- 'hasSupervisor' : kindSupervisor != null ? 1 : 0 ,
676- 'supervisor' : kindSupervisor? .index ?? 0 ,
677- 'hasUser' : kindUser != null ? 1 : 0 ,
678- 'user' : kindUser? .index ?? 0 ,
678+ 'supervisor' : kindSupervisor? .index ?? kindMachine.index,
679+ 'user' : kindSupervisor? .index ?? kindMachine.index,
679680 };
680681
681682 @override
@@ -685,12 +686,9 @@ class TrapMicroOp extends MicroOp {
685686
686687 static BitStruct struct (Mxlen _) => BitStruct ({
687688 'funct' : MicroOp .functRange,
688- // 8 bits per trap kind
689- 'machine' : const BitRange (5 , 12 ),
690- 'supervisor' : const BitRange (13 , 20 ),
691- 'user' : const BitRange (21 , 28 ),
692- 'hasSupervisor' : BitRange .single (29 ),
693- 'hasUser' : BitRange .single (30 ),
689+ 'machine' : const BitRange (5 , 9 ),
690+ 'supervisor' : const BitRange (10 , 14 ),
691+ 'user' : const BitRange (15 , 19 ),
694692 });
695693}
696694
@@ -808,8 +806,8 @@ class WriteLinkRegisterMicroOp extends MicroOp {
808806
809807 static BitStruct struct (Mxlen mxlen) => BitStruct ({
810808 'funct' : MicroOp .functRange,
811- 'link' : const BitRange ( 5 , 7 ),
812- 'pcOffset' : BitRange (8 , 8 + mxlen.size),
809+ 'link' : const BitRange . single ( 5 ),
810+ 'pcOffset' : BitRange (6 , 6 + mxlen.size - 1 ),
813811 });
814812}
815813
@@ -984,9 +982,9 @@ class ValidateFieldMicroOp extends MicroOp {
984982
985983 static BitStruct struct (Mxlen mxlen) => BitStruct ({
986984 'funct' : MicroOp .functRange,
987- 'condition' : const BitRange (5 , 8 ),
988- 'field' : const BitRange (9 , 12 ),
989- 'value' : BitRange (12 , 12 + mxlen.size),
985+ 'condition' : const BitRange (5 , 7 ),
986+ 'field' : const BitRange (8 , 10 ),
987+ 'value' : BitRange (10 , 10 + mxlen.size - 1 ),
990988 });
991989}
992990
@@ -1015,8 +1013,8 @@ class SetFieldMicroOp extends MicroOp {
10151013
10161014 static BitStruct struct (Mxlen mxlen) => BitStruct ({
10171015 'funct' : MicroOp .functRange,
1018- 'field' : const BitRange (5 , 8 ),
1019- 'value' : BitRange (9 , 9 + mxlen.size),
1016+ 'field' : const BitRange (5 , 7 ),
1017+ 'value' : BitRange (8 , 8 + mxlen.size - 1 ),
10201018 });
10211019}
10221020
@@ -1035,11 +1033,10 @@ class ReadCsrMicroOp extends MicroOp {
10351033 @override
10361034 String toString () => 'ReadCsrMicroOp($source )' ;
10371035
1038- // NOTE: must be unique, SetField uses 21
10391036 static const int funct = 22 ;
10401037
10411038 static BitStruct struct (Mxlen _) =>
1042- BitStruct ({'funct' : MicroOp .functRange, 'source' : const BitRange (5 , 8 )});
1039+ BitStruct ({'funct' : MicroOp .functRange, 'source' : const BitRange (5 , 7 )});
10431040}
10441041
10451042class OperationDecodePattern {
@@ -1268,21 +1265,25 @@ class Operation<T extends InstructionType> {
12681265
12691266 bool matches (InstructionType instr) => _mapMatch (instr.toMap ());
12701267
1271- int microcodeWidth (Mxlen mxlen) => microcode
1268+ int mopWidth (Mxlen mxlen) => microcode
12721269 .map ((mop) {
12731270 final m = mop.toMap ();
12741271 final funct = m['funct' ]! ;
12751272 final e = kMicroOpTable.firstWhere ((e) => e.funct == funct);
1276- final s = e.struct (mxlen);
1277-
1278- for (final field in s.mapping.entries) {
1279- m[field.key] = field.value.mask;
1280- }
1281-
1282- return s.encode (m).bitLength;
1273+ return e.struct (mxlen).width;
12831274 })
12841275 .fold (0 , (a, b) => a > b ? a : b);
12851276
1277+ List <BigInt > mopEncode (Mxlen mxlen) => [
1278+ BigInt .from (microcode.length),
1279+ ...microcode.map ((mop) {
1280+ final m = mop.toMap ();
1281+ final funct = m['funct' ]! ;
1282+ final e = kMicroOpTable.firstWhere ((e) => e.funct == funct);
1283+ return e.struct (mxlen).bigEncode (m);
1284+ }),
1285+ ];
1286+
12861287 @override
12871288 String toString () =>
12881289 'Operation(mnemonic: $mnemonic , opcode: $opcode , funct2: $funct2 ,'
@@ -1385,12 +1386,19 @@ class Microcode {
13851386 fieldIndices,
13861387 ).width;
13871388
1388- int get opIndexWidth => decodeLookup.keys.fold (0 , (a, b) => a > b ? a : b);
1389+ int get opIndexWidth =>
1390+ decodeLookup.keys.fold (0 , (a, b) => a > b ? a : b).bitLength;
13891391
1390- int opWidth (Mxlen mxlen) => map.values
1391- .map ((op) => op.microcodeWidth (mxlen))
1392+ int mopWidth (Mxlen mxlen) => map.values
1393+ .map ((op) => op.mopWidth (mxlen))
13921394 .fold (0 , (a, b) => a > b ? a : b);
13931395
1396+ int mopIndexWidth (Mxlen mxlen) => encodedMops (mxlen).length.bitLength;
1397+
1398+ List <BigInt > encodedMops (Mxlen mxlen) => map.values
1399+ .map ((m) => m.mopEncode (mxlen))
1400+ .fold ([], (a, b) => [...a, ...b]);
1401+
13941402 Map <int , OperationDecodePattern > get decodeLookup {
13951403 Map <int , OperationDecodePattern > result = {};
13961404 var i = 0 ;
@@ -1621,4 +1629,9 @@ class Microcode {
16211629 final name = i.runtimeType.toString ();
16221630 return name.substring (10 , name.length - 1 );
16231631 }
1632+
1633+ static String mopType <T extends MicroOp >(MicroOpEncoding <T > i) {
1634+ final name = i.runtimeType.toString ();
1635+ return name.substring (16 , name.length - 8 );
1636+ }
16241637}
0 commit comments