44
55from enum import IntFlag , auto , unique
66from typing import Sequence
7- from coreblocks .arch .isa_consts import Funct12 , Funct3 , Funct7 , Opcode , PrivilegeLevel , SatpMode
7+ from coreblocks .arch .isa_consts import Funct12 , Funct3 , Funct7 , Opcode , PrivilegeLevel
88
99
1010from transactron import *
2727 UnsafeInstructionResolvedKey ,
2828 FlushICacheKey ,
2929 WaitForInterruptResumeKey ,
30+ SFenceVMAKey ,
3031)
3132from coreblocks .func_blocks .interface .func_protocols import FuncUnit
3233
@@ -89,6 +90,8 @@ def elaborate(self, platform):
8990 instr_imm = Signal (self .gen_params .isa .xlen )
9091 instr_s1_val = Signal (self .gen_params .isa .xlen )
9192 instr_s2_val = Signal (self .gen_params .isa .xlen )
93+ instr_s1_x0 = Signal ()
94+ instr_s2_x0 = Signal ()
9295
9396 mret = self .dm .get_dependency (MretKey ())
9497 sret = self .dm .get_optional_dependency (SretKey ())
@@ -97,6 +100,7 @@ def elaborate(self, platform):
97100 csr = self .dm .get_dependency (CSRInstancesKey ())
98101 priv_mode = csr .m_mode .priv_mode
99102 flush_icache = self .dm .get_dependency (FlushICacheKey ())
103+ sfence_vma = self .dm .get_optional_dependency (SFenceVMAKey ())
100104 resume_core = self .dm .get_dependency (UnsafeInstructionResolvedKey ())
101105
102106 @def_method (m , self .issue_decoded , ready = ~ instr_valid )
@@ -108,6 +112,8 @@ def _(arg):
108112 instr_fn .eq (arg .decode_fn ),
109113 instr_s1_val .eq (arg .s1_val ),
110114 instr_s2_val .eq (arg .s2_val ),
115+ instr_s1_x0 .eq (arg .rp_s1_reg == 0 ),
116+ instr_s2_x0 .eq (arg .rp_s2_reg == 0 ),
111117 instr_imm .eq (arg .imm ),
112118 ]
113119
@@ -150,8 +156,10 @@ def _(arg):
150156 with branch (info .side_fx & (instr_fn == PrivilegedFn .Fn .SRET ) & ~ illegal_sret ):
151157 sret (m )
152158
153- # TODO: implement proper SFENCE.VMA, for BARE only - NO-OP is ok
154- assert self .gen_params .vmem_params .supported_schemes == {SatpMode .BARE }
159+ if self .gen_params .vmem_params .supported_schemes > {SatpMode .BARE }:
160+ assert sfence_vma is not None
161+ with branch (info .side_fx & (instr_fn == PrivilegedFn .Fn .SFENCEVMA ) & ~ illegal_sfencevma ):
162+ sfence_vma [0 ](m , vaddr = instr_s1_val , asid = instr_s2_val , all_vaddrs = instr_s1_x0 , all_asids = instr_s2_x0 )
155163
156164 with branch (info .side_fx & (instr_fn == PrivilegedFn .Fn .FENCEI )):
157165 flush_icache (m )
0 commit comments