@@ -441,8 +441,8 @@ def emit_cell_wires(self):
441
441
continue # Instances use one wire per output, not per cell.
442
442
elif isinstance (cell , (_nir .PriorityMatch , _nir .Matches )):
443
443
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 )):
446
446
continue # No outputs.
447
447
elif isinstance (cell , _nir .AssignmentList ):
448
448
width = len (cell .default )
@@ -859,37 +859,78 @@ def emit_read_port(self, cell_idx, cell):
859
859
})
860
860
self .builder .cell (f"$memrd_v2" , ports = ports , params = params , src = _src (cell .src_loc ))
861
861
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 ))
893
934
894
935
def emit_any_value (self , cell_idx , cell ):
895
936
self .builder .cell (f"${ cell .kind } " , ports = {
@@ -939,8 +980,8 @@ def emit_cells(self):
939
980
self .emit_write_port (cell_idx , cell )
940
981
elif isinstance (cell , (_nir .AsyncReadPort , _nir .SyncReadPort )):
941
982
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 )
944
985
elif isinstance (cell , _nir .AnyValue ):
945
986
self .emit_any_value (cell_idx , cell )
946
987
elif isinstance (cell , _nir .Initial ):
0 commit comments