@@ -2,8 +2,8 @@ use crate::config::GenDocs;
22use crate :: dev_aid:: port_diagram;
33use crate :: file_position:: FileText ;
44use crate :: flattening:: {
5- ClockVisibility , FieldDeclKind , InterfaceDeclaration , InterfaceKind , Module , NamedConstant ,
6- StructType ,
5+ ClockVisibility , DeclarationKind , FieldDeclKind , InterfaceDeclaration , InterfaceKind , Module ,
6+ NamedConstant , StructType ,
77} ;
88use crate :: latency:: port_latency_inference:: InferenceTarget ;
99use crate :: linker:: { FileData , GlobalObj , IsExtern , LinkInfo } ;
@@ -115,34 +115,28 @@ fn build_interface_params(li: &LinkInfo, iface: &InterfaceDeclaration, ft: &File
115115
116116fn build_interface_block ( md : & Module , ft : & FileText ) -> String {
117117 let li = & md. link_info ;
118- let mut out = String :: new ( ) ;
119-
120118 let name = li. display_full_name_and_args :: < true > ( ft) ;
121- out. push_str ( & format ! ( "module {name} {{\n " ) ) ;
119+ let mut out = format ! ( "module {name} {{\n " ) ;
122120
123- // Collect (source_pos, line) for clocks and fields, then sort to preserve source order.
124- let mut items: Vec < ( usize , String ) > = Vec :: new ( ) ;
121+ let multiple_domains = md. latency_domains . len ( ) > 1 ;
125122
126- for ( _, clock) in & md. clocks {
127- let Some ( span) = clock. name_span else {
128- continue ;
129- } ;
130- match clock. visibility {
131- ClockVisibility :: Input | ClockVisibility :: Output => {
132- items. push ( ( span. start , format ! ( " clock {}\n " , clock. name) ) ) ;
133- }
134- ClockVisibility :: Local => { }
135- }
136- }
123+ // Group fields by latency domain, preserving source order within each group.
124+ let mut domain_fields: HashMap < LatDomID , Vec < ( usize , String ) > > = HashMap :: new ( ) ;
137125
138126 for ( _, field) in & md. fields {
139127 let Some ( decl_instr) = field. declaration_instruction else {
140128 continue ;
141129 } ;
142- let line = match decl_instr {
130+ let ( lat_dom , line) = match decl_instr {
143131 FieldDeclKind :: SinglePort ( decl_id) => {
144132 let decl = li. instructions [ decl_id] . unwrap_declaration ( ) ;
145- format ! ( " {}\n " , li. display_decl( None , decl, ft) )
133+ let DeclarationKind :: Port { latency_domain, .. } = decl. decl_kind else {
134+ continue ;
135+ } ;
136+ (
137+ latency_domain,
138+ format ! ( " {}\n " , li. display_decl( None , decl, ft) ) ,
139+ )
146140 }
147141 FieldDeclKind :: Interface ( iface_id) => {
148142 let iface = li. instructions [ iface_id] . unwrap_interface ( ) ;
@@ -156,15 +150,40 @@ fn build_interface_block(md: &Module, ft: &FileText) -> String {
156150 } ;
157151 let lat = fmt_latency ( li, & iface. latency_specifier , ft) ;
158152 let params = build_interface_params ( li, iface, ft) ;
159- format ! ( " {kw} {}{lat}{params}\n " , iface. name)
153+ (
154+ iface. latency_domain ,
155+ format ! ( " {kw} {}{lat}{params}\n " , iface. name) ,
156+ )
160157 }
161158 } ;
162- items. push ( ( field. name_span . start , line) ) ;
159+ domain_fields
160+ . entry ( lat_dom)
161+ . or_default ( )
162+ . push ( ( field. name_span . start , line) ) ;
163163 }
164164
165- items. sort_by_key ( |( pos, _) | * pos) ;
166- for ( _, line) in items {
167- out. push_str ( & line) ;
165+ for fields in domain_fields. values_mut ( ) {
166+ fields. sort_by_key ( |( pos, _) | * pos) ;
167+ }
168+
169+ // Emit in domain order: clock header when clock changes, domain header when multiple domains.
170+ let mut prev_clock: Option < ClockID > = None ;
171+ for ( dom_id, dom_info) in & md. latency_domains {
172+ if prev_clock != Some ( dom_info. clock ) {
173+ let clock = & md. clocks [ dom_info. clock ] ;
174+ if clock. name_span . is_some ( ) {
175+ out. push_str ( & format ! ( " clock {}\n " , clock. name) ) ;
176+ }
177+ prev_clock = Some ( dom_info. clock ) ;
178+ }
179+ if multiple_domains {
180+ out. push_str ( & format ! ( " domain {}\n " , dom_info. name) ) ;
181+ }
182+ if let Some ( fields) = domain_fields. get ( & dom_id) {
183+ for ( _, line) in fields {
184+ out. push_str ( line) ;
185+ }
186+ }
168187 }
169188
170189 out. push ( '}' ) ;
0 commit comments