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

Zmmul: Multiply without Divide Extension #3391

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from

Conversation

nananapo
Copy link

@nananapo nananapo commented Jun 16, 2023

Type of change: other enhancement

Impact: API addition (no impact on existing code)

Development Phase: implementation

Release Notes

This PR is to add Zmmul extension on the rocket-chip.
This adds a new Config WithoutDiv and a new parameter divEnabled in MulDivParams.
When divEnabled is false, div logic of MulDiv module is disabled. And div/rem instruction is not included in a decode table.

Copy link
Contributor

@ZenithalHourlyRate ZenithalHourlyRate left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall good to me! Though the software design for enabling Zmmul needs further discussion, including the config name. WithMulDivWithoutDiv seems confusing.

Could you demo with an emulator that a div instruction will cause illegal instruction exception in this config?

Could you add an arch-test CI for zmmul?

@@ -30,6 +30,7 @@ trait CoreParams {
val useCryptoSM: Boolean
val useRVE: Boolean
val useConditionalZero: Boolean
val useMulDivWithoutDiv: Boolean
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

context: We had some prior private communication.

After seeing the code things become more clear to me, It seems that useMulDivWithoutDiv can be merged into MulDiv by setting divUnroll = 0 instead of a standalone option?

I favor this simple way. And for the exposed interface to the end user, he/she only needs to use some config like WithoutDiv and that config will set divUnroll = 0

But this is tricky as divUnroll == 0 has two purpose for developer now

  1. Zmmul, namely turning off div.
  2. Alternative divider impl suggested in Teach MulDiv to do div-only #1228

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After discussion with Jerry, it is concluded that adding another option inside MulDivParams like divUnroll: Option[Int] or (divUnroll: Int and divEnable: Boolean = true) should be used, instead of another boolean in CoreParams. The later way is prefered as it wont break compatibility.

@@ -118,6 +118,7 @@ trait HasNonDiplomaticTileParameters {
Option.when(tileParams.core.useBitManip)(Seq("zbs")) ++
Option.when(tileParams.core.useCryptoNIST)(Seq("zknd", "zkne", "zknh")) ++
Option.when(tileParams.core.useCryptoSM)(Seq("zksed", "zksh")) ++
Option.when(tileParams.core.mulDiv.nonEmpty && tileParams.core.useMulDivWithoutDiv)(Seq("zmmul")) ++
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. zmmul should be placed after zihpm instead of appending to the end

  2. Some interesting thing: rv32imac_zmmul is a valid ISA string.

case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
core = tp.tileParams.core.copy(
mulDiv = Some(MulDivParams(mulUnroll = 8)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not set mulUnroll here.

Copy link
Contributor

@ZenithalHourlyRate ZenithalHourlyRate left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other parts look good to me!

@@ -29,6 +29,7 @@ class MultiplierIO(val dataBits: Int, val tagBits: Int, aluFn: ALUFN = new ALUFN
case class MulDivParams(
mulUnroll: Int = 1,
divUnroll: Int = 1,
divEnabled: Boolean = false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should default to true.

@@ -112,6 +112,7 @@ trait HasNonDiplomaticTileParameters {
//Some(Seq("zicntr")) ++
Option.when(tileParams.core.useConditionalZero)(Seq("zicond")) ++
Some(Seq("zicsr", "zifencei", "zihpm")) ++
Option.when(tileParams.core.mulDiv.nonEmpty && !tileParams.core.mulDiv.get.divEnabled)(Seq("zmmul")) ++
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot to start a review...

Actually it should be

      Option.when(tileParams.core.mulDiv.nonEmpty)(Seq("zmmul")) ++

Check riscv/riscv-isa-manual#869 for more details.

And apply the following diff to the m instead

-val m = if (tileParams.core.mulDiv.nonEmpty) "m" else ""
+val m = if (tileParams.core.mulDiv.nonEmpty  && !tileParams.core.mulDiv.get.divEnabled) "m" else ""

Also you should update the MISA generation in CSR.scala

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi.
If I understand correctly, there is a diferrence between rv32im_zmmul and rv32im about mul inst when misa.M=0.
If I change ISA of rocket-chip to rv32im_zmmul when mulDiv.nonEmpty, the behaviour of mul inst with misa.M=0 will be changed to not cause illegal instruction exception.
Is it OK?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, there is a diferrence between rv32im_zmmul and rv32im about mul inst when misa.M=0.

It does exist in that thread, but from my perception it was not the focus of that thread and it was not finally decided.

From riscv/riscv-isa-manual#869 (comment), a future Sm* extension should come to solve the problem. As it does not exist for now, I assume this detail is undefined, so it is now implementation-defined.

If I change ISA of rocket-chip to rv32im_zmmul when mulDiv.nonEmpty, the behaviour of mul inst with misa.M=0 will be changed to not cause illegal instruction exception.

I think we should not change the behavior, as it is undefined, and counter-intuitive.

I think we should officially support only two modes: m and zmmul. As for m_zmmul, it is equivalent to m and the misa behavior is the same as m.

Now I wont insist that we should output m_zmmul for m. I am OK if you want to just output m or zmmul in the ISA string. One final commit/comment and I will merge.

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.

2 participants