@@ -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 == "s" :
873+ assert len (chunk .value ) % 8 == 0
874+ for bit in reversed (range (0 , len (chunk .value ), 8 )):
875+ args += chunk .value [bit :bit + 8 ]
876+ else :
877+ args += chunk .value
878+ if type is None :
879+ type = "d"
880+ if type == "x" or type == "X" :
881+ # TODO(yosys): "H" type
882+ type = "h"
883+ if type == "s" :
884+ # TODO(yosys): support for single unicode character?
885+ type = "c"
886+ width = spec ["width" ]
887+ align = spec ["align" ]
888+ if align is None :
889+ align = ">" if type != "c" else "<"
890+ if align == "=" :
891+ # TODO(yosys): "=" alignment
892+ align = ">"
893+ fill = spec ["fill" ]
894+ if fill not in (" " , "0" ):
895+ # TODO(yosys): arbitrary fill
896+ fill = " "
897+ # TODO(yosys): support for options, grouping
898+ sign = spec ["sign" ]
899+ if sign != "+" :
900+ # TODO(yosys): support " " sign
901+ sign = ""
902+ if type == "c" :
903+ signed = ""
904+ elif chunk .signed :
905+ signed = "s"
906+ else :
907+ signed = "u"
908+ format .append (f"{{{ len (chunk .value )} :{ align } { fill } { width or '' } { type } { sign } { signed } }}" )
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