@@ -441,8 +441,8 @@ def emit_cell_wires(self):
441441 continue # Instances use one wire per output, not per cell.
442442 elif isinstance (cell , (_nir .PriorityMatch , _nir .Matches )):
443443 continue # Inlined into assignment lists.
444- elif isinstance (cell , (_nir .SyncProperty , _nir .AsyncProperty , _nir .Memory ,
445- _nir .SyncWritePort )):
444+ elif isinstance (cell , (_nir .SyncPrint , _nir .AsyncPrint , _nir .SyncProperty ,
445+ _nir .AsyncProperty , _nir . Memory , _nir . SyncWritePort )):
446446 continue # No outputs.
447447 elif isinstance (cell , _nir .AssignmentList ):
448448 width = len (cell .default )
@@ -859,37 +859,78 @@ def emit_read_port(self, cell_idx, cell):
859859 })
860860 self .builder .cell (f"$memrd_v2" , ports = ports , params = params , src = _src (cell .src_loc ))
861861
862- def emit_property (self , cell_idx , cell ):
863- if isinstance (cell , _nir .AsyncProperty ):
864- ports = {
865- "A" : self .sigspec (cell .test ),
866- "EN" : self .sigspec (cell .en ),
867- }
868- if isinstance (cell , _nir .SyncProperty ):
869- test = self .builder .wire (1 , attrs = {"init" : _ast .Const (0 , 1 )})
870- en = self .builder .wire (1 , attrs = {"init" : _ast .Const (0 , 1 )})
871- for (d , q ) in [
872- (cell .test , test ),
873- (cell .en , en ),
874- ]:
875- ports = {
876- "D" : self .sigspec (d ),
877- "Q" : q ,
878- "CLK" : self .sigspec (cell .clk ),
879- }
880- params = {
881- "WIDTH" : 1 ,
882- "CLK_POLARITY" : {
883- "pos" : True ,
884- "neg" : False ,
885- }[cell .clk_edge ],
886- }
887- self .builder .cell (f"$dff" , ports = ports , params = params , src = _src (cell .src_loc ))
888- ports = {
889- "A" : test ,
890- "EN" : en ,
891- }
892- self .builder .cell (f"${ cell .kind } " , name = cell .name , ports = ports , src = _src (cell .src_loc ))
862+ def emit_print (self , cell_idx , cell ):
863+ args = []
864+ format = []
865+ if cell .format is not None :
866+ for chunk in cell .format .chunks :
867+ if isinstance (chunk , str ):
868+ format .append (chunk )
869+ else :
870+ spec = _ast .Format ._parse_format_spec (chunk .format_desc , _ast .Shape (len (chunk .value ), chunk .signed ))
871+ type = spec ["type" ]
872+ if type is None :
873+ type = "d"
874+ if type == "x" or type == "X" :
875+ # TODO(yosys): "H" type
876+ type = "h"
877+ if type == "s" :
878+ # TODO(yosys): support for single unicode character?
879+ type = "c"
880+ width = spec ["width" ]
881+ align = spec ["align" ]
882+ if align is None :
883+ align = ">" if type != "c" else "<"
884+ if align == "=" :
885+ # TODO(yosys): "=" alignment
886+ align = ">"
887+ fill = spec ["fill" ]
888+ if fill not in (" " , "0" ):
889+ # TODO(yosys): arbitrary fill
890+ fill = " "
891+ # TODO(yosys): support for options, grouping
892+ sign = spec ["sign" ]
893+ if sign != "+" :
894+ # TODO(yosys): support " " sign
895+ sign = ""
896+ if type == "c" :
897+ signed = ""
898+ elif chunk .signed :
899+ signed = "s"
900+ else :
901+ signed = "u"
902+ format .append (f"{{{ len (chunk .value )} :{ align } { fill } { width or '' } { type } { sign } { signed } }}" )
903+ if type == "s" :
904+ assert len (chunk .value ) % 8 == 0
905+ for bit in reversed (range (0 , len (chunk .value ), 8 )):
906+ args += chunk .value [bit :bit + 8 ]
907+ else :
908+ args += chunk .value
909+ ports = {
910+ "EN" : self .sigspec (cell .en ),
911+ "ARGS" : self .sigspec (_nir .Value (args )),
912+ }
913+ params = {
914+ "FORMAT" : "" .join (format ),
915+ "ARGS_WIDTH" : len (args ),
916+ "PRIORITY" : - cell_idx ,
917+ }
918+ if isinstance (cell , (_nir .AsyncPrint , _nir .AsyncProperty )):
919+ ports ["TRG" ] = self .sigspec (_nir .Value ())
920+ params ["TRG_ENABLE" ] = False
921+ params ["TRG_WIDTH" ] = 0
922+ params ["TRG_POLARITY" ] = 0
923+ if isinstance (cell , (_nir .SyncPrint , _nir .SyncProperty )):
924+ ports ["TRG" ] = self .sigspec (cell .clk )
925+ params ["TRG_ENABLE" ] = True
926+ params ["TRG_WIDTH" ] = 1
927+ params ["TRG_POLARITY" ] = cell .clk_edge == "pos"
928+ if isinstance (cell , (_nir .AsyncPrint , _nir .SyncPrint )):
929+ self .builder .cell (f"$print" , params = params , ports = ports , src = _src (cell .src_loc ))
930+ if isinstance (cell , (_nir .AsyncProperty , _nir .SyncProperty )):
931+ params ["FLAVOR" ] = cell .kind
932+ ports ["A" ] = self .sigspec (cell .test )
933+ self .builder .cell (f"$check" , params = params , ports = ports , src = _src (cell .src_loc ))
893934
894935 def emit_any_value (self , cell_idx , cell ):
895936 self .builder .cell (f"${ cell .kind } " , ports = {
@@ -939,8 +980,8 @@ def emit_cells(self):
939980 self .emit_write_port (cell_idx , cell )
940981 elif isinstance (cell , (_nir .AsyncReadPort , _nir .SyncReadPort )):
941982 self .emit_read_port (cell_idx , cell )
942- elif isinstance (cell , (_nir .AsyncProperty , _nir .SyncProperty )):
943- self .emit_property (cell_idx , cell )
983+ elif isinstance (cell , (_nir .AsyncPrint , _nir . SyncPrint , _nir . AsyncProperty , _nir .SyncProperty )):
984+ self .emit_print (cell_idx , cell )
944985 elif isinstance (cell , _nir .AnyValue ):
945986 self .emit_any_value (cell_idx , cell )
946987 elif isinstance (cell , _nir .Initial ):
0 commit comments