summaryrefslogtreecommitdiff
path: root/riscv/riscv_mem.sail
diff options
context:
space:
mode:
Diffstat (limited to 'riscv/riscv_mem.sail')
-rw-r--r--riscv/riscv_mem.sail48
1 files changed, 32 insertions, 16 deletions
diff --git a/riscv/riscv_mem.sail b/riscv/riscv_mem.sail
index 5ec665e8..87d7e41a 100644
--- a/riscv/riscv_mem.sail
+++ b/riscv/riscv_mem.sail
@@ -1,28 +1,44 @@
/* memory */
+/* TODO: remove this when unused */
function check_alignment (addr : xlenbits, width : atom('n)) -> forall 'n. unit =
if unsigned(addr) % width != 0 then throw Error_misaligned_access() else ()
-val MEMr : forall 'n. (xlenbits, atom('n)) -> bits(8 * 'n) effect {rmem}
-val MEMr_acquire : forall 'n. (xlenbits, atom('n)) -> bits(8 * 'n) effect {rmem}
-val MEMr_strong_acquire : forall 'n. (xlenbits, atom('n)) -> bits(8 * 'n) effect {rmem}
-val MEMr_reserved : forall 'n. (xlenbits, atom('n)) -> bits(8 * 'n) effect {rmem}
-val MEMr_reserved_acquire : forall 'n. (xlenbits, atom('n)) -> bits(8 * 'n) effect {rmem}
-val MEMr_reserved_strong_acquire : forall 'n. (xlenbits, atom('n)) -> bits(8 * 'n) effect {rmem}
+union MemoryOpResult ('a : Type) = {
+ MemValue : 'a,
+ MemException: ExceptionType
+}
-function MEMr (addr, width) = __RISCV_read(addr, width)
-function MEMr_acquire (addr, width) = __RISCV_read(addr, width)
-function MEMr_strong_acquire (addr, width) = __RISCV_read(addr, width)
-function MEMr_reserved (addr, width) = __RISCV_read(addr, width)
-function MEMr_reserved_acquire (addr, width) = __RISCV_read(addr, width)
-function MEMr_reserved_strong_acquire (addr, width) = __RISCV_read(addr, width)
+function is_aligned_addr (addr : xlenbits, width : atom('n)) -> forall 'n. bool =
+ unsigned(addr) % width != 0
-val mem_read : forall 'n. (xlenbits, atom('n), bool, bool, bool) -> bits(8 * 'n) effect {rmem, escape}
+function checked_mem_read(t : ReadType, addr : xlenbits, width : atom('n)) -> forall 'n. MemoryOpResult(bits(8 * 'n)) =
+ match (t, __RISCV_read(addr, width)) {
+ (Instruction, None()) => MemException(E_Fetch_Access_Fault),
+ (Data, None()) => MemException(E_Load_Access_Fault),
+ (_, Some(v)) => MemValue(v)
+ }
-function mem_read (addr, width, aq, rl, res) = {
- if aq | res then check_alignment(addr, width);
+val MEMr : forall 'n. (xlenbits, atom('n)) -> MemoryOpResult(bits(8 * 'n)) effect {rmem}
+val MEMr_acquire : forall 'n. (xlenbits, atom('n)) -> MemoryOpResult(bits(8 * 'n)) effect {rmem}
+val MEMr_strong_acquire : forall 'n. (xlenbits, atom('n)) -> MemoryOpResult(bits(8 * 'n)) effect {rmem}
+val MEMr_reserved : forall 'n. (xlenbits, atom('n)) -> MemoryOpResult(bits(8 * 'n)) effect {rmem}
+val MEMr_reserved_acquire : forall 'n. (xlenbits, atom('n)) -> MemoryOpResult(bits(8 * 'n)) effect {rmem}
+val MEMr_reserved_strong_acquire : forall 'n. (xlenbits, atom('n)) -> MemoryOpResult(bits(8 * 'n)) effect {rmem}
- match (aq, rl, res) {
+function MEMr (addr, width) = checked_mem_read(Data, addr, width)
+function MEMr_acquire (addr, width) = checked_mem_read(Data, addr, width)
+function MEMr_strong_acquire (addr, width) = checked_mem_read(Data, addr, width)
+function MEMr_reserved (addr, width) = checked_mem_read(Data, addr, width)
+function MEMr_reserved_acquire (addr, width) = checked_mem_read(Data, addr, width)
+function MEMr_reserved_strong_acquire (addr, width) = checked_mem_read(Data, addr, width)
+
+val mem_read : forall 'n. (xlenbits, atom('n), bool, bool, bool) -> MemoryOpResult(bits(8 * 'n)) effect {rmem, escape}
+
+function mem_read (addr, width, aq, rl, res) = {
+ if (aq | res) & (~ (is_aligned_addr(addr, width)))
+ then MemException(E_Load_Addr_Align)
+ else match (aq, rl, res) {
(false, false, false) => MEMr(addr, width),
(true, false, false) => MEMr_acquire(addr, width),
(false, false, true) => MEMr_reserved(addr, width),