mirror of
https://github.com/Silicon1602/srdl2sv.git
synced 2024-11-14 11:03:36 +00:00
Improve counter property
The counter now covers more corner cases regarding saturation. Furthermore, a bug that caused incr & decr-counters to always inadvertently increment and decrement, even if only one of the two signals was set. Furthermore, the overflow signal is now generated in RTL. Still missing: - incrthreshold/decrthreshold is not yet supported - It is not yet supported to assign an underflow/overflow to the input of another counter.
This commit is contained in:
parent
4144329f3f
commit
18204d9a3e
@ -212,22 +212,30 @@ class Field(Component):
|
|||||||
if self.obj.get_property('counter'):
|
if self.obj.get_property('counter'):
|
||||||
self.logger.debug("Detected counter property")
|
self.logger.debug("Detected counter property")
|
||||||
|
|
||||||
# Determine saturation values
|
self.rtl_footer.append(Field.templ_dict['counter_comment']['rtl'])
|
||||||
|
|
||||||
|
# Determine saturation values and add appropriate RTL
|
||||||
if isinstance(self.obj.get_property('incrsaturate'), bool):
|
if isinstance(self.obj.get_property('incrsaturate'), bool):
|
||||||
if self.obj.get_property('incrsaturate'):
|
if self.obj.get_property('incrsaturate'):
|
||||||
incr_sat_value = 2**self.obj.width-1
|
incr_sat_value = 2**self.obj.width-1
|
||||||
|
overflow_value = incr_sat_value
|
||||||
else:
|
else:
|
||||||
incr_sat_value = False
|
incr_sat_value = False
|
||||||
|
overflow_value = 2**self.obj.width-1
|
||||||
else:
|
else:
|
||||||
incr_sat_value = self.obj.get_property('incrsaturate')
|
incr_sat_value = self.obj.get_property('incrsaturate')
|
||||||
|
overflow_value = incr_sat_value
|
||||||
|
|
||||||
if isinstance(self.obj.get_property('decrsaturate'), bool):
|
if isinstance(self.obj.get_property('decrsaturate'), bool):
|
||||||
if self.obj.get_property('decrsaturate'):
|
if self.obj.get_property('decrsaturate'):
|
||||||
decr_sat_value = 2**self.obj.width-1
|
decr_sat_value = 0
|
||||||
|
underflow_value = decr_sat_value
|
||||||
else:
|
else:
|
||||||
decr_sat_value = False
|
decr_sat_value = False
|
||||||
|
underflow_value = 0
|
||||||
else:
|
else:
|
||||||
decr_sat_value = self.obj.get_property('decrsaturate')
|
decr_sat_value = self.obj.get_property('decrsaturate')
|
||||||
|
underflow_value = decr_sat_value
|
||||||
|
|
||||||
# Determine with what value the counter is incremented
|
# Determine with what value the counter is incremented
|
||||||
# According to the spec, the incrvalue/decrvalue default to '1'
|
# According to the spec, the incrvalue/decrvalue default to '1'
|
||||||
@ -236,19 +244,23 @@ class Field(Component):
|
|||||||
obj_incr_width = self.obj.get_property('incrwidth')
|
obj_incr_width = self.obj.get_property('incrwidth')
|
||||||
obj_decr_width = self.obj.get_property('decrwidth')
|
obj_decr_width = self.obj.get_property('decrwidth')
|
||||||
|
|
||||||
|
incr_width_input = False
|
||||||
|
|
||||||
if obj_incr_value == 0:
|
if obj_incr_value == 0:
|
||||||
incr_value = None
|
incr_value = 0
|
||||||
incr_width = 0
|
incr_width = 1
|
||||||
elif obj_incr_value is None:
|
elif obj_incr_value is None:
|
||||||
if obj_incr_width:
|
# Increment value is not set. Check if incrwidth is set and use
|
||||||
# Decrement value is not set. Check if incrwidth is set and use
|
|
||||||
# that is applicable
|
# that is applicable
|
||||||
|
if obj_incr_width:
|
||||||
incr_value = False
|
incr_value = False
|
||||||
incr_width = obj_incr_width
|
incr_width = obj_incr_width
|
||||||
|
|
||||||
|
incr_width_input = True
|
||||||
|
|
||||||
# Doesn't return RTL, only adds input port
|
# Doesn't return RTL, only adds input port
|
||||||
self.process_yaml(
|
self.process_yaml(
|
||||||
Field.templ_dict['counter_incr_input'],
|
Field.templ_dict['counter_incr_val_input'],
|
||||||
{'path': self.path_underscored,
|
{'path': self.path_underscored,
|
||||||
'genvars': self.genvars_str,
|
'genvars': self.genvars_str,
|
||||||
'incr_width': incr_width-1
|
'incr_width': incr_width-1
|
||||||
@ -259,6 +271,7 @@ class Field(Component):
|
|||||||
incr_value = '1'
|
incr_value = '1'
|
||||||
incr_width = 1
|
incr_width = 1
|
||||||
elif isinstance(obj_incr_value, int):
|
elif isinstance(obj_incr_value, int):
|
||||||
|
# An explicit width is set for the incr_val
|
||||||
incr_value = str(obj_incr_value)
|
incr_value = str(obj_incr_value)
|
||||||
incr_width = math.floor(math.log2(obj_incr_value)+1)
|
incr_width = math.floor(math.log2(obj_incr_value)+1)
|
||||||
|
|
||||||
@ -284,10 +297,12 @@ class Field(Component):
|
|||||||
"will be ignored!")
|
"will be ignored!")
|
||||||
|
|
||||||
|
|
||||||
if incr_value:
|
# If no input is defined for the increment value, define
|
||||||
|
# an internal signal. It is possible that this is tied to 0.
|
||||||
|
if not incr_width_input:
|
||||||
self.rtl_footer.append(
|
self.rtl_footer.append(
|
||||||
self.process_yaml(
|
self.process_yaml(
|
||||||
Field.templ_dict['counter_internal_incr_signal'],
|
Field.templ_dict['counter_internal_incr_val_signal'],
|
||||||
{'path': self.path_underscored,
|
{'path': self.path_underscored,
|
||||||
'genvars': self.genvars_str,
|
'genvars': self.genvars_str,
|
||||||
'incr_width': incr_width-1,
|
'incr_width': incr_width-1,
|
||||||
@ -296,19 +311,24 @@ class Field(Component):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Handle decrement value
|
||||||
|
decr_width_input = False
|
||||||
|
|
||||||
if obj_decr_value == 0:
|
if obj_decr_value == 0:
|
||||||
decr_value = None
|
decr_value = 0
|
||||||
decr_width = 0
|
decr_width = 1
|
||||||
elif obj_decr_value is None:
|
elif obj_incr_value is None:
|
||||||
if obj_decr_width:
|
|
||||||
# Decrement value is not set. Check if decrwidth is set and use
|
# Decrement value is not set. Check if decrwidth is set and use
|
||||||
# that is applicable
|
# that is applicable
|
||||||
|
if obj_decr_width:
|
||||||
decr_value = False
|
decr_value = False
|
||||||
decr_width = obj_decr_width
|
decr_width = obj_decr_width
|
||||||
|
|
||||||
|
decr_width_input = True
|
||||||
|
|
||||||
# Doesn't return RTL, only adds input port
|
# Doesn't return RTL, only adds input port
|
||||||
self.process_yaml(
|
self.process_yaml(
|
||||||
Field.templ_dict['counter_decr_input'],
|
Field.templ_dict['counter_decr_val_input'],
|
||||||
{'path': self.path_underscored,
|
{'path': self.path_underscored,
|
||||||
'genvars': self.genvars_str,
|
'genvars': self.genvars_str,
|
||||||
'decr_width': decr_width-1
|
'decr_width': decr_width-1
|
||||||
@ -319,6 +339,7 @@ class Field(Component):
|
|||||||
decr_value = '1'
|
decr_value = '1'
|
||||||
decr_width = 1
|
decr_width = 1
|
||||||
elif isinstance(obj_decr_value, int):
|
elif isinstance(obj_decr_value, int):
|
||||||
|
# An explicit width is set for the decr_val
|
||||||
decr_value = str(obj_decr_value)
|
decr_value = str(obj_decr_value)
|
||||||
decr_width = math.floor(math.log2(obj_decr_value)+1)
|
decr_width = math.floor(math.log2(obj_decr_value)+1)
|
||||||
|
|
||||||
@ -344,10 +365,12 @@ class Field(Component):
|
|||||||
"will be ignored!")
|
"will be ignored!")
|
||||||
|
|
||||||
|
|
||||||
if decr_value:
|
# If no input is defined for the decrement value, define
|
||||||
|
# an internal signal. It is possible that this is tied to 0.
|
||||||
|
if not decr_width_input:
|
||||||
self.rtl_footer.append(
|
self.rtl_footer.append(
|
||||||
self.process_yaml(
|
self.process_yaml(
|
||||||
Field.templ_dict['counter_internal_decr_signal'],
|
Field.templ_dict['counter_internal_decr_val_signal'],
|
||||||
{'path': self.path_underscored,
|
{'path': self.path_underscored,
|
||||||
'genvars': self.genvars_str,
|
'genvars': self.genvars_str,
|
||||||
'decr_width': decr_width-1,
|
'decr_width': decr_width-1,
|
||||||
@ -356,92 +379,174 @@ class Field(Component):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (incr_width or incr_value) and (decr_width or decr_value):
|
# Handle the increment/decrement signals.
|
||||||
sat_condition = []
|
# If the increment or decrement signal is not set, use an input
|
||||||
if incr_sat_value:
|
# if the decrement value is bigger than 0
|
||||||
sat_condition.append(
|
if not incr_value and not decr_value:
|
||||||
self.process_yaml(
|
|
||||||
Field.templ_dict['incr_decr_sat_counter_condition'],
|
|
||||||
{'path': self.path_underscored,
|
|
||||||
'genvars': self.genvars_str,
|
|
||||||
'greater_smaller': '>',
|
|
||||||
'sat_value': incr_sat_value
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if decr_sat_value:
|
|
||||||
if sat_condition:
|
|
||||||
sat_condition.append(' && ')
|
|
||||||
|
|
||||||
sat_condition.append(
|
|
||||||
self.process_yaml(
|
|
||||||
Field.templ_dict['incr_decr_sat_counter_condition'],
|
|
||||||
{'path': self.path_underscored,
|
|
||||||
'genvars': self.genvars_str,
|
|
||||||
'greater_smaller': '<',
|
|
||||||
'sat_value': decr_sat_value
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
counter_logic = self.process_yaml(
|
|
||||||
Field.templ_dict['incr_decr_counter'],
|
|
||||||
{'path': self.path_underscored,
|
|
||||||
'genvars': self.genvars_str,
|
|
||||||
'incr_decr_sat_counter_condition': ''.join(sat_condition),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
elif incr_width or incr_value:
|
|
||||||
sat_condition = self.process_yaml(
|
|
||||||
Field.templ_dict['incr_sat_counter_condition'],
|
|
||||||
{'path': self.path_underscored,
|
|
||||||
'genvars': self.genvars_str,
|
|
||||||
'sat_value': incr_sat_value,
|
|
||||||
}
|
|
||||||
) if incr_sat_value else '1'
|
|
||||||
|
|
||||||
counter_logic = self.process_yaml(
|
|
||||||
Field.templ_dict['incr_counter'],
|
|
||||||
{'path': self.path_underscored,
|
|
||||||
'genvars': self.genvars_str,
|
|
||||||
'incr_sat_counter_condition': sat_condition,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
elif decr_width or decr_value:
|
|
||||||
sat_condition = self.process_yaml(
|
|
||||||
Field.templ_dict['decr_sat_counter_condition'],
|
|
||||||
{'path': self.path_underscored,
|
|
||||||
'genvars': self.genvars_str,
|
|
||||||
'sat_value': decr_sat_value,
|
|
||||||
}
|
|
||||||
) if decr_sat_value else '1'
|
|
||||||
|
|
||||||
counter_logic = self.process_yaml(
|
|
||||||
Field.templ_dict['decr_counter'],
|
|
||||||
{'path': self.path_underscored,
|
|
||||||
'genvars': self.genvars_str,
|
|
||||||
'decr_sat_counter_condition': sat_condition,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.logger.fatal("Illegal counter configuration! Both 'incr_value' "\
|
self.logger.fatal("Illegal counter configuration! Both 'incr_value' "\
|
||||||
"and 'decr_value' are forced to 0. If you intended "\
|
"and 'decr_value' are forced to 0. If you intended "\
|
||||||
"to use 'incr_width' or 'decr_width', simply don't "\
|
"to use 'incr_width' or 'decr_width', simply don't "\
|
||||||
"force 'incr_value' or 'decr_value' to any value.")
|
"force 'incr_value' or 'decr_value' to any value.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
if incr_value:
|
||||||
|
incr = self.obj.get_property('incr')
|
||||||
|
|
||||||
|
if not incr:
|
||||||
|
# Will only add input port but not return any RTL
|
||||||
|
self.process_yaml(
|
||||||
|
Field.templ_dict['counter_incr_input'],
|
||||||
|
{'path': self.path_underscored}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.rtl_footer.append(
|
||||||
|
self.process_yaml(
|
||||||
|
Field.templ_dict['counter_internal_incr_signal'],
|
||||||
|
{'path': self.path_underscored,
|
||||||
|
'genvars': self.genvars_str,
|
||||||
|
'incr': self.get_signal_name(incr)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if incr.width > 0:
|
||||||
|
self.logger.error("Increment signal '{}' is wider than 1-bit. "\
|
||||||
|
"This might result in unwanted behavior and "\
|
||||||
|
"will also cause Lint-errors.".format(
|
||||||
|
incr.inst_name))
|
||||||
|
else:
|
||||||
|
# Tie signal to 0
|
||||||
|
self.rtl_footer.append(
|
||||||
|
self.process_yaml(
|
||||||
|
Field.templ_dict['counter_internal_incr_signal'],
|
||||||
|
{'path': self.path_underscored,
|
||||||
|
'genvars': self.genvars_str,
|
||||||
|
'incr': '0'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if decr_value:
|
||||||
|
decr = self.obj.get_property('decr')
|
||||||
|
|
||||||
|
if not self.obj.get_property('decr'):
|
||||||
|
# Will only add input port but not return any RTL
|
||||||
|
self.process_yaml(
|
||||||
|
Field.templ_dict['counter_decr_input'],
|
||||||
|
{'path': self.path_underscored}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.rtl_footer.append(
|
||||||
|
self.process_yaml(
|
||||||
|
Field.templ_dict['counter_internal_decr_signal'],
|
||||||
|
{'path': self.path_underscored,
|
||||||
|
'genvars': self.genvars_str,
|
||||||
|
'decr': self.get_signal_name(decr)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if decr.width > 0:
|
||||||
|
self.logger.error("Decrement signal '{}' is wider than 1-bit. "\
|
||||||
|
"This might result in unwanted behavior and "\
|
||||||
|
"will also cause Lint-errors.".format(
|
||||||
|
decr.inst_name))
|
||||||
|
else:
|
||||||
|
# Tie signal to 0
|
||||||
|
self.rtl_footer.append(
|
||||||
|
self.process_yaml(
|
||||||
|
Field.templ_dict['counter_internal_decr_signal'],
|
||||||
|
{'path': self.path_underscored,
|
||||||
|
'genvars': self.genvars_str,
|
||||||
|
'decr': '0'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Handle saturation signals
|
||||||
|
if not incr_sat_value:
|
||||||
|
self.rtl_footer.append(
|
||||||
|
self.process_yaml(
|
||||||
|
Field.templ_dict['counter_incr_sat_tied'],
|
||||||
|
{'path': self.path_underscored,
|
||||||
|
'genvars': self.genvars_str,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.rtl_footer.append(
|
||||||
|
self.process_yaml(
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if not decr_sat_value:
|
||||||
|
self.rtl_footer.append(
|
||||||
|
self.process_yaml(
|
||||||
|
Field.templ_dict['counter_decr_sat_tied'],
|
||||||
|
{'path': self.path_underscored,
|
||||||
|
'genvars': self.genvars_str,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.rtl_footer.append(
|
||||||
|
self.process_yaml(
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Handle overflow & underflow signals
|
||||||
|
if self.obj.get_property('overflow'):
|
||||||
|
self.rtl_footer.append(
|
||||||
|
self.process_yaml(
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.obj.get_property('underflow'):
|
||||||
|
self.rtl_footer.append(
|
||||||
|
self.process_yaml(
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Implement actual counter logic
|
||||||
self.rtl_footer.append(
|
self.rtl_footer.append(
|
||||||
self.process_yaml(
|
self.process_yaml(
|
||||||
Field.templ_dict['counter'],
|
Field.templ_dict['counter'],
|
||||||
{'path': self.path_underscored,
|
{'path': self.path_underscored,
|
||||||
'genvars': self.genvars_str,
|
'genvars': self.genvars_str,
|
||||||
'counter_logic': counter_logic,
|
|
||||||
'field_type': self.field_type,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def __add_swmod_swacc(self):
|
def __add_swmod_swacc(self):
|
||||||
if self.obj.get_property('swmod'):
|
if self.obj.get_property('swmod'):
|
||||||
self.logger.debug("Field has swmod property")
|
self.logger.debug("Field has swmod property")
|
||||||
|
@ -92,7 +92,7 @@ hw_access_field:
|
|||||||
signal_type: '{field_type}'
|
signal_type: '{field_type}'
|
||||||
hw_access_counter:
|
hw_access_counter:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
if ({path}_update_cnt{genvars})
|
if ({path}_incr{genvars} || {path}_decr{genvars})
|
||||||
<<INDENT>>
|
<<INDENT>>
|
||||||
{enable_mask_start}
|
{enable_mask_start}
|
||||||
{path}_q{genvars}{idx} <= {path}_next{genvars}{idx};
|
{path}_q{genvars}{idx} <= {path}_next{genvars}{idx};
|
||||||
@ -226,93 +226,145 @@ swmod_assign:
|
|||||||
output_ports:
|
output_ports:
|
||||||
- name: '{path}_swmod'
|
- name: '{path}_swmod'
|
||||||
signal_type: 'logic'
|
signal_type: 'logic'
|
||||||
|
counter_comment:
|
||||||
|
rtl: |-
|
||||||
|
/***********************
|
||||||
|
* Counter Combo Logic *
|
||||||
|
***********************/
|
||||||
counter:
|
counter:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
|
|
||||||
// Combinational logic that implements counter
|
// Combinational logic that implements counter
|
||||||
|
// Note that the three branches for all three possibilities
|
||||||
|
// are implemented but that either the _incr or the _decr value
|
||||||
|
// might be tied to 0.
|
||||||
always_comb
|
always_comb
|
||||||
begin
|
begin
|
||||||
{path}_next{genvars} = {path}_q{genvars};
|
{path}_next{genvars} = {path}_q{genvars};
|
||||||
{path}_update_cnt{genvars} = 0;
|
|
||||||
|
|
||||||
{counter_logic}
|
|
||||||
|
|
||||||
|
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};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else if ({path}_incr{genvars})
|
||||||
|
begin
|
||||||
|
if (!{path}_incr_sat{genvars})
|
||||||
|
<<INDENT>>
|
||||||
|
{path}_next{genvars} += {path}_incr_val{genvars};
|
||||||
|
<<UNINDENT>>
|
||||||
|
end
|
||||||
|
else if ({path}_decr{genvars})
|
||||||
|
begin
|
||||||
|
if (!{path}_decr_sat{genvars})
|
||||||
|
<<INDENT>>
|
||||||
|
{path}_next{genvars} += {path}_decr_val{genvars};
|
||||||
|
<<UNINDENT>>
|
||||||
|
end
|
||||||
end
|
end
|
||||||
signals:
|
signals:
|
||||||
- name: '{path}_update_cnt'
|
|
||||||
signal_type: 'logic'
|
|
||||||
- name: '{path}_next'
|
- name: '{path}_next'
|
||||||
signal_type: '{field_type}'
|
signal_type: '{field_type}'
|
||||||
counter_internal_incr_signal:
|
counter_internal_incr_val_signal:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
assign {path}_incr_val{genvars} = {incr_value};
|
assign {path}_incr_val{genvars} = {incr_value};
|
||||||
signals:
|
signals:
|
||||||
- name: '{path}_incr_val'
|
- name: '{path}_incr_val'
|
||||||
signal_type: 'logic [{incr_width}:0]'
|
signal_type: 'logic [{incr_width}:0]'
|
||||||
counter_internal_decr_signal:
|
counter_internal_decr_val_signal:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
assign {path}_decr_val{genvars} = {decr_value};
|
assign {path}_decr_val{genvars} = {decr_value};
|
||||||
signals:
|
signals:
|
||||||
- name: '{path}_decr_val'
|
- name: '{path}_decr_val'
|
||||||
signal_type: 'logic [{decr_width}:0]'
|
signal_type: 'logic [{decr_width}:0]'
|
||||||
counter_incr_input:
|
counter_incr_val_input:
|
||||||
rtl: ''
|
rtl: ''
|
||||||
input_ports:
|
input_ports:
|
||||||
- name: '{path}_incr_val'
|
- name: '{path}_incr_val'
|
||||||
signal_type: 'logic [{incr_width}:0]'
|
signal_type: 'logic [{incr_width}:0]'
|
||||||
counter_decr_input:
|
counter_decr_val_input:
|
||||||
rtl: ''
|
rtl: ''
|
||||||
input_ports:
|
input_ports:
|
||||||
- name: '{path}_decr_val'
|
- name: '{path}_decr_val'
|
||||||
signal_type: 'logic [{decr_width}:0]'
|
signal_type: 'logic [{decr_width}:0]'
|
||||||
incr_counter:
|
counter_internal_incr_signal:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
if ({path}_incr{genvars})
|
assign {path}_incr{genvars} = {incr};
|
||||||
begin
|
signals:
|
||||||
if ({incr_sat_counter_condition})
|
|
||||||
begin
|
|
||||||
{path}_next{genvars} += {path}_incr_val{genvars};
|
|
||||||
{path}_update_cnt{genvars} = 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
input_ports:
|
|
||||||
- name: '{path}_incr'
|
- name: '{path}_incr'
|
||||||
signal_type: 'logic'
|
signal_type: 'logic'
|
||||||
decr_counter:
|
counter_internal_decr_signal:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
if ({path}_decr{genvars})
|
assign {path}_decr{genvars} = {decr};
|
||||||
begin
|
signals:
|
||||||
if ({decr_sat_counter_condition})
|
|
||||||
begin
|
|
||||||
{path}_next{genvars} -= {path}_decr_val{genvars};
|
|
||||||
{path}_update_cnt{genvars} = 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
input_ports:
|
|
||||||
- name: '{path}_decr'
|
- name: '{path}_decr'
|
||||||
signal_type: 'logic'
|
signal_type: 'logic'
|
||||||
incr_decr_counter:
|
counter_incr_input:
|
||||||
rtl: |-
|
rtl: ''
|
||||||
if ({path}_incr{genvars} || {path}_decr{genvars})
|
|
||||||
begin
|
|
||||||
if ({incr_decr_sat_counter_condition})
|
|
||||||
begin
|
|
||||||
{path}_next{genvars} += {path}_incr_val{genvars};
|
|
||||||
{path}_next{genvars} -= {path}_decr_val{genvars};
|
|
||||||
{path}_update_cnt{genvars} = 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
input_ports:
|
input_ports:
|
||||||
- name: '{path}_incr'
|
- name: '{path}_incr'
|
||||||
signal_type: 'logic'
|
signal_type: ''
|
||||||
|
counter_decr_input:
|
||||||
|
rtl: ''
|
||||||
|
input_ports:
|
||||||
- name: '{path}_decr'
|
- name: '{path}_decr'
|
||||||
|
signal_type: ''
|
||||||
|
counter_incr_sat:
|
||||||
|
rtl: |-
|
||||||
|
|
||||||
|
// 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};
|
||||||
|
signals:
|
||||||
|
- name: '{path}_incr_sat'
|
||||||
signal_type: 'logic'
|
signal_type: 'logic'
|
||||||
incr_sat_counter_condition:
|
counter_incr_sat_tied:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
{path}_next{genvars} + {path}_incr_val{genvars} <= {sat_value}
|
|
||||||
decr_sat_counter_condition:
|
// 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} = 1'b0;
|
||||||
|
signals:
|
||||||
|
- name: '{path}_incr_sat'
|
||||||
|
signal_type: 'logic'
|
||||||
|
counter_decr_sat:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
{path}_next{genvars} - {path}_decr_val{genvars} >= {sat_value}
|
assign {path}_decr_sat{genvars} = {path}_q{genvars} + ({{{incr_width}{{{path}_incr}}}} & {path}_incr_val) - ({{{decr_width}{{{path}_decr}}}} & {path}_decr_val) > {sat_value};
|
||||||
incr_decr_sat_counter_condition:
|
signals:
|
||||||
|
- name: '{path}_decr_sat'
|
||||||
|
signal_type: 'logic'
|
||||||
|
counter_decr_sat_tied:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
({path}_next{genvars} + {path}_incr_val{genvars} - {path}_decr_val{genvars} {greater_smaller}= {sat_value})
|
assign {path}_decr_sat{genvars} = 1'b0;
|
||||||
|
signals:
|
||||||
|
- name: '{path}_decr_sat'
|
||||||
|
signal_type: 'logic'
|
||||||
|
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{genvars} = {path}_incr{genvars} && {path}_overflow_int{genvars};
|
||||||
|
signals:
|
||||||
|
- name: '{path}_overflow_int'
|
||||||
|
signal_type: 'logic'
|
||||||
|
output_ports:
|
||||||
|
- name: '{path}_overflow'
|
||||||
|
signal_type: 'logic'
|
||||||
|
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};
|
||||||
|
signals:
|
||||||
|
- name: '{path}_underflow_int'
|
||||||
|
signal_type: 'logic'
|
||||||
|
output_ports:
|
||||||
|
- name: '{path}_underflow'
|
||||||
|
signal_type: 'logic'
|
||||||
|
Loading…
Reference in New Issue
Block a user