@@ -6,8 +6,11 @@ import 'package:riscv/riscv.dart';
66import 'package:river/river.dart' ;
77
88import 'core/csr.dart' ;
9- import 'core/pipeline.dart' ;
109import 'core/int.dart' ;
10+ import 'core/mmu.dart' ;
11+ import 'core/pipeline.dart' ;
12+
13+ import 'memory/port.dart' ;
1114
1215class RiverCoreHDL extends Module {
1316 final RiverCore config;
@@ -19,49 +22,106 @@ class RiverCoreHDL extends Module {
1922 this .config,
2023 Logic clk,
2124 Logic reset,
22- Logic enable,
23- DataPortInterface memFetchRead,
24- DataPortInterface memExecRead,
25- DataPortInterface memWrite, {
25+ Logic enable, {
26+ Map <MemoryBlock , (DataPortInterface , DataPortInterface )> devices = const {},
2627 Map <String , Logic > srcIrqs = const {},
2728 super .name = 'river_core' ,
2829 }) {
2930 clk = addInput ('clk' , clk);
3031 reset = addInput ('reset' , reset);
3132 enable = addInput ('enable' , enable);
3233
33- memFetchRead = memFetchRead.clone ()
34- ..connectIO (
35- this ,
36- memFetchRead,
37- outputTags: {DataPortGroup .control},
38- inputTags: {DataPortGroup .data, DataPortGroup .integrity},
39- uniquify: (og) => 'memFetchRead_$og ' ,
40- );
41-
42- memExecRead = memExecRead.clone ()
43- ..connectIO (
44- this ,
45- memExecRead,
46- outputTags: {DataPortGroup .control},
47- inputTags: {DataPortGroup .data, DataPortGroup .integrity},
48- uniquify: (og) => 'memExecRead_$og ' ,
49- );
50-
51- memWrite = memWrite.clone ()
52- ..connectIO (
53- this ,
54- memWrite,
55- outputTags: {DataPortGroup .control, DataPortGroup .data},
56- inputTags: {DataPortGroup .integrity},
57- uniquify: (og) => 'memWrite_$og ' ,
58- );
34+ devices = Map .fromEntries (
35+ devices.entries.indexed.map ((e) {
36+ final index = e.$1;
37+ final mmap = e.$2.key;
38+ final devReadPort = e.$2.value.$1;
39+ final devWritePort = e.$2.value.$2;
40+ return MapEntry (mmap, (
41+ devReadPort.clone ()..connectIO (
42+ this ,
43+ devReadPort,
44+ outputTags: {DataPortGroup .control},
45+ inputTags: {DataPortGroup .data, DataPortGroup .integrity},
46+ uniquify: (og) => 'devRead${index }_$og ' ,
47+ ),
48+ devWritePort.clone ()..connectIO (
49+ this ,
50+ devWritePort,
51+ outputTags: {DataPortGroup .control, DataPortGroup .data},
52+ inputTags: {DataPortGroup .integrity},
53+ uniquify: (og) => 'devWrite${index }_$og ' ,
54+ ),
55+ ));
56+ }),
57+ );
5958
6059 final pipelineEnable = Logic (name: 'pipelineEnable' );
6160 final pc = Logic (name: 'pc' , width: config.mxlen.size);
6261 final sp = Logic (name: 'sp' , width: config.mxlen.size);
6362 final mode = Logic (name: 'mode' , width: 3 );
6463 final interruptHold = Logic (name: 'interruptHold' );
64+ final fence = Logic (name: 'fence' );
65+
66+ final pagingMode = Logic (
67+ name: 'pagingMode' ,
68+ width: PagingMode .values
69+ .where ((m) => m.isSupported (config.mxlen))
70+ .map ((m) => m.id)
71+ .fold ((0 ), (a, b) => a > b ? a : b)
72+ .bitLength,
73+ );
74+
75+ final pageTableAddress = Logic (
76+ name: 'pageTableAddress' ,
77+ width: config.mxlen.size,
78+ );
79+
80+ final enableMxr = Logic (name: 'enableMxr' );
81+ final enableSum = Logic (name: 'enableSum' );
82+
83+ final mmuFetchRead = DataPortInterface (
84+ config.mxlen.size,
85+ config.mxlen.size,
86+ );
87+ final mmuExecRead = DataPortInterface (config.mxlen.size, config.mxlen.size);
88+ final mmuWritebackRead = DataPortInterface (
89+ config.mxlen.size,
90+ config.mxlen.size,
91+ );
92+
93+ final mmuWrite = DataPortInterface (config.mxlen.size, config.mxlen.size);
94+ final sizedMmuWrite = DataPortInterface (
95+ config.mxlen.size + 7 ,
96+ config.mxlen.size,
97+ );
98+
99+ SizedWriteSingleDataPort (
100+ clk,
101+ reset,
102+ backingRead: mmuWritebackRead,
103+ backingWrite: mmuWrite,
104+ source: sizedMmuWrite,
105+ );
106+
107+ MmuHDL (
108+ clk,
109+ reset,
110+ [(MemoryAccess .write, mmuWrite)],
111+ [
112+ (MemoryAccess .instr, mmuFetchRead),
113+ (MemoryAccess .read, mmuExecRead),
114+ (MemoryAccess .read, mmuWritebackRead),
115+ ],
116+ config: config.mmu,
117+ privilegeMode: mode,
118+ pagingMode: config.mmu.hasPaging ? pagingMode : null ,
119+ pageTableAddress: config.mmu.hasPaging ? pageTableAddress : null ,
120+ devices: devices,
121+ enableSum: config.mmu.hasSum ? enableSum : null ,
122+ enableMxr: config.mmu.hasMxr ? enableMxr : null ,
123+ fence: fence,
124+ );
65125
66126 final rs1Read = DataPortInterface (config.mxlen.size, 5 );
67127 final rs2Read = DataPortInterface (config.mxlen.size, 5 );
@@ -154,11 +214,20 @@ class RiverCoreHDL extends Module {
154214 externalPending: externalPending,
155215 hasSupervisor: config.hasSupervisor,
156216 hasUser: config.hasUser,
217+ hasPaging: config.mmu.hasPaging,
218+ hasMxr: config.mmu.hasMxr,
219+ hasSum: config.mmu.hasSum,
157220 csrRead: csrRead,
158221 csrWrite: csrWrite,
159222 )
160223 : null ;
161224
225+ if (csrs != null ) {
226+ pagingMode <= Const (0 , width: pagingMode.width);
227+ pageTableAddress <= Const (0 , width: config.mxlen.size);
228+ // TODO: drive pagingMode, pageTableAddress, mxr, and sum from CSRs
229+ }
230+
162231 pipeline = RiverPipeline (
163232 clk,
164233 reset,
@@ -169,9 +238,9 @@ class RiverCoreHDL extends Module {
169238 config.type.hasCsrs ? csrRead : null ,
170239 config.type.hasCsrs ? csrWrite : null ,
171240 // TODO: have a cache backed memory interface
172- memFetchRead ,
173- memExecRead ,
174- memWrite ,
241+ mmuFetchRead ,
242+ mmuExecRead ,
243+ sizedMmuWrite ,
175244 rs1Read,
176245 rs2Read,
177246 rdWrite,
@@ -194,12 +263,13 @@ class RiverCoreHDL extends Module {
194263 pc < config.resetVector,
195264 sp < 0 ,
196265 mode < 0 ,
266+ fence < 0 ,
197267 interruptHold < 0 ,
198268 ],
199269 orElse: [
200270 If (
201271 interruptHold & externalPending,
202- then: [interruptHold < 0 , pipelineEnable < 1 ],
272+ then: [interruptHold < 0 , pipelineEnable < 1 , fence < 0 ],
203273 ),
204274
205275 If (
@@ -212,12 +282,13 @@ class RiverCoreHDL extends Module {
212282 sp < pipeline.nextSp,
213283 mode < pipeline.nextMode,
214284 interruptHold < pipeline.interruptHold,
285+ fence < pipeline.fence,
215286 pipelineEnable < 0 ,
216287 ],
217- orElse: [pipelineEnable < 1 ],
288+ orElse: [pipelineEnable < 1 , fence < 0 ],
218289 ),
219290 ],
220- orElse: [pipelineEnable < 0 ],
291+ orElse: [pipelineEnable < 0 , fence < 0 ],
221292 ),
222293 ],
223294 ),
0 commit comments