@@ -118,25 +118,105 @@ fn create_sub_tile_io_fc(ty: &str,
118118 parser : & EventReader < BufReader < File > > ) -> Result < SubTileIOFC , FPGAArchParseError > {
119119 match ty {
120120 "frac" => {
121- Ok ( SubTileIOFC :: Frac ( SubTileFracFC {
122- val : match val. parse ( ) {
121+ Ok ( SubTileIOFC :: Frac (
122+ match val. parse ( ) {
123123 Ok ( v) => v,
124124 Err ( e) => return Err ( FPGAArchParseError :: AttributeParseError ( format ! ( "{val}: {e}" ) , parser. position ( ) ) ) ,
125125 } ,
126- } ) )
126+ ) )
127127 } ,
128128 "abs" => {
129- Ok ( SubTileIOFC :: Abs ( SubTileAbsFC {
130- val : match val. parse ( ) {
129+ Ok ( SubTileIOFC :: Abs (
130+ match val. parse ( ) {
131131 Ok ( v) => v,
132132 Err ( e) => return Err ( FPGAArchParseError :: AttributeParseError ( format ! ( "{val}: {e}" ) , parser. position ( ) ) ) ,
133133 } ,
134- } ) )
134+ ) )
135135 } ,
136136 _ => Err ( FPGAArchParseError :: AttributeParseError ( format ! ( "Unknown fc_type: {}" , ty) , parser. position ( ) ) ) ,
137137 }
138138}
139139
140+ fn parse_sub_tile_fc_override ( name : & OwnedName ,
141+ attributes : & [ OwnedAttribute ] ,
142+ parser : & mut EventReader < BufReader < File > > ) -> Result < SubTileFCOverride , FPGAArchParseError > {
143+ assert ! ( name. to_string( ) == "fc_override" ) ;
144+
145+ let mut fc_type: Option < String > = None ;
146+ let mut fc_val: Option < String > = None ;
147+ let mut port_name: Option < String > = None ;
148+ let mut segment_name: Option < String > = None ;
149+
150+ for a in attributes {
151+ match a. name . to_string ( ) . as_str ( ) {
152+ "fc_type" => {
153+ fc_type = match fc_type {
154+ None => Some ( a. value . clone ( ) ) ,
155+ Some ( _) => return Err ( FPGAArchParseError :: DuplicateAttribute ( a. to_string ( ) , parser. position ( ) ) ) ,
156+ }
157+ } ,
158+ "fc_val" => {
159+ fc_val = match fc_val {
160+ None => Some ( a. value . clone ( ) ) ,
161+ Some ( _) => return Err ( FPGAArchParseError :: DuplicateAttribute ( a. to_string ( ) , parser. position ( ) ) ) ,
162+ }
163+ } ,
164+ "port_name" => {
165+ port_name = match port_name {
166+ None => Some ( a. value . clone ( ) ) ,
167+ Some ( _) => return Err ( FPGAArchParseError :: DuplicateAttribute ( a. to_string ( ) , parser. position ( ) ) ) ,
168+ }
169+ } ,
170+ "segment_name" => {
171+ segment_name = match segment_name {
172+ None => Some ( a. value . clone ( ) ) ,
173+ Some ( _) => return Err ( FPGAArchParseError :: DuplicateAttribute ( a. to_string ( ) , parser. position ( ) ) ) ,
174+ }
175+ } ,
176+ _ => return Err ( FPGAArchParseError :: UnknownAttribute ( a. to_string ( ) , parser. position ( ) ) ) ,
177+ } ;
178+ }
179+ let fc_type = match fc_type {
180+ Some ( n) => n,
181+ None => return Err ( FPGAArchParseError :: MissingRequiredAttribute ( "fc_type" . to_string ( ) , parser. position ( ) ) ) ,
182+ } ;
183+ let fc_val = match fc_val {
184+ Some ( n) => n,
185+ None => return Err ( FPGAArchParseError :: MissingRequiredAttribute ( "fc_val" . to_string ( ) , parser. position ( ) ) ) ,
186+ } ;
187+ let fc = create_sub_tile_io_fc ( & fc_type, & fc_val, parser) ?;
188+ if port_name. is_none ( ) && segment_name. is_none ( ) {
189+ return Err ( FPGAArchParseError :: MissingRequiredAttribute ( "At least one of port_name or segment_name must be specified." . to_string ( ) , parser. position ( ) ) ) ;
190+ }
191+
192+ loop {
193+ match parser. next ( ) {
194+ Ok ( XmlEvent :: StartElement { name, .. } ) => {
195+ return Err ( FPGAArchParseError :: InvalidTag ( name. to_string ( ) , parser. position ( ) ) ) ;
196+ } ,
197+ Ok ( XmlEvent :: EndElement { name } ) => {
198+ match name. to_string ( ) . as_str ( ) {
199+ "fc_override" => break ,
200+ _ => return Err ( FPGAArchParseError :: UnexpectedEndTag ( name. to_string ( ) , parser. position ( ) ) ) ,
201+ }
202+ } ,
203+ Ok ( XmlEvent :: EndDocument ) => {
204+ return Err ( FPGAArchParseError :: UnexpectedEndOfDocument ( name. to_string ( ) ) ) ;
205+ } ,
206+ Err ( e) => {
207+ return Err ( FPGAArchParseError :: XMLParseError ( format ! ( "{e:?}" ) , parser. position ( ) ) ) ;
208+ } ,
209+ _ => { } ,
210+ } ;
211+ }
212+
213+ Ok ( SubTileFCOverride {
214+ fc,
215+ port_name,
216+ segment_name,
217+ } )
218+ }
219+
140220fn parse_sub_tile_fc ( name : & OwnedName ,
141221 attributes : & [ OwnedAttribute ] ,
142222 parser : & mut EventReader < BufReader < File > > ) -> Result < SubTileFC , FPGAArchParseError > {
@@ -196,14 +276,13 @@ fn parse_sub_tile_fc(name: &OwnedName,
196276 let in_fc = create_sub_tile_io_fc ( & in_type, & in_val, parser) ?;
197277 let out_fc = create_sub_tile_io_fc ( & out_type, & out_val, parser) ?;
198278
279+ let mut fc_overrides: Vec < SubTileFCOverride > = Vec :: new ( ) ;
199280 loop {
200281 match parser. next ( ) {
201- Ok ( XmlEvent :: StartElement { name, .. } ) => {
282+ Ok ( XmlEvent :: StartElement { name, attributes , .. } ) => {
202283 match name. to_string ( ) . as_str ( ) {
203284 "fc_override" => {
204- // TODO: Implement.
205- // FIXME: Check that this is documented in VTR.
206- let _ = parser. skip ( ) ;
285+ fc_overrides. push ( parse_sub_tile_fc_override ( & name, & attributes, parser) ?) ;
207286 } ,
208287 _ => return Err ( FPGAArchParseError :: InvalidTag ( name. to_string ( ) , parser. position ( ) ) ) ,
209288 } ;
@@ -227,6 +306,7 @@ fn parse_sub_tile_fc(name: &OwnedName,
227306 Ok ( SubTileFC {
228307 in_fc,
229308 out_fc,
309+ fc_overrides,
230310 } )
231311}
232312
0 commit comments