Skip to content

Commit ae4b640

Browse files
author
Rhys Gretsch
committed
Implement a language agnostic hardware representation
1 parent 679eb13 commit ae4b640

File tree

4 files changed

+540
-3
lines changed

4 files changed

+540
-3
lines changed

pyrtl/hardwareSchema.py

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
2+
def hardwareSchema():
3+
''' This function holds the schemas to check that any json hardware
4+
representation conforms to the same requirements
5+
6+
All components except for inputs should have some driving logic
7+
If the driving logic does not list an operation it is a simple
8+
assignment operation (destination = argument)
9+
10+
Arguments should always be listed from left to right as one might
11+
read them in a language like verilog
12+
EX. a + b becomes op='+', args=[a,b]
13+
Ex. a ? b : c becomes op='?', args=[a, b, c]
14+
Ex. {a, b} becomes op='concat', args=[a,b]
15+
16+
If the module does not have a primary component (inputs, outputs,
17+
registers, wires, memory) their field should be included with an
18+
empty list
19+
20+
'''
21+
22+
nameSchema = {
23+
"description": "The component's name",
24+
"type": "string"
25+
}
26+
27+
bitwidthSchema = {
28+
"description": "The number of bits this component contains",
29+
"type": "integer"
30+
}
31+
32+
componentSchema = {
33+
"name": nameSchema,
34+
"bitwidth": bitwidthSchema,
35+
"Constant value": {
36+
"description": "If this is a constant this field holds its constant value",
37+
"type": "integer"
38+
},
39+
"driver": {
40+
"description": "The operation or wire that drives this component",
41+
"type": "object",
42+
"properties": {
43+
"op": {
44+
"description": "Logical operation whose output is driving this component",
45+
"type": "string"
46+
},
47+
"args": {
48+
"description": """A list of the arguments of the operation,
49+
in order of left to right""",
50+
"type": "array",
51+
"items": {
52+
"description": "Individual arguments",
53+
"type": "string"
54+
}
55+
},
56+
"src": {
57+
"description": "The component input into a register",
58+
"type": "string"
59+
},
60+
"rst val": {
61+
"description": "If this is a register, this lists what it should be reset to",
62+
"type": "integer"
63+
}
64+
}
65+
}
66+
}
67+
68+
memorySchema = {
69+
"name": nameSchema,
70+
"bitwidth": bitwidthSchema,
71+
"size": {
72+
"description": "The number of addressable locations",
73+
"type": "integer"
74+
},
75+
"initial values": {
76+
"description": "For ROM memory this outlines each address' initial value as an integer",
77+
"type": "array",
78+
"items": {
79+
"description": """The index in the list is the memory address each
80+
intial value maps to""",
81+
"type": "integer"
82+
}
83+
},
84+
"reads": {
85+
"description": "A list of all read operations ocurring on this memory",
86+
"type": "array",
87+
"items": {
88+
"description": "A single memory read operation",
89+
"type": "object",
90+
"properties": {
91+
"destination": {
92+
"description": "The component receiving the result of the read operation",
93+
"type": "string"
94+
},
95+
"addr": {
96+
"description": "The wire name that selects the memory address to be read",
97+
"type": "string"
98+
}
99+
},
100+
"required": ["destination", "addr"]
101+
}
102+
},
103+
"writes": {
104+
"description": "A list of all the write operations to this memory",
105+
"type": "array",
106+
"items": {
107+
"description": "A single memory write operation",
108+
"type": "object",
109+
"properties": {
110+
"addr": {
111+
"description": """The component that selects the
112+
memory address to be written""",
113+
"type": "string"
114+
},
115+
"data src": {
116+
"description": """The component that provides the
117+
data to be written to memory""",
118+
"type": "string"
119+
},
120+
"w.e": {
121+
"description": "The component that controls the write enable if applicable",
122+
"type": "string"
123+
},
124+
},
125+
"required": ["addr", "data src"]
126+
}
127+
}
128+
}
129+
130+
exportSchema = {
131+
# necessary for version control
132+
"$schema": "https://json-schema.org/draft/2020-12/schema",
133+
"title": "JSON Hardware representation",
134+
"type": "object",
135+
"properties": {
136+
"module": {
137+
"description": "The top level module",
138+
"type": "object",
139+
"properties": {
140+
"name": {
141+
"description": "The module name",
142+
"type": "string"
143+
},
144+
"inputs": {
145+
"description": "List of inputs to the module",
146+
"type:": "array",
147+
"items": {
148+
"description": "An input into the module",
149+
"type": "object",
150+
"properties": componentSchema,
151+
"required": ["name", "bitwidth"]
152+
},
153+
"uniqueItems": True
154+
},
155+
"outputs": {
156+
"description": "List of the module's outputs",
157+
"type": "array",
158+
"items": {
159+
"description": "An output of the module",
160+
"type": "object",
161+
"properties": componentSchema,
162+
"required": ["name", "bitwidth", "driver"]
163+
},
164+
"uniqueItems": True
165+
},
166+
"wires": {
167+
"description": "List of the internal wires in the module",
168+
"type": "array",
169+
"items": {
170+
"description": "A wire in the module",
171+
"type": "object",
172+
"properties": componentSchema,
173+
"required": ["name", "bitwidth"]
174+
},
175+
"uniqueItems": True
176+
},
177+
"registers": {
178+
"description": "List of the internal registers in the module",
179+
"type": "array",
180+
"items": {
181+
"description": "A register in the module",
182+
"type": "object",
183+
"properties": componentSchema,
184+
"required": ["name", "bitwidth", "driver"]
185+
},
186+
"uniqueItems": True
187+
},
188+
"memories": {
189+
"description": "List of memories and their respective accesses",
190+
"type": "array",
191+
"items": {
192+
"description": "A single memory module",
193+
"type": "object",
194+
"properties": memorySchema,
195+
"required": ['name', 'bitwidth', 'size']
196+
},
197+
"uniqueItems": True
198+
},
199+
},
200+
"required": ["name", "inputs", "outputs",
201+
"wires", "registers", "memories"]
202+
}
203+
}
204+
}
205+
206+
return exportSchema

0 commit comments

Comments
 (0)