M extension started, mulhsu sign wrong?

master
kaqu 2 years ago
parent fb96c34d61
commit 4f15e12168
  1. 3
      .vscode/launch.json
  2. 17
      debugger/dbgeval.py
  3. 6
      debugger/risq5dbg.py
  4. 7
      libmodules/core.py
  5. 36
      libmodules/instruction_decode.py
  6. 25
      libmodules/register_file.py
  7. 19
      risq5_wo_vex.py
  8. 47
      software/source/testmultiply.c
  9. 2
      software/testloader.sh

@ -18,8 +18,9 @@
"--with-etherbone",
"--ip-address=192.168.1.20",
"--csr-csv=build/csr.csv", // Only this one for remotetest.py!
"--doc" // Generate documentation files for sphinx
"--doc", // Generate documentation files for sphinx
//"--with-bios-for-none" // Provide ROM & BIOS even w/o CPU (+10 minutes!)
"--isa-extension-m" // Provide RISC-V 'M' instruction set extension
],
//"args": ["--build"],
//"pythonArgs": ["--build", "--uart-name=crossover"],

@ -82,12 +82,23 @@ def disassemble(opcode, pc):
msg = "add {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f7 == 0x20: # sub
msg = "sub {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f7 == 0x01: # mul
msg = "mul {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f3 == 0x01:
msg = "sll {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
if f7 == 0x00: # sll
msg = "sll {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f7 == 0x01: # mulh
msg = "mulh {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f3 == 0x02:
msg = "slt {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
if f7 == 0x00: # slt
msg = "slt {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f7 == 0x01: # mulhsu
msg = "mulhsu {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f3 == 0x03:
msg = "sltu {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
if f7 == 0x00: # sltu
msg = "sltu {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f7 == 0x01: # mulhu
msg = "mulhu {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f3 == 0x04:
msg = "xor {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f3 == 0x05:

@ -57,9 +57,15 @@ def main():
parser.add_argument("--doc", action="store_true", help="not used")
parser.add_argument("--flash", action="store_true", help="not used")
parser.add_argument("--uart-name", default="crossover", help="not used")
parser.add_argument("--isa-extension-m", action="store_true", help="RISC-V extension M")
parser.add_argument("--with-bios-for-none", action="store_true", help="Create ROM w/ BIOS even w/o CPU")
args = parser.parse_args()
risq5dbg(args.csr_csv) # Point of no return ...
if __name__ == "__main__":
a = 0xffffffff
b = 0xffffffff
c = a * b
print(hex(c))
main()

@ -59,7 +59,7 @@ class Risq5Core(Module, AutoCSR, AutoDoc, ModuleDoc):
:b32_FSMs: FSM states
"""
def __init__(self, RAMWaitTime=128, LU_CacheWait=24, L1CacheSize=8, L1Cache=None, LUCacheSize=4, LUCache=None, SU_Unit=None, clint=None):
def __init__(self, RAMWaitTime=128, LU_CacheWait=24, L1CacheSize=8, L1Cache=None, LUCacheSize=4, LUCache=None, SU_Unit=None, clint=None, isa_extensions=0x40000100):
# Inputs
self.b32mode = CSRStorage(32, reset_less=True,
@ -197,7 +197,8 @@ class Risq5Core(Module, AutoCSR, AutoDoc, ModuleDoc):
LU_CacheWait=LU_CacheWait, # May be as short as 24?!
LU_CacheValid=self.LU_CacheValid,
LUCache=LUCache,
SU_Unit=SU_Unit,
SU_Unit=SU_Unit,
isa_extensions=isa_extensions
)
#---------------- L1 cache -------------------------------------------------------------
@ -265,7 +266,7 @@ class Risq5Core(Module, AutoCSR, AutoDoc, ModuleDoc):
self.ALU_loaddelay = Signal(32, reset_less=True) # 1st opcode load delay (TODO: shorter!)
ALU_fsm.act("ALU_INIT", # Initialize static registers (TODO: Run after reset?!)
NextValue(regs.csr[risq5defs.CSR_misa], 0x40000100), # misa: 32 bit/I 'extension'
NextValue(regs.csr[risq5defs.CSR_misa], isa_extensions), # misa: 32 bit RISC-V isa extensions list
# mvendorid, marchid, mimpid, mhartid not specified (zero, acc. to spec.)
NextValue(self.b32status.storage[10], 0), # Edge store reset
NextValue(self.b32status.storage[11], 0), # Edge store reset

@ -22,7 +22,7 @@ class Risq5Decoder(Module):
"""
Risq5 instruction decode phase logic
"""
def __init__(self, regs=None, modereg=None, statusreg=None, L1CacheOffset=None, L1CacheSize=32, LU_CacheWait=24, LU_CacheValid=None, LUCache=None, SU_Unit=None):
def __init__(self, regs=None, modereg=None, statusreg=None, L1CacheOffset=None, L1CacheSize=32, LU_CacheWait=24, LU_CacheValid=None, LUCache=None, SU_Unit=None, isa_extensions=0x40000100):
assert isinstance(regs, Risq5RegisterFile)
self.start = Signal() # Start decoding signal
@ -113,21 +113,35 @@ class Risq5Decoder(Module):
NextState("DECODE_IDLE") # No write!
).Else( # Regular instructions ...
If(regs.op == 0x33, # R-Type
If(regs.f3 == 0x00, # add/sub
If(regs.f3 == 0x00, # add/sub/mul
If(regs.f7 == 0x00, # add rd, rs1, rs2 (all indexes prep'd already!)
NextValue(regs.rd_wrport.dat_w, regs.xs1s + regs.xs2s),
).Else( # sub rd, rs1, rs2
).Elif(regs.f7 == 0x20, # sub rd, rs1, rs2
NextValue(regs.rd_wrport.dat_w, regs.xs1s - regs.xs2s),
).Elif(regs.f7 == 0x01, # (M extension) mul rd, rs1, rs2
NextValue(regs.rd_wrport.dat_w, regs.rd_mul64s[0:31]),
),
).Elif(regs.f3 == 0x01, # sll rd, rs1, rs2
NextValue(regs.rd_wrport.dat_w, regs.xs1u << regs.xs2u[0:5]),
).Elif(regs.f3 == 0x02, # slt rd, rs1, rs2
NextValue(regs.rd_wrport.dat_w, regs.xs1s < regs.xs2s),
).Elif(regs.f3 == 0x03, # sltu rd, rs1, rs2
NextValue(regs.rd_wrport.dat_w, regs.xs1u < regs.xs2u), # TODO: Compare unsigned/signed ok?
).Elif(regs.f3 == 0x04, # xor rd, rs1, rs2
).Elif(regs.f3 == 0x01, # sll/mulh
If(regs.f7 == 0x00, # sll rd, rs1, rs2
NextValue(regs.rd_wrport.dat_w, regs.xs1u << regs.xs2u[0:5]),
).Elif(regs.f7 == 0x01, # mulh rd, rs1, rs2 (both signed)
NextValue(regs.rd_wrport.dat_w, regs.rd_mul64s[32:63]),
)
).Elif(regs.f3 == 0x02, # slt/mulhsu
If(regs.f7 == 0x00, # slt rd, rs1, rs2
NextValue(regs.rd_wrport.dat_w, regs.xs1s < regs.xs2s),
).Elif(regs.f7 == 0x01, # mulhsu rd, rs1, rs2 (rs1 signed, rs2 unsigned)
NextValue(regs.rd_wrport.dat_w, regs.rd_mul64us[32:63]),
)
).Elif(regs.f3 == 0x03, # sltu/mulhu
If(regs.f7 == 0x00, # sltu rd, rs1, rs2
NextValue(regs.rd_wrport.dat_w, regs.xs1u < regs.xs2u), # TODO: Compare unsigned/signed ok?
).Elif(regs.f7 == 0x01, # mulhu rd, rs1, rs2 (both unsigned)
NextValue(regs.rd_wrport.dat_w, regs.rd_mul64u[32:63]),
)
).Elif(regs.f3 == 0x04, # xor rd, rs1, rs2
NextValue(regs.rd_wrport.dat_w, regs.xs1u ^ regs.xs2u),
).Elif(regs.f3 == 0x05, # sra
).Elif(regs.f3 == 0x05, # sra
If(regs.f7[5], # sra rd, rs1, rs2
NextValue(regs.rd_wrport.dat_w, regs.xs1s >> regs.xs2u[0:5]),
).Else( # srl rd, rs1, rs2

@ -73,7 +73,15 @@ class Risq5RegisterFile(Module):
self.xs2u = Signal(32, reset_less=True) # Value of source register #2 (unsigned)
self.xs1s = Signal((32,True), reset_less=True) # Signed register #1
self.xs2s = Signal((32,True), reset_less=True) # Signed register #2
self.xs1_64u = Signal(65, reset_less=True) # Register #1 (M extension)
self.xs2_64u = Signal(65, reset_less=True) # Register #2 (M extension)
self.rd_mul64u = Signal(65, reset_less=True) # M extension multiply result (unsigned)
self.xs1_64s = Signal((64,True), reset_less=True) # Signed register #1 (M extension)
self.xs2_64s = Signal((64,True), reset_less=True) # Signed register #2 (M extension)
self.rd_mul64s = Signal((64,True), reset_less=True) # M extension multiply result (signed)
self.rd_mul64us = Signal((64,True), reset_less=True) # M extension multiply result (mixed)
self.ext_x = Signal(32, reset_less=True) # Value to be read externally
self.LUAddress = Signal(32, reset_less=True) # Load unit address to use
self.SUAddress = Signal(32, reset_less=True) # Store unit address to use
@ -103,14 +111,23 @@ class Risq5RegisterFile(Module):
self.comb += [ # Read from memory
rs1_rdport.adr.eq(self.rs1), # Read source register #1
self.xs1u.eq(rs1_rdport.dat_r), # Unsigned
self.xs1s.eq(rs1_rdport.dat_r), # Signed
self.xs1s.eq(rs1_rdport.dat_r), # Signed
rs2_rdport.adr.eq(self.rs2), # Read source register #2
self.xs2u.eq(rs2_rdport.dat_r), # Unsigned
self.xs2s.eq(rs2_rdport.dat_r), # Signed
self.xs2s.eq(rs2_rdport.dat_r), # Signed
ext_rdport.adr.eq(self.read_ext_index), # Read from external
self.ext_x.eq(ext_rdport.dat_r),
]
self.comb += [ # M extension (TODO: Improve brutal implementation ...)
self.xs1_64u.eq(rs1_rdport.dat_r),
self.xs2_64u.eq(rs2_rdport.dat_r),
self.rd_mul64u.eq(self.xs1_64u * self.xs2_64u), # Continuously calculate 64-bit mul (unsigned)
self.xs1_64s.eq(rs1_rdport.dat_r),
self.xs2_64s.eq(rs2_rdport.dat_r),
self.rd_mul64s.eq(self.xs1_64s * self.xs2_64s), # Continuously calculate 64-bit mul (signed)
self.rd_mul64us.eq(self.xs1_64s * self.xs2_64u) # Continuously calculate 64-bit mul (mixed)
]
# ------------------------- CSRs ----------------------------------------------------
self.csr = Array(Signal(32) for _ in range(15)) # csr[0..12]
# Translate CSR ID codes -> Index

@ -71,6 +71,11 @@ from libmodules.core import Risq5Core
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
# CRG ----------------------------------------------------------------------------------------------
class _CRG(Module):
def __init__(self, platform, sys_clk_freq, use_internal_osc=False, with_usb_pll=False, with_rst=True, sdram_rate="1:1"):
@ -242,6 +247,7 @@ class BaseSoC(SoCCore):
self.add_csr("clint")
# Integrate my RISC-V cpu clone
global isa_extensions
RAMWAITTIME=128 # 32-bit max. for testing ... (TODO: 8-bit 128 seems to work as well)
LUWAITTIME=24
self.submodules.risq5ext = risq5ext = Risq5Core(
@ -252,7 +258,8 @@ class BaseSoC(SoCCore):
LUCacheSize=MAXMEMWORDS,
LUCache=dramtransfer2,
SU_Unit=fpga2dram,
clint = clint
clint=clint,
isa_extensions=isa_extensions # Custom value from global var
)
self.add_csr("risq5ext")
@ -281,10 +288,16 @@ def main():
parser.add_argument("--sdram-rate", default="1:1", help="SDRAM Rate 1:1 Full Rate (default), 1:2 Half Rate")
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("--with-bios-for-none", action="store_true", help="Create ROM w/ BIOS even w/o CPU")
parser.add_argument("--isa-extension-m", action="store_true", help="RISC-V extension M")
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
#assert not (args.with_ethernet and args.with_etherbone)
soc = BaseSoC(board=args.board, revision=args.revision,
with_ethernet = args.with_ethernet,
@ -310,7 +323,7 @@ def main():
args.ecppack_bootaddr = flashbase + flashoffset # 0xC0100000
if not args.with_bios_for_none: # 26.02.21/KQ Added
builder.compile_software = False # Cut off BIOS integration
builder.compile_software = False # Cut off BIOS integration
builder.build(**trellis_argdict(args), run=args.build) # Written here to (local) build tree
if args.doc:

@ -0,0 +1,47 @@
#pragma GCC diagnostic ignored "-Wunused-function"
static void start(void)
{
__asm__ __volatile__ ("\
auipc ra,0 # Store current pc \n\
lui sp,%hi(0x40192000) # Setup stack pointer \n\
addi sp,sp,%lo(0x40192000) # s.a. \n\
csrr t0,misa # Verify ISA: M-extension avail \n\
lui t1,0x40001 # M extension bit \n\
addi t1,t1,0x100 # & I base extension bit \n\
bne t0,t1,not_avail # exit \n\
lui t0,0xFFFFF # 0xffffffff * 0xffffffff \n\
ori t0,t0,-1 # \n\
mv t1,t0 # both are negative \n\
mulh t2,t0,t1 # => FFFFFFFE/00000001 \n\
mulhsu t2,t0,t1 # \n\
mulhu t2,t0,t1 # \n\
mul t2,t0,t1 # \n\
nop # \n\
lui t1,0x0 # 0xffffffff * 2 \n\
addi t1,t1,2 # \n\
mulh t2,t0,t1 # => 0x00000001/FFFFFFFE \n\
mulhsu t2,t0,t1 # \n\
mulhu t2,t0,t1 # \n\
mul t2,t0,t1 # \n\
nop # \n\
li t0,0x123 # x = 123 * 2 \n\
li t1,0x2 # ... \n\
mul t2,t0,t1 # => 246 (F6h) \n\
nop # \n\
li t0,-30 # x = -30 * 5 \n\
li t1,5 # ... \n\
mul t2,t0,t1 # => -150 \n\
nop # \n\
li t0,-30 # x = -30 * -5 \n\
li t1,-5 # ... \n\
mul t2,t0,t1 # => 150 (96h) \n\
not_avail: nop # ... \n\
");
#include "onek_nops.c"
#include "onek_nops.c"
#include "onek_nops.c"
#include "onek_nops.c"
}

@ -27,7 +27,7 @@ export PATH=$PATH:$MY_LOCAL_LITEX_PATH/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x
TRIPLE="riscv64-unknown-elf"
CPU="vexriscv"
CPUFLAGS="-march=rv32i -mabi=ilp32 -D__vexriscv__"
CPUFLAGS="-march=rv32im -mabi=ilp32 -D__vexriscv__"
CPUENDIANNESS="little"
CPU_DIRECTORY="$MY_LOCAL_LITEX_PATH/litex/litex/soc/cores/cpu/vexriscv"
COMPILER_RT_DIRECTORY="$MY_LOCAL_LITEX_PATH/pythondata-software-compiler_rt/pythondata_software_compiler_rt/data"

Loading…
Cancel
Save