99import requests
1010import subprocess
1111import sys
12- import time
1312
1413import dotenv
15- from pprint import pprint
1614from amaranth import *
17- from amaranth .lib .wiring import connect , flipped
1815
1916from .. import ChipFlowError
2017from ..platforms import SiliconPlatform , top_interfaces
@@ -60,8 +57,12 @@ class SiliconStep:
6057 """Prepare and submit the design for an ASIC."""
6158 def __init__ (self , config ):
6259 self .config = config
63- self .project_name = config ["chipflow" ].get ("project_name" )
64- self .silicon_config = config ["chipflow" ]["silicon" ]
60+
61+ # Also parse with Pydantic for type checking and better code structure
62+ from chipflow_lib .config_models import Config
63+ self .config_model = Config .model_validate (config )
64+ self .project_name = self .config_model .chipflow .project_name
65+ self .silicon_config = config ["chipflow" ]["silicon" ] # Keep for backward compatibility
6566 self .platform = SiliconPlatform (config )
6667
6768 def build_cli_parser (self , parser ):
@@ -96,7 +97,7 @@ def prepare(self):
9697
9798 Returns the path to the RTLIL file.
9899 """
99- return self .platform .build (SiliconTop (self .config ), name = self .config [ " chipflow" ][ " project_name" ] )
100+ return self .platform .build (SiliconTop (self .config ), name = self .config_model . chipflow . project_name )
100101
101102 def submit (self , rtlil_path , * , dry_run = False ):
102103 """Submit the design to the ChipFlow cloud builder.
@@ -111,7 +112,7 @@ def submit(self, rtlil_path, *, dry_run=False):
111112 submission_name = git_head
112113 if git_dirty :
113114 logging .warning ("Git tree is dirty, submitting anyway!" )
114- submission_name += f "-dirty"
115+ submission_name += "-dirty"
115116 dep_versions = {
116117 "python" : sys .version .split ()[0 ]
117118 }
@@ -149,13 +150,15 @@ def submit(self, rtlil_path, *, dry_run=False):
149150 f"dir={ port .direction } , width={ width } " )
150151 pads [padname ] = {'loc' : port .pins [0 ], 'type' : port .direction .value }
151152
153+ # Use the Pydantic models to access configuration data
154+ silicon_model = self .config_model .chipflow .silicon
152155 config = {
153156 "dependency_versions" : dep_versions ,
154157 "silicon" : {
155- "process" : self . silicon_config [ " process" ] ,
156- "pad_ring" : self . silicon_config [ " package" ] ,
158+ "process" : str ( silicon_model . process ) ,
159+ "pad_ring" : silicon_model . package ,
157160 "pads" : pads ,
158- "power" : self . silicon_config . get ( "power" , {})
161+ "power" : { k : { "type" : v . type , "loc" : v . loc } for k , v in silicon_model . power . items ()}
159162 }
160163 }
161164 if dry_run :
@@ -175,31 +178,30 @@ def submit(self, rtlil_path, *, dry_run=False):
175178 "rtlil" : open (rtlil_path , "rb" ),
176179 "config" : json .dumps (config ),
177180 })
178-
181+
179182 # Parse response body
180183 try :
181184 resp_data = resp .json ()
182185 except ValueError :
183186 resp_data = resp .text
184-
187+
185188 # Handle response based on status code
186189 if resp .status_code == 200 :
187190 logger .info (f"Submitted design: { resp_data } " )
188- print (f"https://{ host } /build/{ resp_data ["build_id" ]} " )
189-
191+ print (f"https://{ host } /build/{ resp_data ['build_id' ]} " )
190192 else :
191193 # Log detailed information about the failed request
192194 logger .error (f"Request failed with status code { resp .status_code } " )
193195 logger .error (f"Request URL: { resp .request .url } " )
194-
196+
195197 # Log headers with auth information redacted
196198 headers = dict (resp .request .headers )
197199 if "Authorization" in headers :
198200 headers ["Authorization" ] = "REDACTED"
199201 logger .error (f"Request headers: { headers } " )
200-
202+
201203 logger .error (f"Request data: { data } " )
202204 logger .error (f"Response headers: { dict (resp .headers )} " )
203205 logger .error (f"Response body: { resp_data } " )
204-
206+
205207 raise ChipFlowError (f"Failed to submit design: { resp_data } " )
0 commit comments