22# Licensed under the Apache License, Version 2.0, see LICENSE for details.
33# SPDX-License-Identifier: Apache-2.0
44
5+ """Export RDL to opentitan RTL."""
6+
57import json
68from pathlib import Path
79
1416DEFAULT_INTERFACE_NAME = "regs"
1517
1618
17- def run (rdlc : RDLCompiler , obj : node .RootNode , out_dir : Path ):
19+ def run (rdlc : RDLCompiler , obj : node .RootNode , out_dir : Path ) -> None :
20+ """Export RDL to opentitan RTL."""
1821 factory = OtInterfaceBuilder (rdlc )
1922 data = factory .parse_root (obj .top )
20- with open ( "/tmp/reg .json", "w" , encoding = "utf-8" ) as f :
23+ with ( out_dir / "rdl .json"). open ( "w" , encoding = "utf-8" ) as f :
2124 json .dump (data , f , indent = 2 )
2225
2326 file_loader = FileSystemLoader (TEMPLATES_DIR )
2427 env = Environment (loader = file_loader )
2528
2629 ip_name = data ["ip_name" ]
2730 reg_pkg_tpl = env .get_template ("reg_pkg.sv.tpl" )
28- # stream = reg_pkg_tpl.stream(data)
2931 stream = reg_pkg_tpl .render (data )
3032 path = out_dir / f"{ ip_name } _reg_pkg.sv"
3133 path .open ("w" ).write (stream )
@@ -35,14 +37,15 @@ def run(rdlc: RDLCompiler, obj: node.RootNode, out_dir: Path):
3537 for interface in data ["interfaces" ]:
3638 name = "_{}" .format (interface ["name" ].lower ()) if "name" in interface else ""
3739 data_ = {"ip_name" : ip_name , "interface" : interface }
38- # stream = reg_top_tpl.stream(data_)
3940 stream = reg_top_tpl .render (data_ ).replace (" \n " , "\n " )
4041 path = out_dir / f"{ ip_name } { name } _reg_top.sv"
4142 path .open ("w" ).write (stream )
4243 print (f"Generated { path } ." )
4344
4445
4546class OtInterfaceBuilder :
47+ """Opentitan Interface Builder."""
48+
4649 num_regs : int = 0 # The number of registers of an interface
4750 num_windows : int = 0 # The number of registers of an interface
4851 any_async_clk : bool = False # Whether is there any register with async clock in the interface
@@ -52,13 +55,13 @@ class OtInterfaceBuilder:
5255 reg_index : int = 0
5356 rdlc : RDLCompiler
5457
55- def __init__ (self , rdlc : RDLCompiler ):
58+ def __init__ (self , rdlc : RDLCompiler ) -> None :
59+ """Constructor."""
5660 self .rdlc = rdlc
5761
5862 def get_field (self , field : node .FieldNode ) -> dict :
59- """Parse a field and return a dictionary.
60- """
61- obj = dict ()
63+ """Parse a field and return a dictionary."""
64+ obj = {}
6265 obj ["name" ] = field .inst_name
6366 obj ["type" ] = "field"
6467 obj ["desc" ] = field .get_property ("desc" , default = "" )
@@ -91,9 +94,8 @@ def get_field(self, field: node.FieldNode) -> dict:
9194 return obj
9295
9396 def get_mem (self , mem : node .FieldNode ) -> dict :
94- """Parse a memory and return a dictionary representing a window.
95- """
96- obj = dict ()
97+ """Parse a memory and return a dictionary representing a window."""
98+ obj = {}
9799 obj ["name" ] = mem .inst_name
98100 obj ["entries" ] = mem .get_property ("mementries" )
99101 obj ["sw_writable" ] = mem .is_sw_writable
@@ -107,9 +109,8 @@ def get_mem(self, mem: node.FieldNode) -> dict:
107109 return obj
108110
109111 def get_reg (self , reg : node .RegNode ) -> dict :
110- """Parse a register and return a dictionary.
111- """
112- obj = dict ()
112+ """Parse a register and return a dictionary."""
113+ obj = {}
113114 obj ["name" ] = reg .inst_name
114115 obj ["type" ] = "reg"
115116 obj ["width" ] = reg .get_property ("regwidth" )
@@ -140,8 +141,8 @@ def get_reg(self, reg: node.RegNode) -> dict:
140141 msb = 0
141142 reset_val = 0
142143 bitmask = 0
143- for field in reg .fields ():
144- field = self .get_field (field )
144+ for f in reg .fields ():
145+ field = self .get_field (f )
145146 obj ["fields" ].append (field )
146147 sw_write_en |= field ["sw_write_en" ]
147148 msb = max (msb , field ["msb" ])
@@ -175,17 +176,14 @@ def get_reg(self, reg: node.RegNode) -> dict:
175176 return obj
176177
177178 def get_paramesters (self , obj : node .AddrmapNode | node .RegfileNode ) -> [dict ]:
178- """Parse the custom property localparams and return a list of dictionaries.
179- """
180- res = [
179+ """Parse the custom property localparams and return a list of dictionaries."""
180+ return [
181181 {"name" : param .name , "type" : "int" , "value" : param .get_value ()}
182182 for param in obj .inst .parameters
183183 ]
184- return res
185184
186185 def get_interface (self , addrmap : node .AddrmapNode , defalt_name : None | str = None ) -> dict :
187- """Parse an interface and return a dictionary.
188- """
186+ """Parse an interface and return a dictionary."""
189187 self .num_regs = 0
190188 self .num_windows = 0
191189 self .any_async_clk = False
@@ -196,7 +194,7 @@ def get_interface(self, addrmap: node.AddrmapNode, defalt_name: None | str = Non
196194 if addrmap .is_array :
197195 print (f"WARNING: Unsupported array type: { type (addrmap )} , skiping..." )
198196
199- interface = dict ()
197+ interface = {}
200198 if defalt_name :
201199 interface ["name" ] = addrmap .inst_name or defalt_name
202200
@@ -233,21 +231,20 @@ def get_interface(self, addrmap: node.AddrmapNode, defalt_name: None | str = Non
233231 interface ["all_async_clk" ] = self .all_async_clk
234232 interface ["any_shadowed_reg" ] = self .any_shadowed_reg
235233 interface ["any_integrity_bypass" ] = any (
236- [ win ["integrity_bypass" ] for win in interface ["windows" ] ]
234+ win ["integrity_bypass" ] for win in interface ["windows" ]
237235 )
238236 return interface
239237
240238 def parse_root (self , root : node .AddrmapNode ) -> dict :
241- """Parse the root node and return a dictionary representing a window.
242- """
239+ """Parse the root node and return a dictionary representing a window."""
243240 if root .is_array :
244241 print ("Error: Unsupported array type on the top" )
245242 raise RuntimeError
246243 if not isinstance (root , node .AddrmapNode ):
247244 print ("Error: Top level must be an addrmap" )
248- raise RuntimeError
245+ raise TypeError
249246
250- obj = dict ()
247+ obj = {}
251248 params = self .get_paramesters (root )
252249 if params :
253250 obj ["parameters" ] = params
@@ -263,10 +260,10 @@ def parse_root(self, root: node.AddrmapNode) -> dict:
263260 continue
264261 else :
265262 print (
266- f"""Error: Unsupported type: { type (child )} , top level only supports
263+ f"""Error: Unsupported type: { type (child )} , top level only supports
267264 addrmap and reg components."""
268265 )
269- raise RuntimeError
266+ raise TypeError
270267
271268 # If the root contain imediate registers, use a default interface name
272269 if len (root .registers ()) > 0 :
0 commit comments