FPU decoder started ...

master
kaqu 2 years ago
parent 3a600427f9
commit 5ff94901af
  1. 71
      libmodules/instruction_decode.py
  2. 48
      libmodules/register_file.py
  3. 15
      risq5_fpu.py

@ -210,7 +210,7 @@ class Risq5Decoder(Module):
NextValue(SU_Unit.bData, regs.xs2u), # Pick actual value to store (from rs2) & load SU
NextValue(self.SUByteID, 6), # Type: Word
NextValue(self.SUStore, 1), # Enforce store unit engagement (for now: allways!)
)
)
).Elif(regs.op == 0x03, # I-Type (1)
If(regs.f3[0:2] == 0x00, # lb/lbu rd, imm_offset(xs1)
NextValue(regs.LUAddress, regs.xs1u + regs.imm_i), # Calculate memory address: [rs1]+offset
@ -297,8 +297,75 @@ class Risq5Decoder(Module):
NextValue(L1CacheOffset, L1CacheOffset + (self.IHelper >> 2) - 1)
),
#)
#------------------- F-Extension ----------------------------------------------------
).Elif(regs.op == 0x07, # I-Type: flw
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Elif(regs.op == 0x27, # S-Type: fsw
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Elif(regs.op == 0x43, # R4-Type: fmadd.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Elif(regs.op == 0x47, # R4-Type: fmsub.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Elif(regs.op == 0x4B, # R4-Type: fnmsub.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Elif(regs.op == 0x4F, # R4-Type: fnmadd.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Elif(regs.op == 0x53, # R-Type
If(regs.f7 == 0x00, # fadd.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Elif(regs.f7 == 0x04, # fsub.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Elif(regs.f7 == 0x08, # fmul.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Elif(regs.f7 == 0x0C, # fdiv.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Elif(regs.f7 == 0x2C, # fsqrt.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Elif(regs.f7 == 0x10, # sign injection
If(regs.f3 == 0x00, # fsgnj.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Elif(regs.f3 == 0x01, # fsgnjn.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Else( #regs.f3 == 0x02, # fsgnjx.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
)
).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
)
).Elif(regs.f7 == 0x60, # fcvt.w
If(regs.rs2 == 0x00, # fcvt.w.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Else( #regs.rs2 == 0x01, # fcvt.wu.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
)
).Elif(regs.f7 == 0x70, # fmv/fclass
If(regs.f3 == 0x00, # fmv.x.w
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Else( #regs.f3 == 0x01, # fclass.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
)
).Elif(regs.f7 == 0x50, # compares
If(regs.f3 == 0x02, # feq.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Elif(regs.f3 == 0x01, # flt.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Else( #regs.f3 == 0x00, # fle.s
NextValue(self.DECODE_state, 0x0F), # Dummy action
)
).Elif(regs.f7 == 0x68, # fcvt.s
If(regs.rs2 == 0x00, # fcvt.s.w
NextValue(self.DECODE_state, 0x0F), # Dummy action
).Else( #regs.rs2 == 0x01, # fcvt.s.wu
NextValue(self.DECODE_state, 0x0F), # Dummy action
)
).Else( # regs.f7 == 0x78, # fmv.w.x
NextValue(self.DECODE_state, 0x0F), # Dummy action
)
# TODO: Maybe RISC-V extensions ...
# TODO: Maybe RISC-V extensions ...
).Else( # Undecodeable operations
# Test for illegal instruction -> Illegal instruction trap/halt

@ -16,7 +16,7 @@ from migen.fhdl.specials import Memory
from litex.soc.interconnect.csr import *
from litex.soc.integration.doc import AutoDoc, ModuleDoc
import libmodules.risq5defs as risq5defs # CSR register defs.
import libmodules.risq5defs as risq5defs # CSR register defs.
class Risq5RegisterFile(Module):
"""
@ -120,6 +120,52 @@ class Risq5RegisterFile(Module):
self.rd_mul64su.eq(self.xs1s * self.xs2u),
]
# -------------------------- F extension ---------------------------------------------------
# Risq5 floating point unit (FPU extension)
# Instruction decode, 32 bit opcode parts --------------------------------------------------
self.frd = Signal(5, reset_less=True) # [11:7] Destination register
#self.rm = Signal(3, reset_less=True) # [14:12] Instruction type modifier
self.frs1 = Signal(5, reset_less=True) # [19:15] source register #1
self.frs2 = Signal(5, reset_less=True) # [24:20] source register #2
self.frs3 = Signal(5, reset_less=True) # [31:27] Instruction type modifier
self.fread_ext_index = Signal(5, reset_less=True) # External read access (index)
self.fwrite_ext_index = Signal(5, reset_less=True) # External write access (index)
fregs = Memory(WORDSIZE, 32) # 32-bit, 32 elements -> f0 .. f31
self.specials += fregs
# rd -> index register to write
self.frd_wrport = fregs.get_port(write_capable=True) # Internal register file access
self.specials += self.frd_wrport
self.fext_wrport = fregs.get_port(write_capable=True)
self.specials += self.fext_wrport
self.comb += [ # Write to memory
self.frd_wrport.adr.eq(self.frd), # Index local memory for WRITE (destination register)
#rd_wrport.dat_w.eq(<value>),
#rd_wrport.we.eq(1) # Write
self.fext_wrport.adr.eq(self.write_ext_index), # Index local memory for WRITE (destination register)
#ext_wrport.dat_w.eq(<value>),
#ext_wrport.we.eq(1) # Write
]
# rs1, rs2 -> index registers to read
frs1_rdport = fregs.get_port() # use .dat_r to pick up data
self.specials += frs1_rdport
frs2_rdport = fregs.get_port()
self.specials += frs2_rdport
frs3_rdport = fregs.get_port()
self.specials += frs3_rdport
fext_rdport = fregs.get_port() # External read port
self.specials += fext_rdport
self.comb += [ # Read from memory
frs1_rdport.adr.eq(self.frs1), # Read source register #1
self.frs1.eq(frs1_rdport.dat_r),
frs2_rdport.adr.eq(self.frs2), # Read source register #2
self.frs2.eq(frs2_rdport.dat_r),
frs3_rdport.adr.eq(self.frs3), # Read source register #3
self.frs3.eq(frs3_rdport.dat_r),
fext_rdport.adr.eq(self.fread_ext_index), # Read from external
self.fwrite_ext_index.eq(fext_rdport.dat_r),
]
# ------------------------- CSRs ----------------------------------------------------
self.csr = Array(Signal(32) for _ in range(15)) # csr[0..12]
# Translate CSR ID codes -> Index

@ -73,8 +73,9 @@ from helpers.prepare_firmware import copyjob
# ISA extensions info: --ZY XWVU TSRQ PONM LKJI HGFE DCBA
# I (base integer) 0000 0000 0000 0000 0001 0000 0000
# IM (+ multiply) 0000 0000 0000 0001 0001 0000 0000
isa_extensions = 0x40000100 # Base integer ISA by default
# IM (+ multiply) 0000 0000 0000 0001 0001 0000 0000
# IMF (+ float math) 0000 0000 0000 0001 0001 0010 0000
isa_extensions = 0x40000120 # Base integer ISA by default
# CRG ----------------------------------------------------------------------------------------------
class _CRG(Module):
@ -289,14 +290,17 @@ def main():
parser.add_argument("--csr_csv", default="build/csr.csv", help="CSR list location")
parser.add_argument("--doc", action="store_true", help="Create doc files for sphinx generator")
parser.add_argument("--isa-extension-m", action="store_true", help="RISC-V extension M")
parser.add_argument("--isa-extension-f", action="store_true", help="RISC-V extension F")
parser.add_argument("--with-bios-for-none", action="store_true", help="Create ROM w/ BIOS even w/o CPU")
parser.add_argument("--flash", action="store_true", help="Load bitstream to flash")
args = parser.parse_args()
# Custom attribute addition
if args.isa_extension_m:
global isa_extensions # RISC-V extensions
isa_extensions |= 0x00001000 # M extension
global isa_extensions # RISC-V extensions
if args.isa_extension_m:
isa_extensions |= 0x00001000 # M extension
if args.isa_extension_f:
isa_extensions |= 0x00000020 # F extension
#assert not (args.with_ethernet and args.with_etherbone)
soc = BaseSoC(board=args.board, revision=args.revision,
@ -351,4 +355,3 @@ if __name__ == "__main__":
copyjob() # Create backup if nec. & move our firmware to the correct location
main() # Create FPGA & load/flash
print("Time used: {0} min.".format(int((time.time() - starttime)/60.0)))
Loading…
Cancel
Save