-
Notifications
You must be signed in to change notification settings - Fork 0
/
blackBoxIbexCore.preprocessed.sv
19140 lines (16518 loc) · 722 KB
/
blackBoxIbexCore.preprocessed.sv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
`define VERILATOR
`define VERILATOR
// Copyright lowRISC contributors.
// Copyright 2017 ETH Zurich and University of Bologna, see also CREDITS.md.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
/**
* Package with constants used by Ibex
*/
package ibex_pkg;
////////////////
// IO Structs //
////////////////
typedef struct packed {
logic [31:0] current_pc;
logic [31:0] next_pc;
logic [31:0] last_data_addr;
logic [31:0] exception_addr;
} crash_dump_t;
typedef struct packed {
logic dummy_instr_id;
logic [4:0] raddr_a;
logic [4:0] waddr_a;
logic we_a;
logic [4:0] raddr_b;
} core2rf_t;
/////////////////////
// Parameter Enums //
/////////////////////
typedef enum integer {
RegFileFF = 0,
RegFileFPGA = 1,
RegFileLatch = 2
} regfile_e;
typedef enum integer {
RV32MNone = 0,
RV32MSlow = 1,
RV32MFast = 2,
RV32MSingleCycle = 3
} rv32m_e;
typedef enum integer {
RV32BNone = 0,
RV32BBalanced = 1,
RV32BFull = 2
} rv32b_e;
/////////////
// Opcodes //
/////////////
typedef enum logic [6:0] {
OPCODE_LOAD = 7'h03,
OPCODE_MISC_MEM = 7'h0f,
OPCODE_OP_IMM = 7'h13,
OPCODE_AUIPC = 7'h17,
OPCODE_STORE = 7'h23,
OPCODE_OP = 7'h33,
OPCODE_LUI = 7'h37,
OPCODE_BRANCH = 7'h63,
OPCODE_JALR = 7'h67,
OPCODE_JAL = 7'h6f,
OPCODE_SYSTEM = 7'h73
} opcode_e;
////////////////////
// ALU operations //
////////////////////
typedef enum logic [5:0] {
// Arithmetics
ALU_ADD,
ALU_SUB,
// Logics
ALU_XOR,
ALU_OR,
ALU_AND,
// RV32B
ALU_XNOR,
ALU_ORN,
ALU_ANDN,
// Shifts
ALU_SRA,
ALU_SRL,
ALU_SLL,
// RV32B
ALU_SRO,
ALU_SLO,
ALU_ROR,
ALU_ROL,
ALU_GREV,
ALU_GORC,
ALU_SHFL,
ALU_UNSHFL,
// Comparisons
ALU_LT,
ALU_LTU,
ALU_GE,
ALU_GEU,
ALU_EQ,
ALU_NE,
// RV32B
ALU_MIN,
ALU_MINU,
ALU_MAX,
ALU_MAXU,
// Pack
// RV32B
ALU_PACK,
ALU_PACKU,
ALU_PACKH,
// Sign-Extend
// RV32B
ALU_SEXTB,
ALU_SEXTH,
// Bitcounting
// RV32B
ALU_CLZ,
ALU_CTZ,
ALU_PCNT,
// Set lower than
ALU_SLT,
ALU_SLTU,
// Ternary Bitmanip Operations
// RV32B
ALU_CMOV,
ALU_CMIX,
ALU_FSL,
ALU_FSR,
// Single-Bit Operations
// RV32B
ALU_SBSET,
ALU_SBCLR,
ALU_SBINV,
ALU_SBEXT,
// Bit Extract / Deposit
// RV32B
ALU_BEXT,
ALU_BDEP,
// Bit Field Place
// RV32B
ALU_BFP,
// Carry-less Multiply
// RV32B
ALU_CLMUL,
ALU_CLMULR,
ALU_CLMULH,
// Cyclic Redundancy Check
ALU_CRC32_B,
ALU_CRC32C_B,
ALU_CRC32_H,
ALU_CRC32C_H,
ALU_CRC32_W,
ALU_CRC32C_W
} alu_op_e;
typedef enum logic [1:0] {
// Multiplier/divider
MD_OP_MULL,
MD_OP_MULH,
MD_OP_DIV,
MD_OP_REM
} md_op_e;
//////////////////////////////////
// Control and status registers //
//////////////////////////////////
// CSR operations
typedef enum logic [1:0] {
CSR_OP_READ,
CSR_OP_WRITE,
CSR_OP_SET,
CSR_OP_CLEAR
} csr_op_e;
// Privileged mode
typedef enum logic[1:0] {
PRIV_LVL_M = 2'b11,
PRIV_LVL_H = 2'b10,
PRIV_LVL_S = 2'b01,
PRIV_LVL_U = 2'b00
} priv_lvl_e;
// Constants for the dcsr.xdebugver fields
typedef enum logic[3:0] {
XDEBUGVER_NO = 4'd0, // no external debug support
XDEBUGVER_STD = 4'd4, // external debug according to RISC-V debug spec
XDEBUGVER_NONSTD = 4'd15 // debug not conforming to RISC-V debug spec
} x_debug_ver_e;
//////////////
// WB stage //
//////////////
// Type of instruction present in writeback stage
typedef enum logic[1:0] {
WB_INSTR_LOAD, // Instruction is awaiting load data
WB_INSTR_STORE, // Instruction is awaiting store response
WB_INSTR_OTHER // Instruction doesn't fit into above categories
} wb_instr_type_e;
//////////////
// ID stage //
//////////////
// Operand a selection
typedef enum logic[1:0] {
OP_A_REG_A,
OP_A_FWD,
OP_A_CURRPC,
OP_A_IMM
} op_a_sel_e;
// Immediate a selection
typedef enum logic {
IMM_A_Z,
IMM_A_ZERO
} imm_a_sel_e;
// Operand b selection
typedef enum logic {
OP_B_REG_B,
OP_B_IMM
} op_b_sel_e;
// Immediate b selection
typedef enum logic [2:0] {
IMM_B_I,
IMM_B_S,
IMM_B_B,
IMM_B_U,
IMM_B_J,
IMM_B_INCR_PC,
IMM_B_INCR_ADDR
} imm_b_sel_e;
// Regfile write data selection
typedef enum logic {
RF_WD_EX,
RF_WD_CSR
} rf_wd_sel_e;
//////////////
// IF stage //
//////////////
// PC mux selection
typedef enum logic [2:0] {
PC_BOOT,
PC_JUMP,
PC_EXC,
PC_ERET,
PC_DRET,
PC_BP
} pc_sel_e;
// Exception PC mux selection
typedef enum logic [1:0] {
EXC_PC_EXC,
EXC_PC_IRQ,
EXC_PC_DBD,
EXC_PC_DBG_EXC // Exception while in debug mode
} exc_pc_sel_e;
// Interrupt requests
typedef struct packed {
logic irq_software;
logic irq_timer;
logic irq_external;
logic [14:0] irq_fast; // 15 fast interrupts,
// one interrupt is reserved for NMI (not visible through mip/mie)
} irqs_t;
// Exception cause
typedef enum logic [5:0] {
EXC_CAUSE_IRQ_SOFTWARE_M = {1'b1, 5'd03},
EXC_CAUSE_IRQ_TIMER_M = {1'b1, 5'd07},
EXC_CAUSE_IRQ_EXTERNAL_M = {1'b1, 5'd11},
// EXC_CAUSE_IRQ_FAST_0 = {1'b1, 5'd16},
// EXC_CAUSE_IRQ_FAST_14 = {1'b1, 5'd30},
EXC_CAUSE_IRQ_NM = {1'b1, 5'd31}, // == EXC_CAUSE_IRQ_FAST_15
EXC_CAUSE_INSN_ADDR_MISA = {1'b0, 5'd00},
EXC_CAUSE_INSTR_ACCESS_FAULT = {1'b0, 5'd01},
EXC_CAUSE_ILLEGAL_INSN = {1'b0, 5'd02},
EXC_CAUSE_BREAKPOINT = {1'b0, 5'd03},
EXC_CAUSE_LOAD_ACCESS_FAULT = {1'b0, 5'd05},
EXC_CAUSE_STORE_ACCESS_FAULT = {1'b0, 5'd07},
EXC_CAUSE_ECALL_UMODE = {1'b0, 5'd08},
EXC_CAUSE_ECALL_MMODE = {1'b0, 5'd11}
} exc_cause_e;
// Debug cause
typedef enum logic [2:0] {
DBG_CAUSE_NONE = 3'h0,
DBG_CAUSE_EBREAK = 3'h1,
DBG_CAUSE_TRIGGER = 3'h2,
DBG_CAUSE_HALTREQ = 3'h3,
DBG_CAUSE_STEP = 3'h4
} dbg_cause_e;
// ICache constants
parameter int unsigned ADDR_W = 32;
parameter int unsigned BUS_SIZE = 32;
parameter int unsigned BUS_BYTES = BUS_SIZE/8;
parameter int unsigned BUS_W = $clog2(BUS_BYTES);
parameter int unsigned IC_SIZE_BYTES = 4096;
parameter int unsigned IC_NUM_WAYS = 2;
parameter int unsigned IC_LINE_SIZE = 64;
parameter int unsigned IC_LINE_BYTES = IC_LINE_SIZE/8;
parameter int unsigned IC_LINE_W = $clog2(IC_LINE_BYTES);
parameter int unsigned IC_NUM_LINES = IC_SIZE_BYTES / IC_NUM_WAYS / IC_LINE_BYTES;
parameter int unsigned IC_LINE_BEATS = IC_LINE_BYTES / BUS_BYTES;
parameter int unsigned IC_LINE_BEATS_W = $clog2(IC_LINE_BEATS);
parameter int unsigned IC_INDEX_W = $clog2(IC_NUM_LINES);
parameter int unsigned IC_INDEX_HI = IC_INDEX_W + IC_LINE_W - 1;
parameter int unsigned IC_TAG_SIZE = ADDR_W - IC_INDEX_W - IC_LINE_W + 1; // 1 valid bit
parameter int unsigned IC_OUTPUT_BEATS = (BUS_BYTES / 2); // number of halfwords
// PMP constants
parameter int unsigned PMP_MAX_REGIONS = 16;
parameter int unsigned PMP_CFG_W = 8;
// PMP acces type
parameter int unsigned PMP_I = 0;
parameter int unsigned PMP_D = 1;
typedef enum logic [1:0] {
PMP_ACC_EXEC = 2'b00,
PMP_ACC_WRITE = 2'b01,
PMP_ACC_READ = 2'b10
} pmp_req_e;
// PMP cfg structures
typedef enum logic [1:0] {
PMP_MODE_OFF = 2'b00,
PMP_MODE_TOR = 2'b01,
PMP_MODE_NA4 = 2'b10,
PMP_MODE_NAPOT = 2'b11
} pmp_cfg_mode_e;
typedef struct packed {
logic lock;
pmp_cfg_mode_e mode;
logic exec;
logic write;
logic read;
} pmp_cfg_t;
// Machine Security Configuration (ePMP)
typedef struct packed {
logic rlb; // Rule Locking Bypass
logic mmwp; // Machine Mode Whitelist Policy
logic mml; // Machine Mode Lockdown
} pmp_mseccfg_t;
// CSRs
typedef enum logic[11:0] {
// Machine information
CSR_MHARTID = 12'hF14,
// Machine trap setup
CSR_MSTATUS = 12'h300,
CSR_MISA = 12'h301,
CSR_MIE = 12'h304,
CSR_MTVEC = 12'h305,
CSR_MCOUNTEREN= 12'h306,
// Machine trap handling
CSR_MSCRATCH = 12'h340,
CSR_MEPC = 12'h341,
CSR_MCAUSE = 12'h342,
CSR_MTVAL = 12'h343,
CSR_MIP = 12'h344,
// Physical memory protection
CSR_PMPCFG0 = 12'h3A0,
CSR_PMPCFG1 = 12'h3A1,
CSR_PMPCFG2 = 12'h3A2,
CSR_PMPCFG3 = 12'h3A3,
CSR_PMPADDR0 = 12'h3B0,
CSR_PMPADDR1 = 12'h3B1,
CSR_PMPADDR2 = 12'h3B2,
CSR_PMPADDR3 = 12'h3B3,
CSR_PMPADDR4 = 12'h3B4,
CSR_PMPADDR5 = 12'h3B5,
CSR_PMPADDR6 = 12'h3B6,
CSR_PMPADDR7 = 12'h3B7,
CSR_PMPADDR8 = 12'h3B8,
CSR_PMPADDR9 = 12'h3B9,
CSR_PMPADDR10 = 12'h3BA,
CSR_PMPADDR11 = 12'h3BB,
CSR_PMPADDR12 = 12'h3BC,
CSR_PMPADDR13 = 12'h3BD,
CSR_PMPADDR14 = 12'h3BE,
CSR_PMPADDR15 = 12'h3BF,
// ePMP control
CSR_MSECCFG = 12'h747,
CSR_MSECCFGH = 12'h757,
// Debug trigger
CSR_TSELECT = 12'h7A0,
CSR_TDATA1 = 12'h7A1,
CSR_TDATA2 = 12'h7A2,
CSR_TDATA3 = 12'h7A3,
CSR_MCONTEXT = 12'h7A8,
CSR_SCONTEXT = 12'h7AA,
// Debug/trace
CSR_DCSR = 12'h7b0,
CSR_DPC = 12'h7b1,
// Debug
CSR_DSCRATCH0 = 12'h7b2, // optional
CSR_DSCRATCH1 = 12'h7b3, // optional
// Machine Counter/Timers
CSR_MCOUNTINHIBIT = 12'h320,
CSR_MHPMEVENT3 = 12'h323,
CSR_MHPMEVENT4 = 12'h324,
CSR_MHPMEVENT5 = 12'h325,
CSR_MHPMEVENT6 = 12'h326,
CSR_MHPMEVENT7 = 12'h327,
CSR_MHPMEVENT8 = 12'h328,
CSR_MHPMEVENT9 = 12'h329,
CSR_MHPMEVENT10 = 12'h32A,
CSR_MHPMEVENT11 = 12'h32B,
CSR_MHPMEVENT12 = 12'h32C,
CSR_MHPMEVENT13 = 12'h32D,
CSR_MHPMEVENT14 = 12'h32E,
CSR_MHPMEVENT15 = 12'h32F,
CSR_MHPMEVENT16 = 12'h330,
CSR_MHPMEVENT17 = 12'h331,
CSR_MHPMEVENT18 = 12'h332,
CSR_MHPMEVENT19 = 12'h333,
CSR_MHPMEVENT20 = 12'h334,
CSR_MHPMEVENT21 = 12'h335,
CSR_MHPMEVENT22 = 12'h336,
CSR_MHPMEVENT23 = 12'h337,
CSR_MHPMEVENT24 = 12'h338,
CSR_MHPMEVENT25 = 12'h339,
CSR_MHPMEVENT26 = 12'h33A,
CSR_MHPMEVENT27 = 12'h33B,
CSR_MHPMEVENT28 = 12'h33C,
CSR_MHPMEVENT29 = 12'h33D,
CSR_MHPMEVENT30 = 12'h33E,
CSR_MHPMEVENT31 = 12'h33F,
CSR_MCYCLE = 12'hB00,
CSR_MINSTRET = 12'hB02,
CSR_MHPMCOUNTER3 = 12'hB03,
CSR_MHPMCOUNTER4 = 12'hB04,
CSR_MHPMCOUNTER5 = 12'hB05,
CSR_MHPMCOUNTER6 = 12'hB06,
CSR_MHPMCOUNTER7 = 12'hB07,
CSR_MHPMCOUNTER8 = 12'hB08,
CSR_MHPMCOUNTER9 = 12'hB09,
CSR_MHPMCOUNTER10 = 12'hB0A,
CSR_MHPMCOUNTER11 = 12'hB0B,
CSR_MHPMCOUNTER12 = 12'hB0C,
CSR_MHPMCOUNTER13 = 12'hB0D,
CSR_MHPMCOUNTER14 = 12'hB0E,
CSR_MHPMCOUNTER15 = 12'hB0F,
CSR_MHPMCOUNTER16 = 12'hB10,
CSR_MHPMCOUNTER17 = 12'hB11,
CSR_MHPMCOUNTER18 = 12'hB12,
CSR_MHPMCOUNTER19 = 12'hB13,
CSR_MHPMCOUNTER20 = 12'hB14,
CSR_MHPMCOUNTER21 = 12'hB15,
CSR_MHPMCOUNTER22 = 12'hB16,
CSR_MHPMCOUNTER23 = 12'hB17,
CSR_MHPMCOUNTER24 = 12'hB18,
CSR_MHPMCOUNTER25 = 12'hB19,
CSR_MHPMCOUNTER26 = 12'hB1A,
CSR_MHPMCOUNTER27 = 12'hB1B,
CSR_MHPMCOUNTER28 = 12'hB1C,
CSR_MHPMCOUNTER29 = 12'hB1D,
CSR_MHPMCOUNTER30 = 12'hB1E,
CSR_MHPMCOUNTER31 = 12'hB1F,
CSR_MCYCLEH = 12'hB80,
CSR_MINSTRETH = 12'hB82,
CSR_MHPMCOUNTER3H = 12'hB83,
CSR_MHPMCOUNTER4H = 12'hB84,
CSR_MHPMCOUNTER5H = 12'hB85,
CSR_MHPMCOUNTER6H = 12'hB86,
CSR_MHPMCOUNTER7H = 12'hB87,
CSR_MHPMCOUNTER8H = 12'hB88,
CSR_MHPMCOUNTER9H = 12'hB89,
CSR_MHPMCOUNTER10H = 12'hB8A,
CSR_MHPMCOUNTER11H = 12'hB8B,
CSR_MHPMCOUNTER12H = 12'hB8C,
CSR_MHPMCOUNTER13H = 12'hB8D,
CSR_MHPMCOUNTER14H = 12'hB8E,
CSR_MHPMCOUNTER15H = 12'hB8F,
CSR_MHPMCOUNTER16H = 12'hB90,
CSR_MHPMCOUNTER17H = 12'hB91,
CSR_MHPMCOUNTER18H = 12'hB92,
CSR_MHPMCOUNTER19H = 12'hB93,
CSR_MHPMCOUNTER20H = 12'hB94,
CSR_MHPMCOUNTER21H = 12'hB95,
CSR_MHPMCOUNTER22H = 12'hB96,
CSR_MHPMCOUNTER23H = 12'hB97,
CSR_MHPMCOUNTER24H = 12'hB98,
CSR_MHPMCOUNTER25H = 12'hB99,
CSR_MHPMCOUNTER26H = 12'hB9A,
CSR_MHPMCOUNTER27H = 12'hB9B,
CSR_MHPMCOUNTER28H = 12'hB9C,
CSR_MHPMCOUNTER29H = 12'hB9D,
CSR_MHPMCOUNTER30H = 12'hB9E,
CSR_MHPMCOUNTER31H = 12'hB9F,
CSR_CPUCTRL = 12'h7C0,
CSR_SECURESEED = 12'h7C1
} csr_num_e;
// CSR pmp-related offsets
parameter logic [11:0] CSR_OFF_PMP_CFG = 12'h3A0; // pmp_cfg @ 12'h3a0 - 12'h3a3
parameter logic [11:0] CSR_OFF_PMP_ADDR = 12'h3B0; // pmp_addr @ 12'h3b0 - 12'h3bf
// CSR status bits
parameter int unsigned CSR_MSTATUS_MIE_BIT = 3;
parameter int unsigned CSR_MSTATUS_MPIE_BIT = 7;
parameter int unsigned CSR_MSTATUS_MPP_BIT_LOW = 11;
parameter int unsigned CSR_MSTATUS_MPP_BIT_HIGH = 12;
parameter int unsigned CSR_MSTATUS_MPRV_BIT = 17;
parameter int unsigned CSR_MSTATUS_TW_BIT = 21;
// CSR machine ISA
parameter logic [1:0] CSR_MISA_MXL = 2'd1; // M-XLEN: XLEN in M-Mode for RV32
// CSR interrupt pending/enable bits
parameter int unsigned CSR_MSIX_BIT = 3;
parameter int unsigned CSR_MTIX_BIT = 7;
parameter int unsigned CSR_MEIX_BIT = 11;
parameter int unsigned CSR_MFIX_BIT_LOW = 16;
parameter int unsigned CSR_MFIX_BIT_HIGH = 30;
// CSR Machine Security Configuration bits
parameter int unsigned CSR_MSECCFG_MML_BIT = 0;
parameter int unsigned CSR_MSECCFG_MMWP_BIT = 1;
parameter int unsigned CSR_MSECCFG_RLB_BIT = 2;
// These LFSR parameters have been generated with
// $ opentitan/util/design/gen-lfsr-seed.py --width 32 --seed 2480124384 --prefix ""
parameter int LfsrWidth = 32;
typedef logic [LfsrWidth-1:0] lfsr_seed_t;
typedef logic [LfsrWidth-1:0][$clog2(LfsrWidth)-1:0] lfsr_perm_t;
parameter lfsr_seed_t RndCnstLfsrSeedDefault = 32'hac533bf4;
parameter lfsr_perm_t RndCnstLfsrPermDefault = {
160'h1e35ecba467fd1b12e958152c04fa43878a8daed
};
endpackage
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
// Macros and helper code for using assertions.
// - Provides default clk and rst options to simplify code
// - Provides boiler plate template for common assertions
`ifndef PRIM_ASSERT_SV
`define PRIM_ASSERT_SV
///////////////////
// Helper macros //
///////////////////
// Default clk and reset signals used by assertion macros below.
`define ASSERT_DEFAULT_CLK clk_i
`define ASSERT_DEFAULT_RST !rst_ni
// Converts an arbitrary block of code into a Verilog string
`define PRIM_STRINGIFY(__x) `"__x`"
// ASSERT_ERROR logs an error message with either `uvm_error or with $error.
//
// This somewhat duplicates `DV_ERROR macro defined in hw/dv/sv/dv_utils/dv_macros.svh. The reason
// for redefining it here is to avoid creating a dependency.
`define ASSERT_ERROR(__name) \
`ifdef UVM \
uvm_pkg::uvm_report_error("ASSERT FAILED", `PRIM_STRINGIFY(__name), uvm_pkg::UVM_NONE, \
`__FILE__, `__LINE__, "", 1); \
`else \
$error("%0t: (%0s:%0d) [%m] [ASSERT FAILED] %0s", $time, `__FILE__, `__LINE__, \
`PRIM_STRINGIFY(__name)); \
`endif
// The basic helper macros are actually defined in "implementation headers". The macros should do
// the same thing in each case (except for the dummy flavour), but in a way that the respective
// tools support.
//
// If the tool supports assertions in some form, we also define INC_ASSERT (which can be used to
// hide signal definitions that are only used for assertions).
//
// The list of basic macros supported is:
//
// ASSERT_I: Immediate assertion. Note that immediate assertions are sensitive to simulation
// glitches.
//
// ASSERT_INIT: Assertion in initial block. Can be used for things like parameter checking.
//
// ASSERT_FINAL: Assertion in final block. Can be used for things like queues being empty at end of
// sim, all credits returned at end of sim, state machines in idle at end of sim.
//
// ASSERT: Assert a concurrent property directly. It can be called as a module (or
// interface) body item.
//
// Note: We use (__rst !== '0) in the disable iff statements instead of (__rst ==
// '1). This properly disables the assertion in cases when reset is X at the
// beginning of a simulation. For that case, (reset == '1) does not disable the
// assertion.
//
// ASSERT_NEVER: Assert a concurrent property NEVER happens
//
// ASSERT_KNOWN: Assert that signal has a known value (each bit is either '0' or '1') after reset.
// It can be called as a module (or interface) body item.
//
// COVER: Cover a concurrent property
//
// ASSUME: Assume a concurrent property
//
// ASSUME_I: Assume an immediate property
`ifdef VERILATOR
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
// Macro bodies included by prim_assert.sv for tools that don't support assertions. See
// prim_assert.sv for documentation for each of the macros.
`define ASSERT_I(__name, __prop)
`define ASSERT_INIT(__name, __prop)
`define ASSERT_FINAL(__name, __prop)
`define ASSERT(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST)
`define ASSERT_NEVER(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST)
`define ASSERT_KNOWN(__name, __sig, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST)
`define COVER(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST)
`define ASSUME(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST)
`define ASSUME_I(__name, __prop)
`elsif SYNTHESIS
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
// Macro bodies included by prim_assert.sv for tools that don't support assertions. See
// prim_assert.sv for documentation for each of the macros.
`define ASSERT_I(__name, __prop)
`define ASSERT_INIT(__name, __prop)
`define ASSERT_FINAL(__name, __prop)
`define ASSERT(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST)
`define ASSERT_NEVER(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST)
`define ASSERT_KNOWN(__name, __sig, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST)
`define COVER(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST)
`define ASSUME(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST)
`define ASSUME_I(__name, __prop)
`elsif YOSYS
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
// Macro bodies included by prim_assert.sv for formal verification with Yosys. See prim_assert.sv
// for documentation for each of the macros.
`define ASSERT_I(__name, __prop) \
always_comb begin : __name \
assert (__prop); \
end
`define ASSERT_INIT(__name, __prop) \
initial begin : __name \
assert (__prop); \
end
// This doesn't make much sense for a formal tool (we never get to the final block!)
`define ASSERT_FINAL(__name, __prop)
`define ASSERT(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
always_ff @(posedge __clk) begin \
if (! (__rst !== '0)) __name: assert (__prop); \
end
`define ASSERT_NEVER(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
always_ff @(posedge __clk) begin \
if (! (__rst !== '0)) __name: assert (! (__prop)); \
end
// Yosys uses 2-state logic, so this doesn't make sense here
`define ASSERT_KNOWN(__name, __sig, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST)
`define COVER(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
always_ff @(posedge __clk) begin : __name \
cover ((! (__rst !== '0)) && (__prop)); \
end
`define ASSUME(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
always_ff @(posedge __clk) begin \
if (! (__rst !== '0)) __name: assume (__prop); \
end
`define ASSUME_I(__name, __prop) \
always_comb begin : __name \
assume (__prop); \
end
`define INC_ASSERT
`else
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
// Macro bodies included by prim_assert.sv for tools that support full SystemVerilog and SVA syntax.
// See prim_assert.sv for documentation for each of the macros.
`define ASSERT_I(__name, __prop) \
__name: assert (__prop) \
else begin \
`ASSERT_ERROR(__name) \
end
// Formal tools will ignore the initial construct, so use static assertion as a workaround.
// This workaround terminates design elaboration if the __prop predict is false.
// It calls $fatal() with the first argument equal to 2, it outputs the statistics about the memory
// and CPU time.
`define ASSERT_INIT(__name, __prop) \
`ifdef FPV_ON \
if (!(__prop)) $fatal(2, "Fatal static assertion [%s]: (%s) is not true.", \
(__name), (__prop)); \
`else \
initial begin \
__name: assert (__prop) \
else begin \
`ASSERT_ERROR(__name) \
end \
end \
`endif
`define ASSERT_FINAL(__name, __prop) \
final begin \
__name: assert (__prop || $test$plusargs("disable_assert_final_checks")) \
else begin \
`ASSERT_ERROR(__name) \
end \
end
`define ASSERT(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
__name: assert property (@(posedge __clk) disable iff ((__rst) !== '0) (__prop)) \
else begin \
`ASSERT_ERROR(__name) \
end
`define ASSERT_NEVER(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
__name: assert property (@(posedge __clk) disable iff ((__rst) !== '0) not (__prop)) \
else begin \
`ASSERT_ERROR(__name) \
end
`define ASSERT_KNOWN(__name, __sig, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
`ASSERT(__name, !$isunknown(__sig), __clk, __rst)
`define COVER(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
__name: cover property (@(posedge __clk) disable iff ((__rst) !== '0) (__prop));
`define ASSUME(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
__name: assume property (@(posedge __clk) disable iff ((__rst) !== '0) (__prop)) \
else begin \
`ASSERT_ERROR(__name) \
end
`define ASSUME_I(__name, __prop) \
__name: assume (__prop) \
else begin \
`ASSERT_ERROR(__name) \
end
`define INC_ASSERT
`endif
//////////////////////////////
// Complex assertion macros //
//////////////////////////////
// Assert that signal is an active-high pulse with pulse length of 1 clock cycle
`define ASSERT_PULSE(__name, __sig, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
`ASSERT(__name, $rose(__sig) |=> !(__sig), __clk, __rst)
// Assert that a property is true only when an enable signal is set. It can be called as a module
// (or interface) body item.
`define ASSERT_IF(__name, __prop, __enable, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
`ASSERT(__name, (__enable) |-> (__prop), __clk, __rst)
// Assert that signal has a known value (each bit is either '0' or '1') after reset if enable is
// set. It can be called as a module (or interface) body item.
`define ASSERT_KNOWN_IF(__name, __sig, __enable, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
`ASSERT_KNOWN(__name``KnownEnable, __enable, __clk, __rst) \
`ASSERT_IF(__name, !$isunknown(__sig), __enable, __clk, __rst)
//////////////////////////////////
// For formal verification only //
//////////////////////////////////
// Note that the existing set of ASSERT macros specified above shall be used for FPV,
// thereby ensuring that the assertions are evaluated during DV simulations as well.
// ASSUME_FPV
// Assume a concurrent property during formal verification only.
`define ASSUME_FPV(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
`ifdef FPV_ON \
`ASSUME(__name, __prop, __clk, __rst) \
`endif
// ASSUME_I_FPV
// Assume a concurrent property during formal verification only.
`define ASSUME_I_FPV(__name, __prop) \
`ifdef FPV_ON \
`ASSUME_I(__name, __prop) \
`endif
// COVER_FPV
// Cover a concurrent property during formal verification
`define COVER_FPV(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
`ifdef FPV_ON \
`COVER(__name, __prop, __clk, __rst) \
`endif
`endif // PRIM_ASSERT_SV
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
package prim_ram_1p_pkg;
typedef struct packed {
logic cfg_en;
logic [3:0] cfg;
} cfg_t;
typedef struct packed {
cfg_t ram_cfg; // configuration for ram
cfg_t rf_cfg; // configuration for regfile
} ram_1p_cfg_t;
parameter ram_1p_cfg_t RAM_1P_CFG_DEFAULT = '0;
endpackage // prim_ram_1p_pkg
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Constants for use in primitives
//
// This file is a stop-gap until the DV file list is generated by FuseSoC.
// Its contents are taken from the file which would be generated by FuseSoC.
// https://github.com/lowRISC/ibex/issues/893
package prim_pkg;
// Implementation target specialization
typedef enum integer {
ImplGeneric,
ImplXilinx
} impl_e;
endpackage : prim_pkg
// Copyright lowRISC contributors.
// Copyright 2018 ETH Zurich and University of Bologna, see also CREDITS.md.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
/**
* Arithmetic logic unit
*/
module ibex_alu #(
parameter ibex_pkg::rv32b_e RV32B = ibex_pkg::RV32BNone
) (
input ibex_pkg::alu_op_e operator_i,
input logic [31:0] operand_a_i,
input logic [31:0] operand_b_i,
input logic instr_first_cycle_i,
input logic [32:0] multdiv_operand_a_i,
input logic [32:0] multdiv_operand_b_i,
input logic multdiv_sel_i,
input logic [31:0] imd_val_q_i[2],
output logic [31:0] imd_val_d_o[2],
output logic [1:0] imd_val_we_o,
output logic [31:0] adder_result_o,
output logic [33:0] adder_result_ext_o,
output logic [31:0] result_o,
output logic comparison_result_o,
output logic is_equal_result_o
);
import ibex_pkg::*;
logic [31:0] operand_a_rev;
logic [32:0] operand_b_neg;
// bit reverse operand_a for left shifts and bit counting
for (genvar k = 0; k < 32; k++) begin : gen_rev_operand_a
assign operand_a_rev[k] = operand_a_i[31-k];
end
///////////
// Adder //
///////////
logic adder_op_b_negate;
logic [32:0] adder_in_a, adder_in_b;
logic [31:0] adder_result;
always_comb begin
adder_op_b_negate = 1'b0;
unique case (operator_i)
// Adder OPs
ALU_SUB,
// Comparator OPs
ALU_EQ, ALU_NE,
ALU_GE, ALU_GEU,
ALU_LT, ALU_LTU,
ALU_SLT, ALU_SLTU,
// MinMax OPs (RV32B Ops)
ALU_MIN, ALU_MINU,
ALU_MAX, ALU_MAXU: adder_op_b_negate = 1'b1;
default:;
endcase
end
// prepare operand a
assign adder_in_a = multdiv_sel_i ? multdiv_operand_a_i : {operand_a_i,1'b1};
// prepare operand b
assign operand_b_neg = {operand_b_i,1'b0} ^ {33{1'b1}};
always_comb begin
unique case(1'b1)
multdiv_sel_i: adder_in_b = multdiv_operand_b_i;
adder_op_b_negate: adder_in_b = operand_b_neg;
default : adder_in_b = {operand_b_i, 1'b0};
endcase
end
// actual adder
assign adder_result_ext_o = $unsigned(adder_in_a) + $unsigned(adder_in_b);
assign adder_result = adder_result_ext_o[32:1];
assign adder_result_o = adder_result;
////////////////
// Comparison //
////////////////
logic is_equal;
logic is_greater_equal; // handles both signed and unsigned forms
logic cmp_signed;
always_comb begin
unique case (operator_i)
ALU_GE,
ALU_LT,
ALU_SLT,
// RV32B only
ALU_MIN,
ALU_MAX: cmp_signed = 1'b1;
default: cmp_signed = 1'b0;
endcase
end
assign is_equal = (adder_result == 32'b0);
assign is_equal_result_o = is_equal;