diff --git a/srdl2sv/components/field.py b/srdl2sv/components/field.py index 0c0ea53..254bc82 100644 --- a/srdl2sv/components/field.py +++ b/srdl2sv/components/field.py @@ -87,7 +87,7 @@ class Field(Component): access_rtl = {} if alias: - owning_addrmap, full_path, path, path_underscored =\ + _, _, path, path_underscored =\ Field.create_underscored_path_static(obj) else: owning_addrmap, full_path, path, path_underscored =\ @@ -264,42 +264,46 @@ class Field(Component): # Determine saturation values if isinstance(self.obj.get_property('incrsaturate'), bool): if self.obj.get_property('incrsaturate'): - incr_sat_value = 2**self.obj.width-1 + incr_sat_value = f"{self.obj.width}'d{2**self.obj.width-1}" overflow_value = incr_sat_value else: incr_sat_value = False overflow_value = 2**self.obj.width-1 else: - incr_sat_value = self.obj.get_property('incrsaturate') + incr_sat_value = self.get_signal_name( + self.obj.get_property('incrsaturate')) overflow_value = incr_sat_value if isinstance(self.obj.get_property('decrsaturate'), bool): if self.obj.get_property('decrsaturate'): - decr_sat_value = 0 + decr_sat_value = f"{self.obj.width}'d0" underflow_value = decr_sat_value else: decr_sat_value = False underflow_value = 0 else: - decr_sat_value = self.obj.get_property('decrsaturate') + decr_sat_value = self.get_signal_name( + self.obj.get_property('decrsaturate')) underflow_value = decr_sat_value # Determine threshold values if isinstance(self.obj.get_property('incrthreshold'), bool): if self.obj.get_property('incrthreshold'): - incr_thr_value = 2**self.obj.width-1 + incr_thr_value = f"{self.obj.width}'d{2**self.obj.width-1}" else: incr_thr_value = False else: - incr_thr_value = self.obj.get_property('incrthreshold') + incr_thr_value = self.get_signal_name( + self.obj.get_property('incrthreshold')) if isinstance(self.obj.get_property('decrthreshold'), bool): if self.obj.get_property('decrthreshold'): - decr_thr_value = 2**self.obj.width-1 + decr_thr_value = f"{self.obj.width}'d{2**self.obj.width-1}" else: decr_thr_value = False else: - decr_thr_value = self.obj.get_property('decrthreshold') + decr_thr_value = self.get_signal_name( + self.obj.get_property('decrthreshold')) # Determine with what value the counter is incremented # According to the spec, the incrvalue/decrvalue default to '1' @@ -428,6 +432,20 @@ class Field(Component): "defined. This is not legal and the decrwidth property " "will be ignored!") + # Calculate the number of bits that need to be padded with 0s + if remaining_width := self.obj.width - incr_width: + incr_zero_pad = f"{remaining_width}'b0, " + incr_sat_zero_pad = f"{remaining_width+1}'b0, " + else: + incr_zero_pad = "" + incr_sat_zero_pad = "1'b0" + + if remaining_width := self.obj.width - decr_width: + decr_zero_pad = f"{remaining_width}'b0, " + decr_sat_zero_pad = f"{remaining_width+1}'b0, " + else: + decr_zero_pad = '' + decr_sat_zero_pad = "1'b0" # If no input is defined for the decrement value, define # an internal signal. It is possible that this is tied to 0. @@ -551,9 +569,10 @@ class Field(Component): Field.templ_dict['counter_incr_sat'], {'path': self.path_underscored, 'genvars': self.genvars_str, - 'incr_width': incr_width, - 'decr_width': decr_width, 'sat_value': incr_sat_value, + 'width_plus_1': self.obj.width + 1, + 'incr_sat_zero_pad': incr_sat_zero_pad, + 'decr_sat_zero_pad': decr_sat_zero_pad, } ) ) @@ -573,9 +592,10 @@ class Field(Component): Field.templ_dict['counter_decr_sat'], {'path': self.path_underscored, 'genvars': self.genvars_str, - 'incr_width': incr_width, - 'decr_width': decr_width, 'sat_value': decr_sat_value, + 'width_plus_1': self.obj.width + 1, + 'incr_sat_zero_pad': incr_sat_zero_pad, + 'decr_sat_zero_pad': decr_sat_zero_pad, } ) ) @@ -590,9 +610,10 @@ class Field(Component): Field.templ_dict['counter_incr_thr'], {'path': self.path_underscored, 'genvars': self.genvars_str, - 'incr_width': incr_width, - 'decr_width': decr_width, 'thr_value': incr_thr_value, + 'width_plus_1': self.obj.width + 1, + 'incr_sat_zero_pad': incr_sat_zero_pad, + 'decr_sat_zero_pad': incr_sat_zero_pad, } ) ) @@ -603,9 +624,10 @@ class Field(Component): Field.templ_dict['counter_decr_thr'], {'path': self.path_underscored, 'genvars': self.genvars_str, - 'incr_width': incr_width, - 'decr_width': decr_width, 'thr_value': decr_thr_value, + 'width_plus_1': self.obj.width + 1, + 'incr_sat_zero_pad': incr_sat_zero_pad, + 'decr_sat_zero_pad': decr_sat_zero_pad, } ) ) @@ -617,9 +639,10 @@ class Field(Component): Field.templ_dict['counter_overflow'], {'path': self.path_underscored, 'genvars': self.genvars_str, - 'incr_width': incr_width, - 'decr_width': decr_width, 'overflow_value': overflow_value, + 'width_plus_1': self.obj.width + 1, + 'incr_sat_zero_pad': incr_sat_zero_pad, + 'decr_sat_zero_pad': decr_sat_zero_pad, } ) ) @@ -630,9 +653,10 @@ class Field(Component): Field.templ_dict['counter_underflow'], {'path': self.path_underscored, 'genvars': self.genvars_str, - 'incr_width': incr_width, - 'decr_width': decr_width, 'underflow_value': underflow_value, + 'width_plus_1': self.obj.width + 1, + 'incr_sat_zero_pad': incr_sat_zero_pad, + 'decr_sat_zero_pad': decr_sat_zero_pad, } ) ) @@ -643,6 +667,8 @@ class Field(Component): Field.templ_dict['counter'], {'path': self.path_underscored, 'genvars': self.genvars_str, + 'incr_zero_pad': incr_zero_pad, + 'decr_zero_pad': decr_zero_pad, } ) ) @@ -1467,6 +1493,12 @@ class Field(Component): "field. Note that explicit connecting this "\ "is not required if a field_reset was defined.") + if self.obj.get_property('counter') \ + and self.obj.get_property("reset") is None: + self.logger.warning("Field is a counter but has no reset. "\ + "This should probably be fixed since this "\ + "will result in undefined behavior in simulations.") + @staticmethod def __process_reset_signal(reset_signal): diff --git a/srdl2sv/components/templates/fields.yaml b/srdl2sv/components/templates/fields.yaml index 51283d3..a7ff55e 100644 --- a/srdl2sv/components/templates/fields.yaml +++ b/srdl2sv/components/templates/fields.yaml @@ -281,28 +281,28 @@ counter: // might be tied to 0. always_comb begin - {path}_next{genvars} = {path}_q{genvars}; + {path}_next{genvars} = {path}_q{genvars}; if ({path}_incr{genvars} && {path}_decr{genvars}) begin if (!{path}_incr_sat{genvars} && !{path}_decr_sat{genvars}) begin - {path}_next{genvars} += {path}_incr_val{genvars}; - {path}_next{genvars} -= {path}_decr_val{genvars}; + {path}_next{genvars} += {{{incr_zero_pad}{path}_incr_val{genvars}}}; + {path}_next{genvars} -= {{{decr_zero_pad}{path}_decr_val{genvars}}}; end end else if ({path}_incr{genvars}) begin if (!{path}_incr_sat{genvars}) <> - {path}_next{genvars} += {path}_incr_val{genvars}; + {path}_next{genvars} += {{{incr_zero_pad}{path}_incr_val{genvars}}}; <> end else if ({path}_decr{genvars}) begin if (!{path}_decr_sat{genvars}) <> - {path}_next{genvars} += {path}_decr_val{genvars}; + {path}_next{genvars} -= {{{decr_zero_pad}{path}_decr_val{genvars}}}; <> end end @@ -359,7 +359,7 @@ counter_incr_sat: // Determine whether the counter is saturated // The signal is tied if the counter is not saturating // in the respective direction - assign {path}_incr_sat{genvars} = {path}_q{genvars} + ({{{incr_width}{{{path}_incr}}}} & {path}_incr_val) - ({{{decr_width}{{{path}_decr}}}} & {path}_decr_val) > {sat_value}; + assign {path}_incr_sat{genvars} = {{1'b0, {path}_q{genvars}}} + ({{{width_plus_1}{{{path}_incr}}}} & {{{incr_sat_zero_pad}{path}_incr_val}}) - ({{{width_plus_1}{{{path}_decr}}}} & {{{decr_sat_zero_pad}{path}_decr_val}}) > {{1'b0, {sat_value}}}; signals: - name: '{path}_incr_sat' signal_type: 'logic' @@ -375,7 +375,7 @@ counter_incr_sat_tied: signal_type: 'logic' counter_decr_sat: rtl: |- - assign {path}_decr_sat{genvars} = {path}_q{genvars} + ({{{incr_width}{{{path}_incr}}}} & {path}_incr_val) - ({{{decr_width}{{{path}_decr}}}} & {path}_decr_val) > {sat_value}; + assign {path}_decr_sat{genvars} = {{1'b0, {path}_q{genvars}}} + ({{{width_plus_1}{{{path}_incr}}}} & {{{incr_sat_zero_pad}{path}_incr_val}}) < {{1'b0, {sat_value}}} + ({{{width_plus_1}{{{path}_decr}}}} & {{{decr_sat_zero_pad}{path}_decr_val}}); signals: - name: '{path}_decr_sat' signal_type: 'logic' @@ -391,13 +391,13 @@ counter_thr_comment: // Define threshold signals (similar to overflow, but for a user specified value) counter_incr_thr: rtl: |- - assign {path}_incr_thr{genvars} = {path}_q{genvars} + ({{{incr_width}{{{path}_incr}}}} & {path}_incr_val) - ({{{decr_width}{{{path}_decr}}}} & {path}_decr_val) > {thr_value}; + assign {path}_incr_thr{genvars} = {{1'b0, {path}_q{genvars}}} + ({{{width_plus_1}{{{path}_incr}}}} & {{{incr_sat_zero_pad}{path}_incr_val}}) - ({{{width_plus_1}{{{path}_decr}}}} & {{{decr_sat_zero_pad}{path}_decr_val}}) >= {{1'b0, {thr_value}}}; output_ports: - name: '{path}_incr_thr' signal_type: 'logic' counter_decr_thr: rtl: |- - assign {path}_decr_thr{genvars} = {path}_q{genvars} + ({{{incr_width}{{{path}_incr}}}} & {path}_incr_val) - ({{{decr_width}{{{path}_decr}}}} & {path}_decr_val) > {thr_value}; + assign {path}_decr_thr{genvars} = {{1'b0, {path}_q{genvars}}} + ({{{width_plus_1}{{{path}_incr}}}} & {{{incr_sat_zero_pad}{path}_incr_val}}) <= {{1'b0, {sat_value}}} + ({{{width_plus_1}{{{path}_decr}}}} & {{{decr_sat_zero_pad}{path}_decr_val}}) ; output_ports: - name: '{path}_decr_thr' signal_type: 'logic' @@ -405,7 +405,7 @@ counter_overflow: rtl: |- // Logic to determine occurance of an overflow - assign {path}_overflow_int{genvars} = {path}_q{genvars} + ({{{incr_width}{{{path}_incr}}}} & {path}_incr_val) - ({{{decr_width}{{{path}_decr}}}} & {path}_decr_val) > {overflow_value}; + assign {path}_overflow_int{genvars} = {{1'b0, {path}_q{genvars}}} + ({{{width_plus_1}{{{path}_incr}}}} & {{{incr_sat_zero_pad}{path}_incr_val}}) - ({{{width_plus_1}{{{path}_decr}}}} & {{{decr_sat_zero_pad}{path}_decr_val}}) > {{1'b0, {overflow_value}}}; assign {path}_overflow{genvars} = {path}_incr{genvars} && {path}_overflow_int{genvars}; signals: - name: '{path}_overflow_int' @@ -417,8 +417,8 @@ counter_underflow: rtl: |- // Logic to determine occurance of an underflow - assign {path}_underflow_int{genvars} = {path}_q{genvars} + ({{{incr_width}{{{path}_incr}}}} & {path}_incr_val) - ({{{decr_width}{{{path}_decr}}}} & {path}_decr_val) > {underflow_value}; - assign {path}_underflow{genvars} = {path}_incr{genvars} && {path}_underflow_int{genvars}; + assign {path}_underflow_int{genvars} = {path}_q{genvars} + ({{{incr_width}{{{path}_incr}}}} & {path}_incr_val) > {underflow_value} + ({{{decr_width}{{{path}_decr}}}} & {path}_decr_val) ; + assign {path}_underflow{genvars} = {path}_decr{genvars} && {path}_underflow_int{genvars}; signals: - name: '{path}_underflow_int' signal_type: 'logic'