fcvt.w.s & fcvt.wu.s done
parent
967388bd40
commit
8d0d848861
|
@ -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…
Reference in New Issue