fmin/fmax ok

master
kaqu 1 year ago
parent df65276f56
commit ff357d54bf
  1. 5
      debugger/dbgeval.py
  2. 105
      libmodules/fpu_decode.py
  3. 17
      libmodules/instruction_decode.py
  4. 2
      software/source/flwstw.c

@ -252,6 +252,11 @@ def disassemble(opcode, pc):
msg = "fsgnjn.s {0},{1},{2}".format(f_description[rd], f_description[rs1], f_description[rs2])
elif f3 == 0x02:
msg = "fsgnjx.s {0},{1},{2}".format(f_description[rd], f_description[rs1], f_description[rs2])
elif f7 == 0x14: # compares
if f3 == 0x00:
msg = "fmin.s {0},{1},{2}".format(f_description[rd], f_description[rs1], f_description[rs2])
elif f3 == 0x01:
msg = "fmax.s {0},{1},{2}".format(f_description[rd], f_description[rs1], f_description[rs2])
elif f7 == 0x70:
if f3 == 0x00:
msg = "fmv.x.s {0},{1}".format(x_description[rd], f_description[rs1])

@ -35,6 +35,9 @@ class Risq5FPUDecoder(Module):
self.fmsub = Signal()
self.fnmadd = Signal()
self.fnmsub = Signal()
self.fmin = Signal()
self.fmax = Signal()
self.fcvt_w_s = Signal()
self.fready = Signal() # Indicate ready
self.fwrite = Signal() # F-Extension: Do a write to a float register
@ -70,7 +73,7 @@ class Risq5FPUDecoder(Module):
NextValue(self.m1, Cat(0,0,0, regs.fs1[0:23], 1, 0)), # | 0x00800000 + R/G/S bits
NextValue(self.m2, Cat(0,0,0, regs.fs2[0:23], 1, 0)), # | 0x00800000 + R/G/S bits
NextState("FADD1")
).Elif((self.fmadd | self.fmsub | self.fnmadd | self.fnmsub | self.fmul | self.fdiv) & ~self.fready, # Triggers set & ready flag reset externally!
).Elif((self.fmin | self.fmax | self.fmadd | self.fmsub | self.fnmadd | self.fnmsub | self.fmul | self.fdiv) & ~self.fready, # Triggers set & ready flag reset externally!
NextValue(self.sign1, regs.fs1[31]),
NextValue(self.sign2, regs.fs2[31]),
NextValue(self.e1, regs.fs1[23:31] - 127),
@ -79,14 +82,22 @@ class Risq5FPUDecoder(Module):
NextValue(self.m2, Cat(regs.fs2[0:23], 1, 0)), # | 0x00800000
If(self.fdiv, # Division
NextState("FDIV1"),
).Elif(self.fmin, # Minimum
NextState("FMIN1"),
).Elif(self.fmax, # Maximum
NextState("FMAX1")
).Else( # Multiplication variants
NextState("FMUL1"),
)
).Elif(self.fsqrt & ~self.fready, # Trigger set & ready flag reset externally!
).Elif((self.fsqrt | self.fcvt_w_s) & ~self.fready, # Trigger set & ready flag reset externally!
NextValue(self.sign1, regs.fs1[31]),
NextValue(self.e1, regs.fs1[23:31] - 127),
NextValue(self.m1, Cat(regs.fs1[0:23], 1, 0)), # | 0x00800000
NextState("FSQRT1"),
If(self.fsqrt,
NextState("FSQRT1"),
).Else( # Conversion to integer ...
NextState("FCVT_W_S1")
)
)
)
@ -461,6 +472,94 @@ class Risq5FPUDecoder(Module):
NextState("FPU_IDLE")
) # End of fsqrt.s processing
FPU_fsm.act("FMIN1",
# Simple sign compare ahead
If(self.sign1 ^ self.sign2, # Sign mismatch? That's easy!
If(self.sign1, # f1 negative -> hence smaller (min!)
NextValue(regs.frd_wrport.dat_w, regs.fs1), # Just map value straight ...
).Else( # f2 negative/min
NextValue(regs.frd_wrport.dat_w, regs.fs2), # Just map value straight ...
)
).Elif(self.e1 < self.e2, # Same sign: Compare exponents, then (maybe) mantissas
# f1 smaller absolute number?
If(self.sign1, # But negative?
NextValue(regs.frd_wrport.dat_w, regs.fs2), # Just map value straight ...
).Else( # Positive
NextValue(regs.frd_wrport.dat_w, regs.fs1), # Just map value straight ...
)
).Elif(self.e2 < self.e1, # f2 smaller absolute number?
If(self.sign1, # But negative?
NextValue(regs.frd_wrport.dat_w, regs.fs1), # Just map value straight ...
).Else( # Positive
NextValue(regs.frd_wrport.dat_w, regs.fs2), # Just map value straight ...
)
).Else( # Equal exponents?
If(self.m1 < self.m2, # Compare mantissas: f1 smaller
If(self.sign1, # But negative?
NextValue(regs.frd_wrport.dat_w, regs.fs2), # Just map value straight ...
).Else( # Positive
NextValue(regs.frd_wrport.dat_w, regs.fs1), # Just map value straight ...
)
).Else( # f2 smaller/equal
If(self.sign1, # But negative?
NextValue(regs.frd_wrport.dat_w, regs.fs1), # Just map value straight ...
).Else( # Positive
NextValue(regs.frd_wrport.dat_w, regs.fs2), # Just map value straight ...
)
)
),
NextValue(self.fwrite, 1), # Write required
NextValue(self.fready, 1), # Indicate ready to main decoder
NextState("FPU_IDLE")
) # End of fmin.s processing
FPU_fsm.act("FMAX1",
# Simple sign compare ahead
If(self.sign1 ^ self.sign2, # Sign mismatch? That's easy!
If(self.sign1, # f1 negative -> hence smaller (min!)
NextValue(regs.frd_wrport.dat_w, regs.fs2), # Just map value straight ...
).Else( # f2 negative/min
NextValue(regs.frd_wrport.dat_w, regs.fs1), # Just map value straight ...
)
).Elif(self.e1 < self.e2, # Same sign: Compare exponents, then (maybe) mantissas
# f1 smaller absolute number?
If(self.sign1, # But negative?
NextValue(regs.frd_wrport.dat_w, regs.fs1), # Just map value straight ...
).Else( # Positive
NextValue(regs.frd_wrport.dat_w, regs.fs2), # Just map value straight ...
)
).Elif(self.e2 < self.e1, # f2 smaller absolute number?
If(self.sign1, # But negative?
NextValue(regs.frd_wrport.dat_w, regs.fs2), # Just map value straight ...
).Else( # Positive
NextValue(regs.frd_wrport.dat_w, regs.fs1), # Just map value straight ...
)
).Else( # Equal exponents?
If(self.m1 < self.m2, # Compare mantissas: f1 smaller
If(self.sign1, # But negative?
NextValue(regs.frd_wrport.dat_w, regs.fs1), # Just map value straight ...
).Else( # Positive
NextValue(regs.frd_wrport.dat_w, regs.fs2), # Just map value straight ...
)
).Else( # f2 smaller/equal
If(self.sign1, # But negative?
NextValue(regs.frd_wrport.dat_w, regs.fs2), # Just map value straight ...
).Else( # Positive
NextValue(regs.frd_wrport.dat_w, regs.fs1), # Just map value straight ...
)
)
),
NextValue(self.fwrite, 1), # Write required
NextValue(self.fready, 1), # Indicate ready to main decoder
NextState("FPU_IDLE")
) # End of fmax.s processing
FPU_fsm.act("FCVT_W_S1",
NextState("FCVT_W_S2")
)
# End of fcvt.w.s processing
if __name__ == "__main__":
print("***** Register file is passive ... ;) *****")

@ -348,14 +348,14 @@ class Risq5Decoder(Module):
),
NextValue(fpu_decoder.fwrite, 1), # Trigger write frd
).Elif(regs.f7 == 0x14, # fmin/max
If(regs.f3 == 0x00, # fmin.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Elif(regs.f3 == 0x01, # fmax.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
If(regs.f3 == 0x00, # fmin.s frd, frs1, frs2
NextValue(fpu_decoder.fmin, 1), # Post fmin.s indication
).Elif(regs.f3 == 0x01, # fmax.s frd, frs1, frs2
NextValue(fpu_decoder.fmax, 1), # Post fmax.s indication
)
).Elif(regs.f7 == 0x60, # fcvt.w
If(regs.rs2 == 0x00, # fcvt.w.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
If(regs.rs2 == 0x00, # fcvt.w.s rd, frs1
NextValue(fpu_decoder.fcvt_w_s)
).Else( #regs.rs2 == 0x01, # fcvt.wu.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
)
@ -405,7 +405,7 @@ class Risq5Decoder(Module):
NextValue(self.next, 1), # Indicate ready state to ALU
NextState("DECODE_IDLE") # No write!
).Else(
If(fpu_decoder.fmadd | fpu_decoder.fmsub | fpu_decoder.fnmadd | fpu_decoder.fnmsub | fpu_decoder.fadd | fpu_decoder.fsub | fpu_decoder.fmul | fpu_decoder.fdiv | fpu_decoder.fsqrt, # FPU logic engaging?
If(fpu_decoder.fmadd | fpu_decoder.fmsub | fpu_decoder.fnmadd | fpu_decoder.fnmsub | fpu_decoder.fadd | fpu_decoder.fsub | fpu_decoder.fmul | fpu_decoder.fdiv | fpu_decoder.fsqrt | fpu_decoder.fmin | fpu_decoder.fmax | fpu_decoder.fcvt_w_s, # FPU logic engaging?
NextState("FPU_WAIT") # Reset request within FPU_WAIT!
).Elif(self.div_instruction != 0, # M extension divide instruction?
If(regs.xs2s == 0x0, # RISC-V: Doesn't raise exception div/0!
@ -634,6 +634,9 @@ class Risq5Decoder(Module):
NextValue(fpu_decoder.fmsub, 0),
NextValue(fpu_decoder.fnmsub,0),
NextValue(fpu_decoder.fnmadd, 0),
NextValue(fpu_decoder.fmin, 0),
NextValue(fpu_decoder.fmax, 0),
NextValue(fpu_decoder.fcvt_w_s, 0),
NextState("DECODE_WRITE")
)
)

@ -6,6 +6,8 @@ static void start(void)
lui sp,%hi(0x40192000) # Setup stack pointer \n\
addi sp,sp,%lo(0x40192000) # s.a. \n\
repeat: fadd.s f2,f0,f1 # f2 = f0 + f1 \n\
fmin.s f2,f0,f1 # f2 = min(f0,f1) \n\
fmax.s f2,f0,f1 # f2 = max(f0,f1) \n\
fsub.s f2,f0,f1 # f2 = f0 - f1 \n\
fmul.s f2,f0,f1 # f2 = f0 * f1 \n\
fdiv.s f2,f0,f1 # f2 = f0 / f1 \n\

Loading…
Cancel
Save