fclass.s ok

master
kaqu 2 years ago
parent 64f19e9564
commit b48e50305a
  1. 3
      debugger/dbgeval.py
  2. 74
      libmodules/fpu_decode.py
  3. 7
      libmodules/instruction_decode.py
  4. 24
      software/source/flwstw.c

@ -11,6 +11,7 @@ x_description = [ # Pseudo reg. naming ...
" a6", " a7", " s2", " s3", " s4", " s5", " s6", " s7",
" s8", " s9", " s10", " s11", " t3", " t4", " t5", " t6"
]
f_description = [ # Pseudo reg. naming ...
" ft0", " ft1", " ft2", " ft3", " ft4", " ft5", " ft6", " ft7",
" fs0", " fs1", " fa0", " fa1", " fa2", " fa3", " fa4", " fa5",
@ -278,7 +279,7 @@ def disassemble(opcode, pc):
if f3 == 0x00:
msg = "fmv.x.s {0},{1}".format(x_description[rd], f_description[rs1])
else:
msg = "fclass.s"
msg = "fclass.s {0},{1}".format(x_description[rd], f_description[rs1])
else: # Last operation for op==0x53 ...
msg = "fmv.s.x {0},{1}".format(f_description[rd], x_description[rs1])
else:

@ -43,6 +43,7 @@ class Risq5FPUDecoder(Module):
self.fcvt_s_w = Signal()
self.fcvt_s_wu = Signal()
self.flt = Signal()
self.fclass = Signal()
self.fready = Signal() # Indicate ready
self.fwrite = Signal() # F-Extension: Do a write to a float register
@ -97,15 +98,23 @@ class Risq5FPUDecoder(Module):
).Else( # Multiplication variants
NextState("FMUL1"),
)
).Elif((self.fsqrt | self.fcvt_w_s | self.fcvt_wu_s) & ~self.fready, # Trigger set & ready flag reset externally!
NextValue(self.sign1, regs.fs1[31]),
NextValue(self.e1, regs.fs1[23:31] - 127),
).Elif((self.fsqrt | self.fcvt_w_s | self.fcvt_wu_s | self.fclass) & ~self.fready, # Trigger set & ready flag reset externally!
NextValue(self.sign1, regs.fs1[31]),
If(self.fclass,
NextValue(self.e1, regs.fs1[23:31]), # Native unsigned
).Else( # Sqrt & conversion to int.
NextValue(self.e1, regs.fs1[23:31] - 127),
),
If(self.fsqrt,
NextValue(self.m1, Cat(regs.fs1[0:23], 1, 0)), # | 0x00800000
NextState("FSQRT1"),
).Else( # Conversion to integer ...
).Else( # Conversion to integer or fclass.s ...
NextValue(self.m1, Cat(regs.fs1[0:23], 0, 0)), # W/o 0x00800000 !
NextState("FCVT_W_S1")
If(self.fclass,
NextState("FCLASS1")
).Else(
NextState("FCVT_W_S1")
)
)
).Elif((self.fcvt_s_w | self.fcvt_s_wu) & ~self.fready, # Trigger set & ready flag reset externally!
If(regs.xs1s[31] & self.fcvt_s_w, # Invert negative
@ -742,7 +751,60 @@ class Risq5FPUDecoder(Module):
NextValue(writepost, 1), # Write required (but integer register)
NextValue(self.fready, 1), # Indicate ready to main decoder
NextState("FPU_IDLE")
)
) # End of flt.s processing
FPU_fsm.act("FCLASS1",
If(self.sign1, # Negative number
If(self.e1 == -1, # 255 -> -1 / Infinity or NaN
If(self.m1 == 0,
NextValue(regs.rd_wrport.dat_w, 1), # Bit[0]: -infinity
).Else( # NaN
# Ignored for now: if fcsr & OV/UV/ZR etc. flags 0x100 (signalling NaN)
If(self.m1 != 0x400000, # Non-canonical NaN
NextValue(regs.rd_wrport.dat_w, 0x100), # Signalling NaN
).Else( # Canonical NaN
NextValue(regs.rd_wrport.dat_w, 0x200), # Quit NaN
)
)
).Else( # Neither infinity nor NaN ...
If(self.e1 > 0, # Normal negative number
NextValue(regs.rd_wrport.dat_w, 2), # Bit[1]: -nn
).Else( # e1 == 0
If((self.e1 == 0) & (self.m1 != 0), # Subnormal negative number
NextValue(regs.rd_wrport.dat_w, 4), # Bit[2]: -dn
).Else( # Negative zero
NextValue(regs.rd_wrport.dat_w, 8), # Bit[3]: -0
)
)
)
).Else( # Positive number
If(self.e1 == -1, # Infinity or NaN
If(self.m1 == 0,
NextValue(regs.rd_wrport.dat_w, 0x80), # Bit[7]: infinity
).Else( # NaN
# Ignored for now: if fcsr & OV/UV/ZR etc. flags 0x100 (signalling NaN)
If(self.m1 != 0x400000, # Non-canonical NaN
NextValue(regs.rd_wrport.dat_w, 0x100), # Signalling NaN
).Else( # Canonical NaN
NextValue(regs.rd_wrport.dat_w, 0x200), # Quit NaN
)
)
).Else( # Neither infinity nor NaN ...
If(self.e1 > 0, # Normal positive number
NextValue(regs.rd_wrport.dat_w, 0x40), # Bit[6]: nn
).Else( # e1 == 0
If((self.e1 == 0) & (self.m1 != 0), # Subnormal positive number
NextValue(regs.rd_wrport.dat_w, 0x20), # Bit[5]: dn
).Else( # Positive zero
NextValue(regs.rd_wrport.dat_w, 0x10), # Bit[4]: +0
)
)
)
),
NextValue(writepost, 1), # Write required (but integer register)
NextValue(self.fready, 1), # Indicate ready to main decoder
NextState("FPU_IDLE")
) # End of fclass.s processing
if __name__ == "__main__":

@ -364,8 +364,8 @@ class Risq5Decoder(Module):
If(regs.f3 == 0x00, # fmv.x.s rd, frs1 (f-reg -> x-reg) OK!
NextValue(regs.rd_wrport.dat_w, regs.fs1),
NextValue(writepost, 1), # Trigger write rd (x-reg)
).Else( #regs.f3 == 0x01, # fclass.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Else( #regs.f3 == 0x01, # fclass.s rd, frs1
NextValue(fpu_decoder.fclass, 1)
)
).Elif(regs.f7 == 0x50, # compares
If(regs.f3 == 0x02, # feq.s rd, frs1, frs2
@ -415,7 +415,7 @@ class Risq5Decoder(Module):
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_decoder.fcvt_wu_s | fpu_decoder.fcvt_s_w | fpu_decoder.fcvt_s_wu
| fpu_decoder.flt, # FPU logic engaging?
| fpu_decoder.flt | fpu_decoder.fclass, # 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!
@ -651,6 +651,7 @@ class Risq5Decoder(Module):
NextValue(fpu_decoder.fcvt_s_w, 0),
NextValue(fpu_decoder.fcvt_s_wu, 0),
NextValue(fpu_decoder.flt, 0),
NextValue(fpu_decoder.fclass, 0),
NextState("DECODE_WRITE")
)
)

@ -5,7 +5,28 @@ static void start(void)
auipc ra,0 # Store current pc \n\
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\
repeat: lui x3,%hi(0xFF800000) # -INF \n\
fmv.s.x f3,x3 # x3 -> f3 \n\
fclass.s x3,f3 # x3 = fclass(f3) \n\
lui x3,%hi(0x80000100) # -dn \n\
addi x3,x3,%lo(0x80000100) # \n\
fmv.s.x f3,x3 # x3 -> f3 \n\
fclass.s x3,f3 # x3 = fclass(f3) \n\
lui x3,%hi(0x00000100) # dn \n\
addi x3,x3,%lo(0x00000100) # \n\
fmv.s.x f3,x3 # x3 -> f3 \n\
fclass.s x3,f3 # x3 = fclass(f3) \n\
lui x3,%hi(0x7F800000) # INF \n\
fmv.s.x f3,x3 # x3 -> f3 \n\
fclass.s x3,f3 # x3 = fclass(f3) \n\
lui x3,%hi(0x7F800001) # NaN Non-canonical \n\
addi x3,x3,%lo(0x7F800001) \n\
fmv.s.x f3,x3 # x3 -> f3 \n\
fclass.s x3,f3 # x3 = fclass(f3) \n\
lui x3,%hi(0x7FC00000) # NaN Canonical \n\
fmv.s.x f3,x3 # x3 -> f3 \n\
fclass.s x3,f3 # x3 = fclass(f3) \n\
j repeat # Loop ... \n\
feq.s x3,f0,f1 # x3 = (f0 == f1) \n\
flt.s x3,f0,f1 # x3 = (f0 < f1) \n\
fle.s x3,f0,f1 # x3 = (f0 < f1) \n\
@ -18,6 +39,7 @@ repeat: fadd.s f2,f0,f1 # f2 = f0 + f1 \n\
j repeat # Loop ... \n\
fmin.s f2,f0,f1 # f2 = min(f0,f1) \n\
fmax.s f2,f0,f1 # f2 = max(f0,f1) \n\
fadd.s f2,f0,f1 # f2 = 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