1+ import 'dart:math' show max;
2+
13import 'package:rohd/rohd.dart' ;
24import 'package:rohd_hcl/rohd_hcl.dart' ;
35import 'package:riscv/riscv.dart' ;
46import 'package:river/river.dart' ;
57
68import 'core/csr.dart' ;
79import 'core/pipeline.dart' ;
10+ import 'core/int.dart' ;
811
912class RiverCoreHDL extends Module {
1013 final RiverCore config;
@@ -20,6 +23,7 @@ class RiverCoreHDL extends Module {
2023 DataPortInterface memFetchRead,
2124 DataPortInterface memExecRead,
2225 DataPortInterface memWrite, {
26+ Map <String , Logic > srcIrqs = const {},
2327 super .name = 'river_core' ,
2428 }) {
2529 clk = addInput ('clk' , clk);
@@ -34,6 +38,7 @@ class RiverCoreHDL extends Module {
3438 inputTags: {DataPortGroup .data, DataPortGroup .integrity},
3539 uniquify: (og) => 'memFetchRead_$og ' ,
3640 );
41+
3742 memExecRead = memExecRead.clone ()
3843 ..connectIO (
3944 this ,
@@ -42,6 +47,7 @@ class RiverCoreHDL extends Module {
4247 inputTags: {DataPortGroup .data, DataPortGroup .integrity},
4348 uniquify: (og) => 'memExecRead_$og ' ,
4449 );
50+
4551 memWrite = memWrite.clone ()
4652 ..connectIO (
4753 this ,
@@ -61,6 +67,70 @@ class RiverCoreHDL extends Module {
6167 final rs2Read = DataPortInterface (config.mxlen.size, 5 );
6268 final rdWrite = DataPortInterface (config.mxlen.size, 5 );
6369
70+ regs = RegisterFile (
71+ clk,
72+ reset,
73+ [rdWrite],
74+ [rs1Read, rs2Read],
75+ numEntries: 32 ,
76+ name: 'riscv_regfile' ,
77+ );
78+
79+ int computeNumIrqs (InterruptController ic) {
80+ final irqs = ic.lines.map ((l) => l.irq).toList ();
81+ if (irqs.isEmpty) return 1 ;
82+ final maxIrq = irqs.reduce ((a, b) => a > b ? a : b);
83+ return max (1 , maxIrq + 1 );
84+ }
85+
86+ final interruptBundles =
87+ <
88+ ({
89+ InterruptController cfg,
90+ Logic srcIrq,
91+ InterruptPortInterface ipi,
92+ RiscVInterruptController ctrl,
93+ })
94+ > [];
95+
96+ for (final ic in config.interrupts) {
97+ final numIrqs = computeNumIrqs (ic);
98+
99+ final isExternal = srcIrqs.containsKey (ic.name);
100+ final srcIrq = isExternal
101+ ? addInput (
102+ 'srcIrqLevel_${interruptBundles .length }' ,
103+ srcIrqs[ic.name]! ,
104+ width: numIrqs,
105+ )
106+ : Logic (
107+ name: 'srcIrqLevel_${interruptBundles .length }' ,
108+ width: numIrqs,
109+ );
110+
111+ final ipi = InterruptPortInterface (config.mxlen.size, config.mxlen.size);
112+
113+ final ctrl = RiscVInterruptController (ic, clk, reset, srcIrq, ipi);
114+
115+ ipi.en <= Const (0 );
116+ ipi.write <= Const (0 );
117+ ipi.addr <= Const (0 , width: ipi.addr.width);
118+ ipi.wdata <= Const (0 , width: ipi.wdata.width);
119+ ipi.wstrb <= Const (0 , width: ipi.wstrb.width);
120+
121+ interruptBundles.add ((cfg: ic, srcIrq: srcIrq, ipi: ipi, ctrl: ctrl));
122+ }
123+
124+ Logic externalPending = Const (0 );
125+ for (final b in interruptBundles) {
126+ final v = b.ctrl.irqToTargets;
127+ Logic anyFromThis = Const (0 );
128+ for (var i = 0 ; i < v.width; i++ ) {
129+ anyFromThis = anyFromThis | v[i];
130+ }
131+ externalPending = externalPending | anyFromThis;
132+ }
133+
64134 final csrRead = DataPortInterface (config.mxlen.size, 12 );
65135 final csrWrite = DataPortInterface (config.mxlen.size, 12 );
66136
@@ -81,22 +151,14 @@ class RiverCoreHDL extends Module {
81151 marchid: config.archId,
82152 mimpid: config.impId,
83153 mhartid: config.hartId,
154+ externalPending: externalPending,
84155 hasSupervisor: config.hasSupervisor,
85156 hasUser: config.hasUser,
86157 csrRead: csrRead,
87158 csrWrite: csrWrite,
88159 )
89160 : null ;
90161
91- regs = RegisterFile (
92- clk,
93- reset,
94- [rdWrite],
95- [rs1Read, rs2Read],
96- numEntries: 32 ,
97- name: 'riscv_regfile' ,
98- );
99-
100162 pipeline = RiverPipeline (
101163 clk,
102164 reset,
@@ -135,6 +197,11 @@ class RiverCoreHDL extends Module {
135197 interruptHold < 0 ,
136198 ],
137199 orElse: [
200+ If (
201+ interruptHold & externalPending,
202+ then: [interruptHold < 0 , pipelineEnable < 1 ],
203+ ),
204+
138205 If (
139206 enable & ~ interruptHold,
140207 then: [
@@ -150,12 +217,8 @@ class RiverCoreHDL extends Module {
150217 orElse: [pipelineEnable < 1 ],
151218 ),
152219 ],
153- orElse: [
154- pipelineEnable < 0 ,
155- // TODO: if interrupt hold & interrupt is fired, re-enable pipeline.
156- ],
220+ orElse: [pipelineEnable < 0 ],
157221 ),
158- // TODO: trap handling circuitry
159222 ],
160223 ),
161224 ]);
0 commit comments