From a43cd2ea6c5bf665d2d4bc70d3bbdc81de190c23 Mon Sep 17 00:00:00 2001 From: Dennis Date: Sun, 31 Oct 2021 15:58:31 -0700 Subject: [PATCH] Closes #7: Add flag that disables unpacked arrays --- srdl2sv/cli/cli.py | 10 +++++ srdl2sv/components/addrmap.py | 77 +++++++++++++++++++++++------------ srdl2sv/components/field.py | 23 +++++++++++ 3 files changed, 85 insertions(+), 25 deletions(-) diff --git a/srdl2sv/cli/cli.py b/srdl2sv/cli/cli.py index e2f1847..46ad9ec 100644 --- a/srdl2sv/cli/cli.py +++ b/srdl2sv/cli/cli.py @@ -64,6 +64,12 @@ class CliArguments(): compiler from generating packages and it will prevent\ it from using enums in the port list.") + self.parser.add_argument( + "-u", + "--no-unpacked", + action="store_true", + help="Disable unpacked arrays in the module's I/O interface.") + self.parser.add_argument( "--file-logging", choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL', 'NONE'], @@ -171,6 +177,10 @@ class CliArguments(): config['enums'] = not args.no_enums config['list_args'].append(f"Enums Enabled : {config['enums']}") + # Set unpacked arrays + config['unpacked_arrays'] = not args.no_unpacked + config['list_args'].append(f"Unpacked I/Os : {config['enums']}") + # Set bus config['bus'] = args.bus config['list_args'].append(f"Register Bus Type: {config['bus']}") diff --git a/srdl2sv/components/addrmap.py b/srdl2sv/components/addrmap.py index ae26a2d..a8c80df 100644 --- a/srdl2sv/components/addrmap.py +++ b/srdl2sv/components/addrmap.py @@ -171,33 +171,60 @@ class AddrMap(Component): # Input ports - # Yay for unreadable code.... - input_ports_rtl = [ - AddrMap.templ_dict['input_port']['rtl'].format( - name = key, - signal_type = value[0], - signal_width = input_signal_width, - name_width = input_name_width, - unpacked_dim = '[{}]'.format( - ']['.join( - [str(y) for y in value[1]])) - if value[1] else '') - for (key, value) in input_dict_list - ] + input_ports_rtl = [] + for (key, value) in input_dict_list: + # TODO: Think about a better way to handle datatypes. Simply replacing them + # is not the most efficient way of handling it. + signal_type = value[0].replace('logic', '').strip() + + if config['unpacked_arrays'] and value[1]: + unpacked_dim = f"[{']['.join([str(y) for y in value[1]])}]" + elif value[1]: + unpacked_dim = '' + signal_type = ''.join([ + f"[{':0]['.join([str(y-1) for y in value[1]])}:0]", + signal_type + ]) + else: + unpacked_dim = '' + + input_ports_rtl.append( + AddrMap.templ_dict['input_port']['rtl'].format( + name = key, + signal_type = signal_type, + signal_width = input_signal_width, + name_width = input_name_width, + unpacked_dim = unpacked_dim, + ) + ) # Output ports - output_ports_rtl = [ - AddrMap.templ_dict['output_port']['rtl'].format( - name = key, - signal_width = output_signal_width, - name_width = output_name_width, - signal_type = value[0], - unpacked_dim = '[{}]'.format( - ']['.join( - [str(y) for y in value[1]])) - if value[1] else '') - for (key, value) in output_dict_list - ] + output_ports_rtl = [] + for (key, value) in output_dict_list: + # TODO: Think about a better way to handle datatypes. Simply replacing them + # is not the most efficient way of handling it. + signal_type = value[0].replace('logic', '').strip() + + if config['unpacked_arrays'] and value[1]: + unpacked_dim = f"[{']['.join([str(y) for y in value[1]])}]" + elif value[1]: + unpacked_dim = '' + signal_type = ''.join([ + f"[{':0]['.join([str(y-1) for y in value[1]])}:0]", + signal_type + ]) + else: + unpacked_dim = '' + + output_ports_rtl.append( + AddrMap.templ_dict['output_port']['rtl'].format( + name = key, + signal_type = signal_type, + signal_width = output_signal_width, + name_width = output_name_width, + unpacked_dim = unpacked_dim, + ) + ) # Remove comma from last port entry output_ports_rtl[-1] = output_ports_rtl[-1].rstrip(',') diff --git a/srdl2sv/components/field.py b/srdl2sv/components/field.py index c8e3c77..30e68de 100644 --- a/srdl2sv/components/field.py +++ b/srdl2sv/components/field.py @@ -1254,6 +1254,29 @@ class Field(Component): ) # Save name of object + # + # If the field is multidimensional and packed arrays are turned off throw a + # warning. Structures like: + # + # input [N:0] enum_name input_name, + # + # are not supported and this tool does not support custom datatypes where + # packed dimensions are packed into another datatypes with the enum. + # + # For that reason, in such cases, a simple flat wire will be generated + if self.total_dimensions > 0 and not self.config['unpacked_arrays']: + self.logger.warning( + "Using multidimensional registers/regfiles with " + "enums and also using the option --no-unpacked " + "is only partly supported. Rather than using the enum " + "'%s', the flat wire with dimensions '[%i:0] will be used. " + "Note that the SystemVerilog package that holds the enum can " + "still be used.", + '::'.join(['_'.join([scope, 'pkg']), enum_name]), + self.obj.width-1) + + raise AttributeError + self.field_type =\ '::'.join(['_'.join([scope, 'pkg']), enum_name])