2929from mako .lookup import TemplateLookup
3030from mako .template import Template
3131from raclgen .lib import DEFAULT_RACL_CONFIG
32- from reggen import access , gen_rtl , gen_sec_cm_testplan , window
32+ from reggen import access , gen_rtl , gen_sec_cm_testplan , params , reg_block , window
3333from reggen .countermeasure import CounterMeasure
3434from reggen .ip_block import IpBlock
3535from topgen import get_hjsonobj_xbars
@@ -871,33 +871,90 @@ def generate_top_ral(topname: str, top: ConfigT, name_to_block: IpBlocksT,
871871 original_types = set ()
872872 for module in top ["module" ]:
873873 if "memory" in module .keys () and len (module ["memory" ]) > 0 :
874- newtype = "{}_{}" .format (module ["type" ], module ["name" ])
874+ mod_name = module ["name" ]
875+ newtype = "{}_{}" .format (module ["type" ], mod_name )
875876 assert newtype not in name_to_block
876877
878+ # Take a copy of the block-level description of the thing that is
879+ # being instantiated as mod_name (so that we can configure it).
877880 block = deepcopy (name_to_block [module ["type" ]])
881+
882+ # Update name_to_block and inst_to_block so that they point at the
883+ # new, more specific, information about the block.
878884 name_to_block [newtype ] = block
879- inst_to_block [module [ "name" ] ] = newtype
885+ inst_to_block [mod_name ] = newtype
880886
881887 original_types .add (module ["type" ])
882888
889+ # The instantiation might have requested a specific configuration
890+ # for some of the memories of the block. Apply that here.
883891 for mem_name , item in module ["memory" ].items ():
884- assert block .reg_blocks [mem_name ]
885- assert len (block .reg_blocks [mem_name ].windows ) <= 1
886- item ["name" ] = mem_name
887-
888- win = create_mem (item , addrsep , regwidth )
889- if len (block .reg_blocks [mem_name ].windows ) > 0 :
890- blk_win = block .reg_blocks [mem_name ].windows [0 ]
891-
892- # Top can only add new info for mem, shouldn't overwrite
893- # existing configuration
894- assert win .items == blk_win .items
895- assert win .byte_write == blk_win .byte_write
896- assert win .data_intg_passthru == blk_win .data_intg_passthru
897-
898- block .reg_blocks [mem_name ].windows [0 ] = win
892+ block_mem = block .memories .get (mem_name )
893+ if block_mem is None :
894+ raise ValueError (f"The definition of { block .name } "
895+ f"(instantiated as { mod_name } ) doesn't "
896+ f"declare a memory called { mem_name } ." )
897+
898+ # We only support memories with at most a single window (if
899+ # there are several, we don't know which one to customise)
900+ if len (block_mem .windows ) > 1 :
901+ raise ValueError (f"The block { block .name } declares "
902+ f"multiple windows for its { mem_name } "
903+ f"memory, so topgen can't configure that "
904+ "memory." )
905+
906+ # This is the new window to use
907+ win = create_mem (mem_name , item , addrsep , regwidth )
908+
909+ # If the block doesn't define a window for this memory, we can
910+ # just make one. If it *does* define a window we can overwrite
911+ # it, but want to make sure we won't mess things up.
912+ if not block_mem .windows :
913+ block_mem .windows = [win ]
899914 else :
900- block .reg_blocks [mem_name ].windows .append (win )
915+ blk_win = block_mem .windows [0 ]
916+
917+ # Check we end up with the same number of "items" in the
918+ # window (the window size divided by addrsep)
919+ if win .items != blk_win .items :
920+ raise ValueError (f"The { mod_name } instance of "
921+ f"{ block .name } doesn't match number "
922+ f"of items for { mem_name } . Instance: "
923+ f"{ win .items } ; blk: { blk_win .items } " )
924+
925+ # Check the byte_write setting matches
926+ if win .byte_write != blk_win .byte_write :
927+ raise ValueError (f"The { mod_name } instance of "
928+ f"{ block .name } requests the memory "
929+ f"{ mem_name } with byte_write="
930+ f"{ win .byte_write } , but the block "
931+ f"declares it { blk_win .byte_write } ." )
932+
933+ # Check the data_intg_passthru setting matches
934+ if win .data_intg_passthru != blk_win .data_intg_passthru :
935+ raise ValueError (f"The { mod_name } instance of "
936+ f"{ block .name } requests the memory "
937+ f"{ mem_name } with data_intg_passthru="
938+ f"{ win .data_intg_passthru } , but the "
939+ f"block declares it as "
940+ f"{ blk_win .data_intg_passthru } ." )
941+
942+ # If we get here, the two definitions matched. Use the new
943+ # one.
944+ block_mem .windows [0 ] = win
945+
946+ # At the moment the RAL template does not know about memories
947+ # but it knows about windows in memory blocks. Therefoe we
948+ # create an empty register block for RAL.
949+ if_name = mem_name
950+ block .reg_blocks [if_name ] = reg_block .RegBlock (regwidth , params .ReggenParams (),
951+ windows = block_mem .windows )
952+
953+ if_addr = {
954+ asid : int (addr , 0 )
955+ for (asid , addr ) in module ["base_addrs" ][if_name ].items ()
956+ }
957+ if_addrs [(mod_name , if_name )] = if_addr
901958
902959 for t in original_types :
903960 if t not in inst_to_block .values ():
@@ -911,16 +968,19 @@ def generate_top_ral(topname: str, top: ConfigT, name_to_block: IpBlocksT,
911968 return gen_dv (chip , dv_base_names , str (out_path ))
912969
913970
914- def create_mem (item , addrsep , regwidth ) -> window .Window :
915- byte_write = ("byte_write" in item and
916- item ["byte_write" ].lower () == "true" )
917- data_intg_passthru = ("data_intg_passthru" in item and
918- item ["data_intg_passthru" ].lower () == "true" )
919- size_in_bytes = int (item ["size" ], 0 )
971+ def create_mem (name : str , item : dict [str , object ], addrsep : int , regwidth : int ) -> window .Window :
972+ byte_write = item .get ("byte_write" , "false" ).lower () == "true"
973+ data_intg_passthru = item .get ("data_intg_passthru" , "false" ).lower () == "true"
974+
975+ item_size = item .get ("size" )
976+ if item_size is None :
977+ raise ValueError ("Item describing memory window with no size" )
978+
979+ size_in_bytes = int (item_size , 0 )
920980 num_regs = size_in_bytes // addrsep
921981 swaccess = access .SWAccess ("top-level memory" , item .get ("swaccess" , "rw" ))
922982
923- return window .Window (name = item [ " name" ] ,
983+ return window .Window (name = name ,
924984 desc = "(generated from top-level)" ,
925985 unusual = False ,
926986 byte_write = byte_write ,
0 commit comments