File: rv_add_1.sat.sail

package info (click to toggle)
sail-ocaml 0.19.1%2Bdfsg5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 18,008 kB
  • sloc: ml: 75,941; ansic: 8,848; python: 1,342; exp: 560; sh: 474; makefile: 218; cpp: 36
file content (161 lines) | stat: -rw-r--r-- 4,320 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
default Order dec

$include <prelude.sail>

type xlen       : Int  = 32
type xlen_bytes : Int  = 4
type xlenbits   : Type = bits(xlen)

type regno ('n : Int), 0 <= 'n < 32 = atom('n)
type regbits = bits(5)

val regbits_to_regno : bits(5) -> {'n, 0 <= 'n < 32. regno('n)}
function regbits_to_regno b = unsigned(b)

enum iop = {RISCV_ADDI, RISCV_SLTI, RISCV_SLTIU, RISCV_XORI, RISCV_ORI, RISCV_ANDI}

/* Architectural state */
register R1 : xlenbits
register R2 : xlenbits
register R3 : xlenbits
register R4 : xlenbits
register R5 : xlenbits
register R6 : xlenbits
register R7 : xlenbits
register R8 : xlenbits
register R9 : xlenbits
register R10 : xlenbits
register R11 : xlenbits
register R12 : xlenbits
register R13 : xlenbits
register R14 : xlenbits
register R15 : xlenbits
register R16 : xlenbits
register R17 : xlenbits
register R18 : xlenbits
register R19 : xlenbits
register R20 : xlenbits
register R21 : xlenbits
register R22 : xlenbits
register R23 : xlenbits
register R24 : xlenbits
register R25 : xlenbits
register R26 : xlenbits
register R27 : xlenbits
register R28 : xlenbits
register R29 : xlenbits
register R30 : xlenbits
register R31 : xlenbits

/* Getters and setters for X registers (special case for zeros register, x0) */
val rX : forall 'n, 0 <= 'n < 32. regno('n) -> xlenbits effect {rreg}

function rX(r) = {
  if r == 0 then sail_zero_extend(0x0, sizeof(xlen))
  else if r == 1 then R1
  else if r == 2 then R2
  else if r == 3 then R3
  else if r == 4 then R4
  else if r == 5 then R5
  else if r == 6 then R6
  else if r == 7 then R7
  else if r == 8 then R8
  else if r == 9 then R9
  else if r == 10 then R10
  else if r == 11 then R11
  else if r == 12 then R12
  else if r == 13 then R13
  else if r == 14 then R14
  else if r == 15 then R15
  else if r == 16 then R16
  else if r == 17 then R17
  else if r == 18 then R18
  else if r == 19 then R19
  else if r == 20 then R20
  else if r == 21 then R21
  else if r == 22 then R22
  else if r == 23 then R23
  else if r == 24 then R24
  else if r == 25 then R25
  else if r == 26 then R26
  else if r == 27 then R27
  else if r == 28 then R28
  else if r == 29 then R29
  else if r == 30 then R30
  else R31
}

val wX : forall 'n, 0 <= 'n < 32. (regno('n), xlenbits) -> unit effect {wreg}

function wX(r, v) = {
  if r == 0 then ()
  else if r == 1 then R1 = v
  else if r == 2 then R2 = v
  else if r == 3 then R3 = v
  else if r == 4 then R4 = v
  else if r == 5 then R5 = v
  else if r == 6 then R6 = v
  else if r == 7 then R7 = v
  else if r == 8 then R8 = v
  else if r == 9 then R9 = v
  else if r == 10 then R10 = v
  else if r == 11 then R11 = v
  else if r == 12 then R12 = v
  else if r == 13 then R13 = v
  else if r == 14 then R14 = v
  else if r == 15 then R15 = v
  else if r == 16 then R16 = v
  else if r == 17 then R17 = v
  else if r == 18 then R18 = v
  else if r == 19 then R19 = v
  else if r == 20 then R20 = v
  else if r == 21 then R21 = v
  else if r == 22 then R22 = v
  else if r == 23 then R23 = v
  else if r == 24 then R24 = v
  else if r == 25 then R25 = v
  else if r == 26 then R26 = v
  else if r == 27 then R27 = v
  else if r == 28 then R28 = v
  else if r == 29 then R29 = v
  else if r == 30 then R30 = v
  else R31 = v
}

val rX_bits : bits(5) -> xlenbits effect {rreg}
function rX_bits(r) = rX(regbits_to_regno(r))
val wX_bits : (bits(5), xlenbits) -> unit effect {wreg}
function wX_bits(r,v) = wX(regbits_to_regno(r), v)

overload X = {rX, wX, rX_bits, wX_bits}

scattered union ast

union clause ast = ITYPE : (bits(12), regbits, regbits, iop)

val decode : bits(32) -> option(ast) effect pure

val execute : ast -> unit effect {rmem, rreg, wreg}

function clause decode imm : bits(12) @ rs1 : regbits @ 0b000 @ rd : regbits @ 0b0010011
  = Some(ITYPE(imm, rs1, rd, RISCV_ADDI))

function clause execute (ITYPE (imm, rs1, rd, RISCV_ADDI)) =
  let rs1_val = X(rs1) in
  let imm_ext : xlenbits = sail_sign_extend(imm, sizeof(xlen)) in
  let result = rs1_val + imm_ext in
  X(rd) = result

function clause decode _ = None()

$property
function prop(imm:  bits(12), rs1: regbits, rd: regbits) -> bool = {
  let v = X(rs1);
  match decode(imm @ rs1 @ 0b000 @ rd @ 0b0010011) {
    Some(instr) => {
      execute(instr);
      X(rd) == v + sail_sign_extend(imm, sizeof(xlen))
    },
    _ => false
  }
}