-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FPU rounding module #728
base: master
Are you sure you want to change the base?
FPU rounding module #728
Conversation
|
||
self.rtval["exp"] = self.final_exp | ||
self.rtval["sig"] = self.final_sig | ||
self.rtval["sign"] = self.final_sign | ||
self.rtval["errors"] = self.final_errors | ||
|
||
return self.rtval |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use inline dictionary in return, like:
return {
"exp": self.final_exp,
...
class FPUrounding(Component): | ||
|
||
fpu_rounding: FPURoundingSignature |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the Component
used? Is the interface used aynwhere?
def elaborate(self, platform): | ||
m = TModule() | ||
|
||
@def_method(m, self.rounding_request) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, all of comb
domains could be replaced with av_comb
, to skip adding extra multiplexer (that enables the assignment only on rounding_request
run condition).
] | ||
|
||
|
||
class FPUrounding(Component): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Docstring would be helpful
self.rtval = {} | ||
self.max_exp = C( | ||
2 ** (self.fpu_rounding_params.fpu_params.exp_width) - 1, | ||
unsigned(self.fpu_rounding_params.fpu_params.exp_width), | ||
) | ||
self.max_normal_exp = C( | ||
2 ** (self.fpu_rounding_params.fpu_params.exp_width) - 2, | ||
unsigned(self.fpu_rounding_params.fpu_params.exp_width), | ||
) | ||
self.quiet_nan = C( | ||
2 ** (self.fpu_rounding_params.fpu_params.sig_width - 1), | ||
unsigned(self.fpu_rounding_params.fpu_params.sig_width), | ||
) | ||
self.max_sig = C( | ||
2 ** (self.fpu_rounding_params.fpu_params.sig_width) - 1, | ||
unsigned(self.fpu_rounding_params.fpu_params.sig_width), | ||
) | ||
self.add_one = Signal() | ||
self.inc_rtnte = Signal() | ||
self.inc_rtnta = Signal() | ||
self.inc_rtpi = Signal() | ||
self.inc_rtmi = Signal() | ||
|
||
self.rounded_sig = Signal(self.fpu_rounding_params.fpu_params.sig_width + 1) | ||
self.normalised_sig = Signal(self.fpu_rounding_params.fpu_params.sig_width) | ||
self.rounded_exp = Signal(self.fpu_rounding_params.fpu_params.exp_width + 1) | ||
|
||
self.final_guard_bit = Signal() | ||
self.final_sticky_bit = Signal() | ||
|
||
self.overflow = Signal() | ||
self.underflow = Signal() | ||
self.inexact = Signal() | ||
self.tininess = Signal() | ||
self.is_inf = Signal() | ||
self.is_nan = Signal() | ||
self.input_not_special = Signal() | ||
self.rounded_inexact = Signal() | ||
|
||
self.final_exp = Signal(self.fpu_rounding_params.fpu_params.exp_width) | ||
self.final_sig = Signal(self.fpu_rounding_params.fpu_params.sig_width) | ||
self.final_sign = Signal() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
those are module internal signals/constants, there is no need to make them public. definitions could be placed in elaborate
code and without self.
("sign", 1), | ||
("sig", fpu_params.sig_width), | ||
("exp", fpu_params.exp_width), | ||
("guard_bit", 1), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean round_bit
?
|
||
with m.Elif(self.overflow): | ||
|
||
with m.If( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amaranth switch/case could be used: with m.Switch(arg.rounding_mode)
yield from one_rounding_mode_test( | ||
RoundingModes.ROUND_NEAREST_EVEN, | ||
tie_to_even_inc_array, | ||
0, | ||
help_values.max_exp, | ||
0, | ||
help_values.max_exp, | ||
request_adapter, | ||
is_input_not_rounded, | ||
) | ||
yield from one_rounding_mode_test( | ||
RoundingModes.ROUND_NEAREST_AWAY, | ||
tie_to_away_inc_array, | ||
0, | ||
help_values.max_exp, | ||
0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests can be parametrized with @parametrize_class
, @parameterized.expand
or similar
("exp", fpu_params.exp_width), | ||
("guard_bit", 1), | ||
("sticky_bit", 1), | ||
("rounding_mode", 3), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
enums can be used as signal shapes
("rounding_mode", 3), | |
("rounding_mode", RoundingModes), |
with m.If((self.rounded_exp == 0) & (self.normalised_sig[-1] == 1)): | ||
m.d.comb += self.final_exp.eq(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain this condition?
Implementation of the rounding module for FPU.
This module excepts that input is in normalized form (unless the number is subnormal) and, in accordance with RISC-V specification, detects tininess after rounding. The flag that allows generation of a rounding module that assumes that input was already rounded is to be used by modules that are able to perform both their operation and rounding at the same time (adder/subtractor, for example). In that case, this module only checks for errors and special cases (one of the inputs was inf/nan).