Skip to content
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

Mux1H: don't special-case (sel: UInt, in: UInt) #1320

Closed
wants to merge 1 commit into from
Closed

Mux1H: don't special-case (sel: UInt, in: UInt) #1320

wants to merge 1 commit into from

Conversation

ingallsj
Copy link
Contributor

@ingallsj ingallsj commented Feb 6, 2020

Related issue: #1314

Type of change: bug report

Impact: API modification

Development Phase: proposal

Release Notes
if instantiating a Mux1H(sel: UInt, in: UInt) when in.getWidth==1, do the same behavior as instantiating a Mux1H(sel.asBools, in.asBools): ignore the select and connect the input directly to the output

@ingallsj ingallsj requested a review from a team as a code owner February 6, 2020 06:36
@claassistantio
Copy link

claassistantio commented Feb 6, 2020

CLA assistant check
All committers have signed the CLA.

@aswaterman
Copy link
Member

Bringing this Mux1H API in line with the others seems like a good thing to do, but it raises some subtle issues:

  • This new version calls asBools, so it'll bail out if the width isn't known at elaboration time, whereas the previous version would just work.
  • Even though this brings the API in line with the others, and even though both the old and new behaviors are within the bounds of a one-hot API, it is a change that some users could theoretically notice. I guess we need a release note or something.
  • The original @note is incomplete, as it fails to mention the zero-hot case. It should say "results unspecified unless exactly one select signal is high". Then the new note you added isn't necessary.

It is possible to get rid of the dependence on asBools by doing something esoteric like

val isLessThanTwoBitsWide = (sel + 1.U) === (sel - 1.U)
Mux(isLessThanTwoBitsWide, in, (sel & in).orR)

where the first statement is a way to check whether sel is one bit wide, but to postpone the check til Firrtl time. (There's got to be a better way of doing that...)

@albert-magyar
Copy link
Contributor

@aswaterman, I think the idea for your example is that the Mux will be optimized away via const-prop after the select case is coerced to a constant?

If so, I imagine that implicitly depends on the idea that (sel + 1.U) and (sel - 1.U) will be strength-reduced to matching expressions for 1-bit sel. This currently does not happen in FIRRTL but seems reasonable to add.

It also in turn depends on FIRRTL const-propping a == a, which I had assumed might already be the case but is actually not currently done. I just PRed those matching-argument degeneracies to const prop in chipsalliance/firrtl#1361.

@aswaterman
Copy link
Member

aswaterman commented Feb 6, 2020 via email

@ingallsj
Copy link
Contributor Author

ingallsj commented Mar 2, 2020

#1314 (comment) :

I definitely don’t want to change the behavior of the 1-wide case for the other ones. If you want the and-or thing even in the 1-wide case, it’s a one-liner in Scala, or you can make your own library method for it rather than using the Chisel one.

will do

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants