2 Copyright (c) 2013, IIT Madras
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9 * Neither the name of IIT Madras nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
16 /* ############################ changes from 1.9.1 ############################
17 1. base field in misa is changed to readOnlyfield of mxl as per the encoding
18 and the same is reflected in sxl and uxl fields of mstatus
19 2. change of fields in mstatus.
22 import defined_types::*;
23 `include "defined_parameters.bsv"
30 method Bit#(3) roundingmode;
31 method Action set_external_interrupt(Tuple2#(Bool,Bool) i);
33 (*always_ready,always_enabled*)
34 method Action boot_sequence(Bit#(1) bootseq);
35 /*======= MMU related interfaces ===== */
37 method Bit#(`Reg_width) send_satp;
38 method Chmod perm_to_TLB;
40 method Bit#(`Reg_width) mmu_cache_disable;
41 /*=========================================== */
42 /*=========== Debug related interfaces ====== */
45 method ActionValue#(Bit#(`Reg_width)) rw_debug_csr(Bit#(12) r, Bool write, Bit#(`Reg_width) data);
46 method TriggerData load_triggerdata;
47 method TriggerData store_triggerdata;
49 method Bool reset_mode;
51 /*=========================================== */
52 method ActionValue#(Tuple2#(Bit#(3),Trap_type)) check_for_trap(`ifdef Debug Bool haltreq, Bool resumereq, Bool resetreq, `endif Bit#(`VADDR) pc, Bit#(32) instruction);
53 method ActionValue#(Tuple4#(Bool,Bit#(`VADDR),Bit#(`Reg_width),Bool)) system_instruction(WriteBackType wbdata ,Bit#(`VADDR) pc, Bit#(`PERFMONITORS) perfmonitor_incr `ifdef simulate , Bit#(32) instruction, Operand_type rd_type, Bit#(5) destination `endif );
54 method ActionValue#(Tuple2#(Bit#(`VADDR), Bool)) take_trap(Trap_type exception, Bit#(3) lv_debugcause, Bit#(`VADDR) pc, Bit#(`VADDR) badaddr);
55 method Bit#(`Reg_width) misa;
56 method Bit#(2) powercontrol;
57 method Action poweracknowledge(Bit#(2) pa);
59 method Action clint_msip(Bit#(1) intrpt);
60 method Action clint_mtip(Bit#(1) intrpt);
61 method Action clint_mtime(Bit#(`Reg_width) c_mtime);
63 method Bit#(2) inferred_xlen;
66 function String csr_funct(Bit#(3) funct3);
74 default: return "NOIDEA";
78 function Reg#(t) readOnlyReg(t r);
79 return (interface Reg;
81 method Action _write(t x) = noAction;
85 function Reg#(Bit#(a)) extInterruptReg(Reg#(Bit#(a)) r1, Reg#(Bit#(a)) r2);
86 return (interface Reg;
87 method Bit#(a) _read = r1 | r2;
88 method Action _write(Bit#(a) x);
94 function Reg#(t) writeSideEffect(Reg#(t) r, Action a);
95 return (interface Reg;
96 method t _read = r._read;
97 method Action _write(t x);
105 (*conflict_free="take_trap, set_external_interrupt"*)
106 (*conflict_free="check_for_trap,system_instruction"*)
107 module mkcsr(Ifc_csr);
109 Reg#(Bool) rg_initialize[2]<-mkCReg(2,False);
110 Reg#(Bit#(12)) rg_index<-mkReg(0);
112 Reg#(Bool) wr_endsimulation <-mkReg(False);
113 Reg#(Bit#(1)) rg_cnt <-mkReg(0);
114 let dump <- mkReg(InvalidFile) ;
115 rule open_file(rg_cnt==0);
116 String dumpFile = "rtl.dump" ;
117 File lfh <- $fopen( dumpFile, "w" ) ;
118 if ( lfh == InvalidFile )begin
119 `ifdef verbose $display("cannot open %s", dumpFile); `endif
126 /////////////////////////////// Machine level register /////////////////////////
127 // Current Privilege Level
128 Reg#(Privilege_mode) rg_prv <- mkConfigReg(Machine); // resets to machine mode
131 Reg#(Bit#(`Reg_width)) csr_mvendorid = readOnlyReg(0);
132 Reg#(Bit#(`Reg_width)) csr_marchid = readOnlyReg(0);
133 Reg#(Bit#(`Reg_width)) csr_mimpid = readOnlyReg(0);
134 Reg#(Bit#(`Reg_width)) csr_mhartid = readOnlyReg(0);
136 Reg#(Bit#(2)) rg_mxl <- mkReg(2);
137 Bit#(26) temp_misa='d0;
140 `ifdef atomic temp_misa[0]=1; `endif
141 `ifdef dpfpu temp_misa[3]=1; `endif
142 `ifdef spfpu temp_misa[5]=1; `endif
143 `ifdef muldiv temp_misa[12]=1; `endif
144 `ifdef MMU temp_misa[18]=1; `endif
146 Reg#(Bit#(26)) rg_misa <- mkReg(temp_misa);
148 Reg#(Bit#(26)) rg_misa <- mkReg(`MISA_BITS);
150 Reg#(Bit#(`Reg_width)) csr_misa = concatReg3(rg_mxl,readOnlyReg(0),rg_misa);
152 // trap vector fields (same as CSR without bottom 2 bits)
153 Reg#(Bit#(2)) rg_mode_m <- mkReg(0); //default value 0 if pc to base or 1 if pc to base + 4xcause
154 Reg#(Bit#(TSub#(`PADDR,2))) rg_mtvec <- mkReg(`MTVEC_DEFAULT);
155 Reg#(Bit#(`Reg_width)) csr_mtvec=concatReg3(readOnlyReg(0),rg_mtvec, rg_mode_m);
158 Reg#(Bit#(1)) rg_tsr <- mkReg(0); // WARL
159 Reg#(Bit#(1)) rg_tw <- mkReg(0); // WARL
160 Reg#(Bit#(1)) rg_tvm <- mkReg(0); // WARL
161 Reg#(Bit#(1)) rg_mxr <- mkReg(0); // Not required
162 Reg#(Bit#(1)) rg_sum <- mkReg(0); // Not required
163 Reg#(Bit#(1)) rg_mprv <- mkReg(0);
164 Reg#(Bit#(2)) rg_xs = readOnlyReg(0);
165 Reg#(Bit#(2)) rg_fs <- mkReg(2'b00);
166 Reg#(Bit#(2)) rg_mpp <- mkReg(2'b0);
167 Reg#(Bit#(2)) rg_hpp = readOnlyReg(0);
168 Reg#(Bit#(1)) rg_spp <- mkReg(0);
169 Reg#(Bit#(1)) rg_mpie <- mkReg(0);
170 Reg#(Bit#(1)) rg_hpie = readOnlyReg(0);
171 Reg#(Bit#(1)) rg_spie <- mkReg(0);
172 Reg#(Bit#(1)) rg_upie <- mkReg(0);
174 Reg#(Bit#(1)) rg_mie <- mkReg(1);
176 Reg#(Bit#(1)) rg_mie <- mkReg(0);
178 Reg#(Bit#(1)) rg_hie = readOnlyReg(0);
179 Reg#(Bit#(1)) rg_sie <- mkReg(0);
180 Reg#(Bit#(1)) rg_uie <- mkReg(0);
181 Reg#(Bit#(1)) rg_sd = readOnlyReg(pack((rg_xs == 2'b11) || (rg_fs == 2'b11)));
182 Reg#(Bit#(`Reg_width)) csr_mstatus = concatReg24(
185 readOnlyReg(rg_mxl), readOnlyReg(rg_mxl), //sxl and uxl fields are hardwired to mxl in misa
187 rg_tsr, rg_tw, rg_tvm,
188 rg_mxr, rg_sum, rg_mprv, // memory privilege
189 rg_xs, rg_fs, // coprocessor states
190 rg_mpp, rg_hpp, rg_spp, // previous privileges
191 rg_mpie, rg_hpie, rg_spie, rg_upie, // previous interrupt enables
192 rg_mie, rg_hie, rg_sie, rg_uie); // interrupt enables
194 // trap delegation fields
195 Reg#(Bit#(16)) rg_medeleg<-mkReg(0);
196 Reg#(Bit#(15)) rg_mideleg<-mkReg(0);
197 Reg#(Bit#(`Reg_width)) csr_medeleg = concatReg2(readOnlyReg(0),rg_medeleg);
198 Reg#(Bit#(`Reg_width)) csr_mideleg = concatReg2(readOnlyReg(0),rg_mideleg);
201 Reg#(Bit#(1)) rg_meie <- mkReg(0);
202 Reg#(Bit#(1)) rg_heie = readOnlyReg(0);
203 Reg#(Bit#(1)) rg_seie <- mkReg(0);
204 Reg#(Bit#(1)) rg_ueie <- mkReg(0);
205 Reg#(Bit#(1)) rg_mtie <- mkReg(0);
206 Reg#(Bit#(1)) rg_htie = readOnlyReg(0);
207 Reg#(Bit#(1)) rg_stie <- mkReg(0);
208 Reg#(Bit#(1)) rg_utie <- mkReg(0);
209 Reg#(Bit#(1)) rg_msie <- mkReg(0);
210 Reg#(Bit#(1)) rg_hsie = readOnlyReg(0);
211 Reg#(Bit#(1)) rg_ssie <- mkReg(0);
212 Reg#(Bit#(1)) rg_usie <- mkReg(0);
214 Reg#(Bit#(1)) rg_dhalt<-mkReg(1);
215 Reg#(Bit#(1)) rg_dresume<-mkReg(1);
217 Reg#(Bit#(1)) rg_dhalt<-mkReg(0);
218 Reg#(Bit#(1)) rg_dresume<-mkReg(0);
220 Reg#(Bit#(1)) rg_dreset<-mkReg(0);
221 Reg#(Bit#(`Reg_width)) csr_mie = concatReg16(
223 rg_dreset,rg_dresume,rg_dhalt,
224 rg_meie, rg_heie, rg_seie, readOnlyReg(rg_ueie),
225 rg_mtie, rg_htie, rg_stie, readOnlyReg(rg_utie),
226 rg_msie, rg_hsie, rg_ssie, readOnlyReg(rg_usie));
227 Reg#(Bool) rg_nmi <- mkReg(True);
230 Reg#(Bit#(1)) rg_meip <- mkConfigReg(0);
231 Reg#(Bit#(1)) rg_heip = readOnlyReg(0);
232 Reg#(Bit#(1)) rg_seips <- mkReg(0);
233 Reg#(Bit#(1)) rg_seipe <- mkReg(0);
234 Reg#(Bit#(1)) rg_ueips <- mkReg(0);
235 Reg#(Bit#(1)) rg_ueipe <- mkReg(0);
236 Reg#(Bit#(1)) rg_seip = extInterruptReg(rg_seips,rg_seipe);
237 Reg#(Bit#(1)) rg_ueip = extInterruptReg(rg_ueips,rg_ueipe);
238 Reg#(Bit#(1)) rg_mtip <-mkReg(0);
239 Reg#(Bit#(1)) rg_htip = readOnlyReg(0);
240 Reg#(Bit#(1)) rg_stip <- mkReg(0);
241 Reg#(Bit#(1)) rg_utip <- mkReg(0);
242 Reg#(Bit#(1)) rg_msip <- mkReg(0);
243 Reg#(Bit#(1)) rg_hsip = readOnlyReg(0);
244 Reg#(Bit#(1)) rg_ssip <- mkReg(0);
245 Reg#(Bit#(1)) rg_usip <- mkReg(0);
248 Reg#(Bit#(`Reg_width)) csr_mcycle[2]<-mkCReg(2,0);
249 Reg#(Bit#(`Reg_width)) csr_minstret[2]<-mkCReg(2,0);
251 Reg#(Bit#(`Reg_width)) csr_mcycle[2]<-mkCReg(2,0);
252 Reg#(Bit#(`Reg_width)) csr_minstret[2]<-mkCReg(2,0);
253 Reg#(Bit#(`Reg_width)) csr_mcycleh[2]<-mkCReg(2,0);
254 Reg#(Bit#(`Reg_width)) csr_minstreth[2]<-mkCReg(2,0);
257 // Machine Trap Handling
258 Reg#(Bit#(`Reg_width)) rg_mepc <- mkReg(0);
259 Reg#(Bit#(`VADDR)) rg_mtval <- mkReg(0);
260 Reg#(Bit#(`Reg_width)) csr_mscratch <- mkReg(0);
261 Reg#(Bit#(`Reg_width)) csr_mepc = rg_mepc;
262 Reg#(Bit#(1)) rg_interrupt <- mkReg(0);
263 Reg#(Bit#(31)) rg_lower_cause <- mkReg(0);
264 Reg#(Bit#(32)) rg_upper_cause <- mkReg(0);
265 Reg#(Bit#(`Reg_width)) csr_mcause= concatReg3(rg_interrupt, rg_upper_cause, rg_lower_cause);
266 Reg#(Bit#(`Reg_width)) csr_mtval = concatReg2(readOnlyReg(0), rg_mtval);
267 Reg#(Bit#(`Reg_width)) csr_mip = concatReg13(
269 readOnlyReg(rg_meip), readOnlyReg(rg_heip), rg_seip, rg_ueip,
270 readOnlyReg(rg_mtip), readOnlyReg(rg_htip), rg_stip, rg_utip,
271 readOnlyReg(rg_msip), readOnlyReg(rg_hsip), rg_ssip, rg_usip);
273 Reg#(Bit#(`Reg_width)) mip = concatReg13(
275 rg_meip, rg_heip, rg_seip, rg_ueip,
276 rg_mtip, rg_htip, rg_stip, rg_utip,
277 rg_msip, rg_hsip, rg_ssip, rg_usip);
278 //////////////////////////////////////////////////////////////////////////////////////////
279 ///////////////////////////////////Physical Memory Protection////////////////////////////
280 Reg#(Bit#(`Reg_width)) csr_pmpcfg0 <- mkReg(0);
282 Reg#(Bit#(`Reg_width)) csr_pmpcfg1 <- mkReg(0);
284 Reg#(Bit#(`Reg_width)) csr_pmpcfg2 <- mkReg(0);
286 Reg#(Bit#(`Reg_width)) csr_pmpcfg3 <- mkReg(0);
289 Reg#(Bit#(TSub#(`PADDR,2))) rg_pmpaddr[`PMPADDREND - `PMPADDRSTART +1];
290 Reg#(Bit#(`Reg_width)) csr_pmpaddr[`PMPADDREND - `PMPADDRSTART +1];
291 for(Integer i=0; i<(`PMPADDREND - `PMPADDRSTART +1); i =i+1) begin
292 rg_pmpaddr[i] <- mkReg(0);
293 csr_pmpaddr[i] = concatReg2(readOnlyReg(0), rg_pmpaddr[i]);
295 //////////////////////////////////////////////////////////////////////////////////////////
297 Reg#(Bit#(1)) rg_u_ir <- mkReg(0);
298 Reg#(Bit#(1)) rg_u_tm <- mkReg(0);
299 Reg#(Bit#(1)) rg_u_cy <- mkReg(0);
300 // Machine Counter Setup
301 Reg#(Bit#(32)) reg_mcounteren<-mkReg(0);
302 Reg#(Bit#(`Reg_width)) csr_mcounteren=concatReg2(readOnlyReg(32'd0),reg_mcounteren);
303 Reg#(Bit#(1)) rg_boot_seq<-mkReg(0);
304 Reg#(Bit#(`Reg_width)) csr_boot_seq =concatReg2(readOnlyReg(0),readOnlyReg(rg_boot_seq));
305 Reg#(Bit#(2)) power_control_out <-mkReg(0);
306 Reg#(Bit#(2)) power_control_in <-mkReg(0);
307 Reg#(Bit#(`Reg_width)) csr_power_control = concatReg3(readOnlyReg(0),readOnlyReg(power_control_in),power_control_out);
309 //////////////////////////////////////////////////////////////////////////////////////////
310 //////////////////////////////SUPERVISOR LEVEL REGISTERS//////////////////////////////////
312 Reg#(Bit#(`Reg_width)) csr_sstatus = concatReg20(
314 readOnlyReg(0), readOnlyReg(rg_mxl), readOnlyReg(12'b0), //uxl field
315 rg_mxr, rg_sum, readOnlyReg(1'b0), // memory privilege //
316 rg_xs, rg_fs, // coprocessor states
317 readOnlyReg(2'b0), readOnlyReg(2'b0), rg_spp, // previous privileges
318 readOnlyReg(1'b0), readOnlyReg(1'b0), rg_spie, rg_upie, // previous interrupt enables
319 readOnlyReg(1'b0), readOnlyReg(1'b0), rg_sie, rg_uie); // interrupt enables
321 Reg#(Bit#(12)) rg_sedeleg<-mkReg(0);
322 Reg#(Bit#(15)) rg_sideleg<-mkReg(0);
323 Reg#(Bit#(`Reg_width)) csr_sedeleg = concatReg2(readOnlyReg(0),rg_sedeleg);
324 Reg#(Bit#(`Reg_width)) csr_sideleg = concatReg2(readOnlyReg(0),rg_sideleg);
326 Reg#(Bit#(`Reg_width)) csr_sie = concatReg13(
328 readOnlyReg(1'b0), readOnlyReg(1'b0), rg_seie, readOnlyReg(rg_ueie),
329 readOnlyReg(1'b0), readOnlyReg(1'b0), rg_stie, readOnlyReg(rg_utie),
330 readOnlyReg(1'b0), readOnlyReg(1'b0), rg_ssie, readOnlyReg(rg_usie));
332 Reg#(Bit#(2)) rg_mode_s <- mkReg(0); //default value 0 if pc to base or 1 if pc to base + 4xcause
333 Reg#(Bit#(TSub#(`Reg_width,2))) rg_stvec <- mkReg(`STVEC_DEFAULT);
334 Reg#(Bit#(`Reg_width)) csr_stvec=concatReg2(rg_stvec,rg_mode_s);
335 Reg#(Bit#(32)) rg_scounteren <- mkReg(0);
336 Reg#(Bit#(`Reg_width)) csr_scounteren = concatReg2(readOnlyReg(0),rg_scounteren);
338 //Supervisor Trap Handling Register
339 Reg#(Bit#(`VADDR)) rg_stval <- mkReg(0);
340 Reg#(Bit#(`Reg_width)) csr_sscratch <- mkReg(0);
341 Reg#(Bit#(`Reg_width)) csr_sepc <- mkReg(0);
342 Reg#(Bit#(`Reg_width)) csr_scause <- mkReg(0);
343 Reg#(Bit#(`Reg_width)) csr_stval = concatReg2(readOnlyReg(0), rg_stval);
344 Reg#(Bit#(`Reg_width)) csr_sip = concatReg13(
346 readOnlyReg(1'b0), readOnlyReg(1'b0), readOnlyReg(rg_seip), rg_ueip,
347 readOnlyReg(1'b0), readOnlyReg(1'b0), readOnlyReg(rg_stip), readOnlyReg(rg_utip),
348 readOnlyReg(1'b0), readOnlyReg(1'b0), rg_ssip, readOnlyReg(rg_usip));
350 //Supervisor Protection and Translation
351 Reg#(Bit#(`Reg_width)) csr_satp <- mkReg(0);
353 //////////////////////////////////////////////////////////////////////////////////////////
354 //////////////////////////////// User level registers ///////////////////////////////////
356 Reg#(Bit#(`Reg_width)) csr_uinstret=readOnlyReg(csr_minstret[1]);
357 Reg#(Bit#(`Reg_width)) csr_ucycle=readOnlyReg(csr_mcycle[1]);
359 Reg#(Bit#(`Reg_width)) csr_uinstret=readOnlyReg(csr_minstret[1]);
360 Reg#(Bit#(`Reg_width)) csr_ucycle=readOnlyReg(csr_mcycle[1]);
361 Reg#(Bit#(`Reg_width)) csr_uinstreth=readOnlyReg(csr_minstreth[1]);
362 Reg#(Bit#(`Reg_width)) csr_ucycleh=readOnlyReg(csr_mcycleh[1]);
365 Reg#(Bit#(`Reg_width)) rg_clint_mtime <-mkReg(0);
366 Reg#(Bit#(5)) rg_fflags<-mkReg(0);
367 Reg#(Bit#(3)) rg_frm<-mkReg(0);
368 Reg#(Bit#(`Reg_width)) csr_fcsr = writeSideEffect(concatReg3(readOnlyReg(0),rg_frm,rg_fflags),rg_fs._write(2'b11));
369 Reg#(Bit#(`Reg_width)) csr_fflags=writeSideEffect(concatReg2(readOnlyReg(0),rg_fflags),rg_fs._write(2'b11));
370 Reg#(Bit#(`Reg_width)) csr_frm = writeSideEffect(concatReg2(readOnlyReg(0),rg_frm),rg_fs._write(2'b11));
371 Reg#(Bit#(4)) rg_memse <- mkReg(0); //0th-bit set -> immu disable,1th-bit set -> icache,2nd-bit -> dmmu, 3rd bit -> dcache
372 Reg#(Bit#(`Reg_width)) csr_memse = concatReg2(readOnlyReg(0),rg_memse);
374 //////////////////////////////////////////////////////////////////////////////////////////
375 ///////////////////////////////////////// PErformance Counters //////////////////////////
377 Array#(Reg#(Bit#(64))) csr_mhpmcounter[`MHPMCOUNTEND-`MHPMCOUNTSTART+1];
378 Reg#(Bit#(`Reg_width)) csr_mhpmevent[`MHPMCOUNTEND-`MHPMCOUNTSTART+1];
379 for(Integer i=0;i<=(`MHPMCOUNTEND-`MHPMCOUNTSTART);i=i+1)begin
380 csr_mhpmcounter[i]<-mkCReg(2,0);
382 csr_mhpmevent[0]<-mkReg('h20000000);
383 csr_mhpmevent[1]<-mkReg('h20000);
384 csr_mhpmevent[2]<-mkReg('h4000);
387 //////////////////////////////////////////////////////////////////////////////////////////
388 ///////////////////////////////////////// Debug Registers /////////////////////////////////
391 Reg#(Bool) resetmode[2]<-mkCReg(2,False); // TODO
392 Reg#(Bit#(1)) ebreakm<-mkReg(1);
393 Reg#(Bit#(1)) ebreaks<-mkReg(1);
394 Reg#(Bit#(1)) ebreaku<-mkReg(1);
396 Reg#(Bool) resetmode[2]<-mkCReg(2,False); // TODO
397 Reg#(Bit#(1)) ebreakm<-mkReg(0);
398 Reg#(Bit#(1)) ebreaks<-mkReg(0);
399 Reg#(Bit#(1)) ebreaku<-mkReg(0);
401 Reg#(Bit#(1)) stopcount<-mkReg(0);
402 Reg#(Bit#(1)) stoptime <-mkReg(0);
403 Reg#(Bit#(3)) debugcause<-mkReg(0);
404 Reg#(Bit#(1)) step<-mkReg(0);
405 Reg#(Bit#(2)) debugprv<-mkReg(0);
406 Reg#(Bit#(32)) dcsr=concatReg13(readOnlyReg(4'd4), readOnlyReg(12'd0),
407 ebreakm,readOnlyReg(1'b0),ebreaks,ebreaku,
410 readOnlyReg(debugcause),readOnlyReg(3'd0),
412 Reg#(Bit#(`VADDR)) dpc <-mkReg(0);
413 Reg#(Bit#(`Reg_width)) csr_dpc=concatReg2(readOnlyReg('d0),dpc);
414 Reg#(Bit#(`Reg_width)) dscratch0<-mkReg(0);
415 Reg#(Bool) debugmode_active[2]<-mkCReg(2,False);
416 Reg#(Bit#(`Reg_width)) debugentry<-mkReg(`DebugBase);
417 //////////////////////////////////////////////////////////////////////////////////////////
418 //////////////////////// Trigger Registers ////////////////////////////////////////
419 Reg#(Bit#(`Reg_width)) tselect=readOnlyReg('d0);
420 Reg#(Bit#(4)) trigger_type=readOnlyReg('d2);
421 Reg#(Bit#(1)) dmode=readOnlyReg(1'd0);
422 Reg#(Bit#(6)) maskmax=readOnlyReg(6'd0);
423 Reg#(Bit#(1)) select<-mkReg(0);
424 Reg#(Bit#(1)) timing=readOnlyReg(1'b0);
425 Reg#(Bit#(6)) triggeraction=readOnlyReg(6'd0); // always enter debug mode.
426 Reg#(Bit#(1)) chain<-mkReg(0);
427 Reg#(Bit#(4)) triggermatch<-mkReg(0);
428 Reg#(Bit#(1)) triggerm<-mkReg(0);
429 Reg#(Bit#(1)) triggers<-mkReg(0);
430 Reg#(Bit#(1)) triggeru<-mkReg(0);
431 Reg#(Bit#(1)) execute<-mkReg(0);
432 Reg#(Bit#(1)) store<-mkReg(0);
433 Reg#(Bit#(1)) load<-mkReg(0);
434 Reg#(Bit#(`Reg_width)) tdata1=concatReg16(trigger_type,dmode,maskmax,
435 readOnlyReg(33'd0),select,timing,
436 triggeraction,chain,triggermatch,
437 triggerm,readOnlyReg(1'b0),triggers,triggeru,
439 Reg#(Bit#(`Reg_width)) tdata2<-mkReg(0);
440 Wire#(TriggerData) executetrigger<-mkDWire(TriggerData{ttype:tagged None,matchscheme:0});
441 Wire#(TriggerData) loadtrigger<-mkDWire(TriggerData{ttype:tagged None,matchscheme:0});
442 Wire#(TriggerData) storetrigger<-mkDWire(TriggerData{ttype:tagged None,matchscheme:0});
443 Reg#(Bool) rg_step_now<-mkReg(False);
444 rule generate_trigger_info_decode;
445 if(execute==1 && ((rg_prv==User &&triggeru==1)||(rg_prv==Supervisor &&triggers==1)||(rg_prv==Machine &&triggerm==1)) )
446 executetrigger<=TriggerData{ttype:select==0?tagged Address tdata2:tagged Data tdata2,matchscheme:triggermatch};
447 if(load==1&& ((rg_prv==User &&triggeru==1)||(rg_prv==Supervisor &&triggers==1)||(rg_prv==Machine &&triggerm==1)) )
448 loadtrigger<=TriggerData{ttype:select==0?tagged Address tdata2:tagged Data tdata2,matchscheme:triggermatch};
449 if(store==1&& ((rg_prv==User &&triggeru==1)||(rg_prv==Supervisor &&triggers==1)||(rg_prv==Machine &&triggerm==1)) )
450 storetrigger<=TriggerData{ttype:select==0?tagged Address tdata2:tagged Data tdata2,matchscheme:triggermatch};
454 function Bool checktrigger(TriggerData tdata, Bit#(`VADDR) pc1, Bit#(32) instruction);
455 Bit#(`Reg_width) pc=zeroExtend(pc1);
456 if(tdata.ttype matches tagged Address .addr)
457 if(tdata.matchscheme==0 && addr==pc)
459 else if(tdata.matchscheme==2 && addr>=pc)
461 else if(tdata.matchscheme==3 && addr<=pc)
463 else if(tdata.matchscheme==4 && addr[31:0]==(addr[63:32]&pc[31:0]))
465 else if(tdata.matchscheme==5 && addr[31:0]==(addr[`Reg_width-1:32]&pc[`Reg_width-1:32]))
469 else if(tdata.ttype matches tagged Data .data)
470 if(data[31:0]==instruction)
478 /////////// Functions to access CSRs /////////////////////////////////////////////////////////////
479 function Reg#(Bit#(`Reg_width)) read_user_sro_registers(Bit#(8) addr);
480 Reg#(Bit#(`Reg_width)) csr=(case(addr)
482 `UTIME :readOnlyReg(rg_clint_mtime);
483 `UINSTRET :csr_uinstret;
485 `UCYCLEH :csr_ucycleh;
486 `UINSTRETH :csr_uinstreth;
488 default:readOnlyReg(0);
492 function Reg#(Bit#(`Reg_width)) read_user_srw_registers(Bit#(8) addr);
493 Reg#(Bit#(`Reg_width)) csr=(case(addr)
494 `FFLAGS :csr_fflags ;
498 default: readOnlyReg(0);
503 function Reg#(Bit#(`Reg_width)) read_supervisor_srw_registers(Bit#(8) addr);
504 Reg#(Bit#(`Reg_width)) csr=(case(addr)
505 `SSTATUS :csr_sstatus;
506 `SEDELEG :csr_sedeleg;
507 `SIDELEG :csr_sideleg;
510 `SCOUNTEREN :csr_scounteren;
511 `SSCRATCH :csr_sscratch;
517 default:readOnlyReg(0);
522 function Reg#(Bit#(`Reg_width)) read_machine_srw_registers(Bit#(8) address);
523 Reg#(Bit#(`Reg_width)) csr=(case(address)
524 `MSTATUS :csr_mstatus;
526 `MEDELEG :csr_medeleg;
527 `MIDELEG :csr_mideleg;
530 `MCOUNTEREN :csr_mcounteren;
531 `MSCRATCH :csr_mscratch;
533 `MCAUSE :((rg_mxl==1)?concatReg3(readOnlyReg(32'd0), rg_interrupt, rg_lower_cause):csr_mcause);
536 `MPOWERCONTROL :csr_power_control;
537 `PMPCFG0 :csr_pmpcfg0;
539 `PMPCFG1 :csr_pmpcfg1;
541 `PMPCFG2 :csr_pmpcfg2;
543 `PMPCFG3 :csr_pmpcfg3;
547 if(address>=`PMPADDRSTART && address<=`PMPADDREND) // lower 4 bits of the counter
548 csr_pmpaddr[address[3:0]];
549 else if(address>=`MHPMEVENTSTART && address<=`MHPMEVENTEND) // lower 32 bits of the counter
550 csr_mhpmcounter[(address-3)[1:0]][1];
558 function Reg#(Bit#(`Reg_width))read_machine_sro_registers(Bit#(8) address);
559 Reg#(Bit#(`Reg_width)) csr=(case(address)
560 `MVENDORID:csr_mvendorid;
561 `MARCHID :csr_marchid;
563 `MHARTID :csr_mhartid;
564 `MBOOTSEQ : csr_boot_seq;
565 default:readOnlyReg(0);
570 function Reg#(Bit#(`Reg_width)) read_machine_counters(Bit#(8) address);
571 Reg#(Bit#(`Reg_width)) csr=(case(address)
572 `MCYCLE :csr_mcycle[1];
573 `MINSTRET :csr_minstret[1];
575 `MCYCLEH :csr_mcycleh[1];
576 `MINSTRETH :csr_minstreth[1];
580 if(address>=`MHPMCOUNTSTART && address<=`MHPMCOUNTEND) // lower 32 bits of the counter
581 csr_mhpmcounter[(address-3)[1:0]][1];
590 function Reg#(Bit#(`Reg_width)) read_debug_registers(Bit#(8) address);
591 Reg#(Bit#(`Reg_width)) csr=(case(address)
592 `DCSR: concatReg2(readOnlyReg(32'd0),dcsr);
594 `DSCRATCH0: dscratch0;
595 `DENTRY : debugentry;
599 default:readOnlyReg(0);
604 function Reg#(Bit#(`Reg_width)) read_csr(Bit#(12) addr);
605 Reg#(Bit#(`Reg_width)) csr=(
607 'h0: read_user_srw_registers(truncate(addr)); // user standard read-write
608 'hC: read_user_sro_registers(truncate(addr)); // user standard read-only
609 `ifdef MMU 'h1: read_supervisor_srw_registers(truncate(addr)); `endif // supervisor read-write
610 'h3: read_machine_srw_registers(truncate(addr)); // machine standard read-write
611 'hF: read_machine_sro_registers(truncate(addr)); // machine standard read-only
612 'hB: read_machine_counters(truncate(addr)); // machine standard counters
613 `ifdef Debug 'h7: read_debug_registers(truncate(addr)); `endif
614 default: readOnlyReg(0);//read_perfcounter(address);
620 function Bool hasCSRPermission(Bit#(12) address, Bool write);
621 Bit#(12) csr_index = pack(address);
622 Bool check_counter_permission = True;
623 if(address >= 12'hB00 && address <= 12'hB1F) begin
624 check_counter_permission = False;
625 if(pack(rg_prv) == 3)
626 check_counter_permission = True;
627 else if(pack(rg_prv) == 1 && csr_mcounteren[address[4:0]]==1)
628 check_counter_permission = True;
630 else if(pack(rg_prv) == 0 && csr_scounteren[address[4:0]]==1)
631 check_counter_permission = True;
634 return ((pack(rg_prv) >= csr_index[9:8]) && check_counter_permission && !(write && csr_index[11:10]==2'b11) );//(!write || (csr_index[11:10] != 2'b11))) || check_counter_permission);
637 // if the operand is not 0 then the instruction will perform a write on the CSR.
638 function Bool valid_csr_access(Bit#(12) csr_addr, Bit#(5) operand, Bit#(2) operation);
639 Bool ret = hasCSRPermission(unpack(csr_addr), (operand != 0 || operation=='b01) ? True:False);
643 function Bool address_valid(Bit#(12) csr_address);
644 case(csr_address[11:8])
646 if((csr_address[7:0]>'h5 && csr_address[7:0]<'h40) ||
647 (csr_address[7:0]>'h44))
653 if((csr_address[7:0]==1)||
654 (csr_address[7:0]>'h6 && csr_address[7:0]<'h40) ||
655 (csr_address[7:0]>'h44 && csr_address[7:0]!='h80))
660 'h3: begin // machine read-write registers
661 if((csr_address[7:0]>'h6 && csr_address[7:0]<'h23) ||
662 (csr_address[7:0]>'h26 && csr_address[7:0]<'h40) ||
663 (csr_address[7:0]>'h44 && csr_address[7:0]<='hA0) ||
664 (csr_address[7:0]>'hA3 && csr_address[7:0]<'hB8) ||
665 (csr_address[7:0]>'hbf))
671 if((csr_address[7:0]<'hA0)||
672 (csr_address[7:0]>'hA3 && csr_address[7:0]<'hB0)||
673 (csr_address[7:0]>'hB2))
679 if((csr_address[7:0]>'h6 && csr_address[7:0]<'h80 && csr_address[7:0]!='h20)||
680 (csr_address[7:0]>'h86 && csr_address[7:0]<'hA0)||
681 (csr_address[7:0]>'hA6))
687 if((csr_address[7:0]>'h6 && csr_address[7:0]<'h83)||
688 (csr_address[7:0]>'h86))
694 if(csr_address[7:0]<'h11 || csr_address[7:0]>'h15)
699 default:return False;
703 rule increment_cycle_counter `ifdef Debug (stopcount==0) `endif ;
705 csr_mcycle[0]<=csr_mcycle[0]+1;
707 Bit#(64) new_cycle={csr_mcycleh[0],csr_mcycle[0]);
708 new_cycle=new_cycle+1;
709 csr_mcycle[0]<=new_cycle[31:0];
710 csr_mcycleh[0]<=new_cycle[63:32];
715 // Check pending interrupts
716 function ActionValue#(Trap_type) fn_chk_pending_interrupt(`ifdef Debug Bool haltreq, Bool resumereq , Bool resetreq`endif )=
719 Bit#(15) pending_debug_interrupt=0;
720 if(haltreq && !debugmode_active[0] && !resetmode[0])
721 pending_debug_interrupt[12]=1;
722 if(resumereq && debugmode_active[0] && !resetmode[0])
723 pending_debug_interrupt[13]=1;
724 if(resetreq && !resetmode[0] && debugmode_active[0])
725 pending_debug_interrupt[14]=1;
727 Bit#(`Reg_width) lv_csr_mip = csr_mip;
728 lv_csr_mip[11]=lv_csr_mip[11]|pack(rg_nmi);
729 Bit#(15) pending_interrupts = (truncate(csr_mip)`ifdef Debug |pending_debug_interrupt `endif ) & truncate(csr_mie) ;
730 `ifdef verbose $display("Pending_interrupts in the beginning csr_mip : %b pending_interrupt: %b", csr_mip, pending_interrupts); `endif
732 let pending_machine_interrupts = pending_interrupts & ~truncate(csr_mideleg);
733 let machine_interrupts_enabled = (rg_mie == 1) || (pack(rg_prv) < pack(Machine));
736 let pending_supervisor_interrupts = pending_interrupts & truncate(csr_mideleg) & ~truncate(csr_sideleg);
737 let supervisor_interrupts_enabled = (rg_sie == 1) && (pack(rg_prv) <= pack(Supervisor));
741 pending_interrupts = (machine_interrupts_enabled ? pending_machine_interrupts : 0)
742 `ifdef MMU |(supervisor_interrupts_enabled ? pending_supervisor_interrupts : 0) `endif ;
744 // format pendingInterrupt value to return
745 Trap_type ret = tagged None;
746 if (pending_interrupts != 0) begin
747 ret = tagged Interrupt unpack(zeroExtend(pack(countZerosLSB(pending_interrupts))));
749 `ifdef verbose $display("Debug interrupts: %h pending_interrupt: %h csr_mie: %h rg_mie: %b ret: ",`ifdef Debug pending_debug_interrupt `else 0 `endif ,pending_interrupts,csr_mie,rg_mie,fshow(ret)); `endif
754 method ActionValue#(Tuple2#(Bit#(3),Trap_type)) check_for_trap(`ifdef Debug Bool haltreq, Bool resumereq, Bool resetreq, `endif Bit#(`VADDR) pc, Bit#(32) instruction)if(!rg_initialize[1] `ifdef simulate && !wr_endsimulation `endif );
755 Trap_type trap_type=tagged None;
756 Bit#(3) lv_debugcause=0;
757 let opcode=instruction[6:2];
758 if(opcode==`CSR_op)begin
759 case(instruction[14:12])
760 'd0:case (instruction[31:20])
762 trap_type=tagged Exception(case(rg_prv) User: Ecall_from_user; Supervisor:Ecall_from_supervisor;Machine:Ecall_from_machine;endcase);
763 'h001:begin // EBREAK
765 Bit#(4) ebreak={ebreakm,0,ebreaks,ebreaku};
766 if((ebreak)[pack(rg_prv)]==1)
767 trap_type=tagged Interrupt DebugInterrupt;
770 trap_type=tagged Exception Breakpoint;
774 if(pack(rg_prv)<pack(Supervisor)) trap_type=tagged Exception Illegal_inst;
777 if(pack(rg_prv)<pack(Machine)) trap_type= tagged Exception Illegal_inst;
781 Bool address_is_valid=address_valid(instruction[31:20]);
782 Bool access_is_valid=valid_csr_access(instruction[31:20],instruction[19:15], instruction[13:12]);
783 `ifdef verbose $display($time,"\tCSR: Address: %h AddressValid: %b AccessValid: %b",instruction[31:20],address_is_valid,access_is_valid); `endif
784 if(!(address_is_valid && access_is_valid))
785 trap_type=tagged Exception Illegal_inst;
789 if(opcode==`FMADD_op || opcode==`FNMSUB_op || opcode==`FNMADD_op || opcode==`FMSUB_op || opcode==`FLOAT_op)begin
790 if(instruction[14:12]=='b111 && rg_frm>4)
791 trap_type=tagged Exception Illegal_inst;
793 if((opcode[4:3]=='b10 || opcode==`FSTORE_op || opcode==`FLOAD_op) && rg_fs==0)
794 trap_type=tagged Exception Illegal_inst;
796 if(checktrigger(executetrigger,pc,instruction))begin
797 `ifdef verbose $display("TRAP: Trigger Fired Debug Interupt"); `endif
798 trap_type=tagged Exception Breakpoint;
802 let pending_interrupt <- fn_chk_pending_interrupt(`ifdef Debug haltreq,resumereq, resetreq `endif );// TODO but resume request here
803 if(pending_interrupt matches tagged Interrupt .interrupt) begin
804 `ifdef verbose $display($time,"\tinterrupt injected in to pipeline"); `endif
805 trap_type=tagged Interrupt interrupt;
807 if(interrupt ==DebugInterrupt)
808 lv_debugcause=(step==1)?4:3;
811 return tuple2(lv_debugcause,trap_type);
814 method ActionValue#(Tuple4#(Bool,Bit#(`VADDR),Bit#(`Reg_width),Bool)) system_instruction(WriteBackType wbdata ,Bit#(`VADDR) pc, Bit#(`PERFMONITORS) perfmonitor_incr `ifdef simulate , Bit#(32) instruction, Operand_type rd_type, Bit#(5) destination `endif )if(!rg_initialize[1] `ifdef simulate && !wr_endsimulation `endif );
815 Bool flush=True; // TODO flush for only writting on certain csr registers
817 Bit#(`VADDR) jump_address=pc+4;
818 Bit#(`Reg_width) destination_value=0;
819 /*====== Execute the current instruction and generate a halt interrupt on the next ===== */
821 `ifdef verbose $display($time,"CSR: STEP_NOW : %b",rg_step_now); `endif
822 if(step==1 && !debugmode_active[0] && !rg_step_now)
827 /*======================================================================================= */
828 if(wbdata matches tagged SYSTEM .csr)begin
829 let csr_reg=read_csr(csr.csr_address);
830 if(csr.funct3==0)begin
831 case (csr.csr_address[11:8]) matches
833 Privilege_mode next_prv =unpack(rg_mpp);
835 rg_mpp <= pack(User);
837 jump_address=truncate(csr_mepc);
842 if(csr.csr_address[5]==0)begin
843 Privilege_mode next_prv =unpack({1'b0,rg_spp});
845 rg_spp <= pack(User)[0];
847 jump_address=truncate(csr_sepc);
853 Bit#(64) pc1=signExtend(pc[38:0]);
854 $fwrite(dump, rg_prv," 0x%16h",pc1, " (0x%8h", instruction,")" );
855 $fwrite(dump," x%d",destination," 0x%16h",destination_value,"\n");
867 rg_prv<=unpack(debugprv);
868 debugmode_active[0]<=False;
873 if(stopcount==0 && !debugmode_active[0]) begin
874 csr_minstret[0]<=csr_minstret[0]+1;
877 for(Integer i=0;i<=(`MHPMCOUNTEND-`MHPMCOUNTSTART);i=i+1)
878 if((csr_mhpmevent[i]&perfmonitor_incr)!=0 `ifdef Debug && stopcount==0 `endif )
879 csr_mhpmcounter[i][1]<=csr_mhpmcounter[i][1]+1;
881 for(Integer i=0;i<=(`MHPMCOUNTEND-`MHPMCOUNTSTART);i=i+1)begin
882 $display($time,"\tEVENT: :%h %s",csr_mhpmevent[i],event_name(csr_mhpmevent[i])," : %d",csr_mhpmcounter[i][1]);
887 destination_value=csr_reg;
888 `ifdef verbose $display($time,"\tCSR: Dest: %h Value: %h rs1: %h funct3: %d rs1_addr: %d",csr.csr_address,csr_reg,csr.rs1,csr.funct3,csr.rs1_addr); `endif
891 'd1: csr_reg <= csr.rs1; // CSRRW
892 'd2:if(csr.rs1_addr!=0) csr_reg <= csr.rs1 | csr_reg; // CSRRS
893 'd3:if(csr.rs1_addr!=0) csr_reg <= ~(csr.rs1) & csr_reg; // CSRRC
894 'd5: csr_reg <= zeroExtend(csr.rs1_addr); // CSRRWI
895 'd6:if(csr.rs1_addr!=0) csr_reg <= zeroExtend(csr.rs1_addr) | csr_reg; // CSRRSI
896 'd7:if(csr.rs1_addr!=0) csr_reg <= ~(zeroExtend(csr.rs1_addr)) & csr_reg; //CSRRCI
899 Bit#(64) pc1=signExtend(pc[38:0]);
900 $fwrite(dump, rg_prv," 0x%16h",pc1, " (0x%8h", instruction,")" );
901 $fwrite(dump," x%d",destination," 0x%16h",destination_value);
906 else if(wbdata matches tagged RESULT .res)begin
907 for(Integer i=0;i<=(`MHPMCOUNTEND-`MHPMCOUNTSTART);i=i+1)
908 if((csr_mhpmevent[i]&perfmonitor_incr)!=0 `ifdef Debug && stopcount==0 `endif )
909 csr_mhpmcounter[i][1]<=csr_mhpmcounter[i][1]+1;
911 for(Integer i=0;i<=(`MHPMCOUNTEND-`MHPMCOUNTSTART);i=i+1)begin
912 $display($time,"\tEVENT: :%h %s",csr_mhpmevent[i],event_name(csr_mhpmevent[i])," : %d",csr_mhpmcounter[i][1]);
916 Bit#(64) pc1=signExtend(pc[38:0]);
917 $fwrite(dump, rg_prv," 0x%16h",pc1, " (0x%8h", instruction,")" );
921 if(stopcount==0 && !debugmode_active[0])begin
922 csr_minstret[0]<=csr_minstret[0]+1;
926 destination_value=res.aluresult;
927 let newfflags=res.fflags;
929 if((newfflags|rg_fflags)!=rg_fflags)begin
930 rg_fflags<=newfflags|rg_fflags;
935 `ifdef verbose $display("Error: FPU id Dirty and FX field is 0"); `endif
938 Bit#(64) dat=signExtend(res.aluresult);
940 if(rd_type==FloatingRF)
942 $fwrite(dump," f%d",destination," 0x%16h",dat);
944 $fwrite(dump," f%d",destination," 0x%16h",{32'hffffffff,dat[31:0]});
948 $fwrite(dump," x%d",destination," 0x%16h",dat);
952 return tuple4(flush,jump_address,destination_value, commit);
955 method ActionValue#(Tuple2#(Bit#(`VADDR), Bool)) take_trap(Trap_type exception, Bit#(3) lv_debugcause, Bit#(`VADDR) pc, Bit#(`VADDR) badaddr)if(!rg_initialize[1]);
956 Bit#(`VADDR) jump_address=0;
958 if(exception matches tagged Exception .ex)begin
959 if(ex==Inst_addr_misaligned || ex==Inst_access_fault || ex==Inst_pagefault)
961 else if(ex==Illegal_inst)
963 else if(ex!=Load_pagefault && ex!=Load_access_fault && ex!=Load_addr_misaligned && ex!=Store_addr_misaligned && ex!=Store_pagefault && ex!=Store_access_fault)
968 `ifdef verbose $display($time,"\tTrap Type: ",fshow(exception)," debugcause: %d",lv_debugcause," BaddAddr: %h",badaddr); `endif
970 if(exception matches tagged Interrupt .in &&& in==DebugResume)begin
971 if(debugmode_active[0])begin
972 rg_prv<=unpack(debugprv);
973 debugmode_active[0]<=False;
974 jump_address=truncate(dpc);
977 else if(exception matches tagged Interrupt .in &&& in==DebugInterrupt)begin
978 debugmode_active[0]<=True;
979 if(!debugmode_active[0])begin
981 debugcause<=lv_debugcause;
982 debugprv<=pack(rg_prv);
987 jump_address=truncate(debugentry);
989 else if(exception matches tagged Interrupt .in &&& in==DebugReset)begin
994 else if(!debugmode_active[0] && !resetmode[0])begin
996 Bit#(`Reg_width) cause = 0;
997 Bit #(TSub #(`Reg_width, 1)) cause_code = 0;
998 Bit #(1) cause_type = 0;
999 case (exception) matches
1000 tagged Interrupt .i: begin cause_type = 1; cause_code = zeroExtend(pack(i)); end
1001 tagged Exception .e: begin cause_type = 0; cause_code = zeroExtend(pack(e));
1002 `ifdef simulate if(e==Endsimulation) begin
1003 for(Integer i=0;i<=(`MHPMCOUNTEND-`MHPMCOUNTSTART);i=i+1)begin
1004 $display($time,"\tEVENT: %s",event_name(csr_mhpmevent[i])," : %d",csr_mhpmcounter[i][1]);
1006 $finish(0) /*wr_endsimulation <=True*/ ;
1011 cause = {cause_type, cause_code};
1013 Bool delegToS = (pack(rg_prv) <= pack(Supervisor)) && (case (exception) matches
1014 tagged Exception .exceptionCause:begin (((csr_medeleg >> pack(exceptionCause)) & 1) != 0);end
1015 tagged Interrupt .interruptCause: (((csr_mideleg >> pack(interruptCause)) & 1) != 0);
1018 //if(exception matches tagged Exception .ex)
1019 // if(ex==Inst_addr_misaligned || ex==Inst_access_fault || ex==Inst_pagefault || ex==Illegal_inst
1020 // || ex==Load_access_fault || ex==Load_addr_misaligned || ex==Load_pagefault
1021 // || ex==Store_addr_misaligned || ex==Store_access_fault || ex==Store_pagefault)
1022 csr_stval<=zeroExtend(badaddr);
1023 csr_sepc<=signExtend(pc);
1025 rg_spp <= pack(rg_prv)[0];
1027 rg_spie <= rg_sie;//(case (rg_prv) User: rg_uie; Supervisor : rg_sie; endcase);
1028 jump_address=truncate(csr_stvec);
1029 rg_prv <= Supervisor;
1034 if(exception matches tagged Exception .ex)
1035 if(ex==Inst_addr_misaligned || ex==Inst_access_fault || ex==Inst_pagefault || ex==Illegal_inst
1036 || ex==Load_access_fault || ex==Load_addr_misaligned || ex==Load_pagefault
1037 || ex==Store_addr_misaligned || ex==Store_access_fault || ex==Store_pagefault)
1038 csr_mtval<=zeroExtend(badaddr);
1039 csr_mepc<=signExtend(pc);
1041 csr_mcause<= zeroExtend({cause[63], cause[30:1]});
1045 rg_mpp <= pack(rg_prv);
1046 jump_address=truncate(csr_mtvec);
1047 rg_mpie <= rg_mie;//(case (rg_prv) User: rg_uie; `ifdef MMU Supervisor : rg_sie; `endif Machine: rg_mie; endcase);
1058 return tuple2(jump_address,flush);
1060 method Bit#(3) roundingmode if(!rg_initialize[1] `ifdef simulate && !wr_endsimulation `endif );
1063 method Action set_external_interrupt(Tuple2#(Bool,Bool) ex_i) if(!rg_initialize[1] `ifdef simulate && !wr_endsimulation `endif );
1066 if(rg_prv == Machine) begin
1067 `ifdef verbose $display("CSR : Machine external interrupt pending"); `endif
1070 else if(rg_prv == Supervisor) begin
1071 rg_seipe <= pack(i);
1073 else if(rg_prv == User) begin
1074 rg_ueipe <= pack(i);
1077 method Action flush;
1078 rg_initialize[0]<=True;
1081 method Bit#(`Reg_width) send_satp;
1084 method Chmod perm_to_TLB;
1085 return Chmod {mprv : rg_mprv, sum : rg_sum, mxr : rg_mxr, mpp : unpack(rg_mpp), prv : rg_prv};
1088 method Bit#(`Reg_width) mmu_cache_disable;
1093 return debugmode_active[1];
1095 method load_triggerdata=loadtrigger;
1096 method store_triggerdata=storetrigger;
1097 method ActionValue#(Bit#(`Reg_width)) rw_debug_csr(Bit#(12) r, Bool write, Bit#(`Reg_width) data) if(!rg_initialize[1]);
1103 method Bool step_now=rg_step_now;
1104 method Bool reset_mode=resetmode[1];
1106 method Bit#(`Reg_width) misa=csr_misa._read;
1107 method Action boot_sequence(Bit#(1) bootseq);
1108 rg_boot_seq<=bootseq;
1110 method Bit#(2) powercontrol=power_control_out;
1111 method Action poweracknowledge(Bit#(2) pa);
1112 power_control_in<=pa;
1115 method Action clint_msip(Bit#(1) intrpt);
1118 method Action clint_mtip(Bit#(1) intrpt);
1121 method Action clint_mtime(Bit#(`Reg_width) c_mtime);
1122 rg_clint_mtime<=c_mtime;
1125 method inferred_xlen=rg_mxl;