-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsvcb.txt
119 lines (100 loc) · 3.04 KB
/
svcb.txt
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
/// Rev 1 of the Streamed Value Change Blocks (SVCB) file format.
/// Types used in the file format
u1 := 1 bit integer, little endian, eight u1 to a byte
u2 := 2 bit integer, little endian, four u2 to a byte
u4 := 4 bit integer, little endian, two u4 to a byte
u32 := 32 bit unsigned integer, little endian
u64 := 64 bit unsigned integer, little endian
lebu32 := lebu128, maximum of u32::MAX
lebu64 := lebu128, maximum of u64::MAX,
// up to eight two-logic values to a byte
two-logic := u1 ∈ {
0,
1,
}
// up to four four-logic values to a byte
four-logic := u2 ∈ {
0,
1,
2 (unknown),
3 (high impedance),
}
// up to two nine-logic values to a byte
nine-logic := u4 ∈ {
0 (zero, strong drive),
1 (one, strong drive),
2 (zero, weak drive),
3 (one, weak drive),
4 (unknown, strong drive),
5 (unknown, weak drive),
6 (zero, unknown drive),
7 (one, unknown drive),
8 (high impedance),
}
unsized-vec(T) := sequence of T
stream(T) := sequence of T, can be streamed rather than all present in memory
vec(T) :=
length := u32
sequence of T, *length* items long
compact-vec(T) :=
length := lebu32
sequence of T, *length* items long
string := vec(utf-8 encoded byte)
storage :=
id := u32
type := u32 ∈ { TWO_LOGIC := 0, FOUR_LOGIC := 1, NINE_LOGIC := 2 }
width := u32
// the index at which the storage starts, e.g. wire[31:7] starts at 7
start := u32
enum-specification :=
name := string
value := unsized-vec(two-logic)
variable :=
scope-id := u32
name := string
interpretation := u32 ∈ { NONE := 0, INTEGER := 1, ENUM := 2, UTF-8 := 3 }
match interpretation {
NONE | UTF-8 => storage-id := u32,
ENUM => {
storage-id := u32,
enum-specs := vec(enum-specification),
},
INTEGER => {
storage-ids := vec(u32),
msb := u32 // most significant bit index
lsb := u32 // least significant bit index
signedness := u32 ∈ { SIGNED_TWOS_COMPLEMENT := 0, UNSIGNED := 1 }
}
}
scope :=
// 0 is the automatic top-level parent scope, must declare a scope before being its child
parent-scope-id := u32
// Therefore, scope-id cannot be 0
scope-id := u32
name := string
value-change :=
storage-id := lebu32
match storages[storage-id].type {
TWO_LOGIC => unsized-vec(two-logic),
FOUR_LOGIC => unsized-vec(four-logic),
NINE_LOGIC => unsized-vec(nine-logic),
}
block :=
type := u8 ∈ { SCOPE := 0, VARIABLE := 1, STORAGE := 2, VALUE_CHANGE := 3, TIMESTEP := 4 }
match type {
SCOPE => scope,
VARIABLE => variable,
STORAGE => storage,
VALUE_CHANGE => compact-vec(value-change),
TIMESTEP => lebu64, // timesteps since previous timestep block
}
/// The file format
rev-1 :=
timescale := u128 // femtoseconds per timestep
blocks := stream(block)
svcb :=
magic := [u8; 4], must be 's', 'v', 'c', 'b'
version := u32
match version {
1 => rev-1,
}