fcvt.w.s & fcvt.wu.s done

master
kaqu 1 year ago
parent 967388bd40
commit 8d0d848861
  1. 50
      libmodules/fpu_decode.py
  2. 7
      libmodules/instruction_decode.py
  3. 1
      software/source/flwstw.c

@ -39,6 +39,7 @@ class Risq5FPUDecoder(Module):
self.fmin = Signal()
self.fmax = Signal()
self.fcvt_w_s = Signal()
self.fcvt_wu_s = Signal()
self.fready = Signal() # Indicate ready
self.fwrite = Signal() # F-Extension: Do a write to a float register
@ -90,7 +91,7 @@ class Risq5FPUDecoder(Module):
).Else( # Multiplication variants
NextState("FMUL1"),
)
).Elif((self.fsqrt | self.fcvt_w_s) & ~self.fready, # Trigger set & ready flag reset externally!
).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),
If(self.fsqrt,
@ -557,13 +558,24 @@ class Risq5FPUDecoder(Module):
) # End of fmax.s processing
FPU_fsm.act("FCVT_W_S1",
If((self.e1 < 0) & self.fcvt_w_s, # Nothing to do ...
NextValue(regs.rd_wrport.dat_w, 0), # Just return zero!
If(self.e1 < 0, # 0..1 range special treatment
If((regs.fcs[5:8] == 0x0) | (regs.fcs[5:8] == 0x4), # rte/Round to nearest, ties to even or rmm/Round to nearest, ties to max magnitude
If(self.e1 < -1,
NextValue(regs.rd_wrport.dat_w, 0), # Just return zero!
).Else(
NextValue(regs.rd_wrport.dat_w, 1),
)
).Elif((regs.fcs[5:8] == 0x2) | (regs.fcs[5:8] == 0x1), # rdn/Round down towards -inf or rtz/Round to zero => Trunc (do nothing)
NextValue(regs.rd_wrport.dat_w, 0), # Just return zero!
).Elif(regs.fcs[5:8] == 0x3, # rup/Round up towards +inf
NextValue(regs.rd_wrport.dat_w, 1),
),
NextValue(writepost, 1), # Write required (but integer register)
NextValue(self.fready, 1), # Indicate ready to main decoder
NextState("FPU_IDLE")
).Else( # Relevant portion existing ...
NextValue(self.s32, 1), # Starter/initial value req.
NextValue(self.lm3, 1), # Just track for unsigned ...
NextState("FCVT_W_S2")
)
)
@ -571,9 +583,11 @@ class Risq5FPUDecoder(Module):
# 1. De-Normalization: Positive exponent dictates pre-decimal point value 1nnnn.xxx (from 1.xxx)
If(self.e1 > 0,
If(self.m1[22], # & 0x400000
NextValue(self.s32, (self.s32 << 1) | 1)
NextValue(self.s32, (self.s32 << 1) | 1),
NextValue(self.lm3, (self.lm3 << 1) | 1),
).Else(
NextValue(self.s32, self.s32 << 1),
NextValue(self.lm3, self.lm3 << 1),
),
NextValue(self.e1, self.e1 - 1),
NextValue(self.m1, self.m1 << 1)
@ -586,34 +600,40 @@ class Risq5FPUDecoder(Module):
If(regs.fcs[5:8] == 0x0, # rte/Round to nearest, ties to even
If(self.m1 == 0x400000, # Excactly 0.5?
If(self.s32[0], # NOT even number?
NextValue(self.s32, self.s32 + 1) # Tie to even!
NextValue(self.s32, self.s32 + 1), # Tie to even!
NextValue(self.lm3, self.lm3 + 1), # Just track value for unsigned result ...
)
).Else(
If(self.m1 > 0x400000, # >= 0.5
NextValue(self.s32, self.s32 + 1) # Round upward
NextValue(self.s32, self.s32 + 1), # Round upward
NextValue(self.lm3, self.lm3 + 1), # Just track value for unsigned result ...
)
# Else (< 0.5): Round downward -> trunc (do nothing)
)
).Elif(regs.fcs[5:8] == 0x2, # rdn/Round down towards -inf
If(self.m1 > 0, # There is a rest ...
If(self.sign1, # Negative: Add to next integer
NextValue(self.s32, self.s32 + 1) # Round upward
NextValue(self.s32, self.s32 + 1), # Round upward
NextValue(self.lm3, self.lm3 + 1), # Just track valule for unsigned result ...
)
# Positive to -inf: Just cut-off!
)
).Elif(regs.fcs[5:8] == 0x3, # rup/Round up towards +inf
If(self.m1 > 0, # There is a rest ...
If(self.sign1, # Positive: Add to next integer
NextValue(self.s32, self.s32 + 1) # Round upward
NextValue(self.s32, self.s32 + 1), # Round upward
NextValue(self.lm3, self.lm3 + 1), # Just track valule for unsigned result ...
)
# Negative to +inf: Just cut-off!
)
).Elif(regs.fcs[5:8] == 0x4, # rmm/Round to nearest, ties to max magnitude
If(self.m1 == 0x400000, # Excactly 0.5?
NextValue(self.s32, self.s32 + 1) # Tie to inf (no matter what sign?!)
NextValue(self.s32, self.s32 + 1), # Tie to inf (no matter what sign?!)
NextValue(self.lm3, self.lm3 + 1), # Just track valule for unsigned result ...
).Else(
If(self.m1 > 0x400000, # >= 0.5
NextValue(self.s32, self.s32 + 1) # Round upward
NextValue(self.s32, self.s32 + 1), # Round upward
NextValue(self.lm3, self.lm3 + 1), # Just track valule for unsigned result ...
)
# Else (< 0.5): Round downward -> trunc (do nothing)
)
@ -622,10 +642,12 @@ class Risq5FPUDecoder(Module):
NextState("FCVT_W_S4")
)
FPU_fsm.act("FCVT_W_S4",
If(self.sign1,
NextValue(regs.rd_wrport.dat_w, Cat(self.s32[0:31], 1)), # Adjust sign
).Else(
NextValue(regs.rd_wrport.dat_w, self.s32), # Just map value straight ...
If(self.sign1 & self.fcvt_w_s,
NextValue(regs.rd_wrport.dat_w, -self.s32), # Adjust sign
).Elif(self.fcvt_wu_s, # Unsigned result?
NextValue(regs.rd_wrport.dat_w, self.lm3[0:32]), # Just map value straight ...
).Else( # >0 signed
NextValue(regs.rd_wrport.dat_w, self.s32 & 0x7FFFFFFF), # Just map value straight ...
),
NextValue(writepost, 1), # Write to rd/integer register required!
NextValue(self.fready, 1), # Indicate ready to main decoder

@ -357,8 +357,8 @@ class Risq5Decoder(Module):
).Elif(regs.f7 == 0x60, # fcvt.w
If(regs.rs2 == 0x00, # fcvt.w.s rd, frs1
NextValue(fpu_decoder.fcvt_w_s, 1)
).Else( #regs.rs2 == 0x01, # fcvt.wu.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Else( #regs.rs2 == 0x01, # fcvt.wu.s rd, frs1
NextValue(fpu_decoder.fcvt_wu_s, 1)
)
).Elif(regs.f7 == 0x70, # fmv/fclass
If(regs.f3 == 0x00, # fmv.x.s rd, frs1 (f-reg -> x-reg) OK!
@ -406,7 +406,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_decoder.fmin | fpu_decoder.fmax | fpu_decoder.fcvt_w_s, # 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_decoder.fcvt_wu_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!
@ -638,6 +638,7 @@ class Risq5Decoder(Module):
NextValue(fpu_decoder.fmin, 0),
NextValue(fpu_decoder.fmax, 0),
NextValue(fpu_decoder.fcvt_w_s, 0),
NextValue(fpu_decoder.fcvt_wu_s, 0),
NextState("DECODE_WRITE")
)
)

@ -7,6 +7,7 @@ static void start(void)
addi sp,sp,%lo(0x40192000) # s.a. \n\
repeat: fadd.s f2,f0,f1 # f2 = f0 + f1 \n\
fcvt.w.s x3,f3 # x3 = int(f3) \n\
fcvt.wu.s x3,f3 # x3 = uint(f3) \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\

Loading…
Cancel
Save