M-extension: mul/mulh/mulhu/mulhsu ok!

master
kaqu 2 years ago
parent 4f15e12168
commit 01d3e372a5
  1. 16
      debugger/risq5dbg.py
  2. 10
      libmodules/instruction_decode.py
  3. 24
      libmodules/register_file.py
  4. 18
      software/source/testmultiply.c

@ -24,14 +24,14 @@ def risq5dbg(csr_csv):
wb.open() # To remote client ... (requires server up & running, s.a.)
print("RISQ5 debugger started ...")
#print("Entering single step mode")
print("Entering single step mode")
wb.regs.risq5ext_b32mode.write(1) # Enable run, L1 cache will load (but will halt before 1. instruction!)
#print("PC adjusted to 0x40190078")
#wb.regs.risq5ext_b32_next_pc.write(0x40190078) # Provide a new PC address
#mode = wb.regs.risq5ext_b32mode.read() # Pick up current mode setting
#wb.regs.risq5ext_b32mode.write(mode | 16) # Adjust PC, will load L1 2nd time now
#wb.regs.risq5ext_b1_wb_reg_we.write(0) # Reset write requests (if any pending)
print("PC adjusted to 0x40190000")
wb.regs.risq5ext_b32_next_pc.write(0x40190000) # Provide a new PC address
mode = wb.regs.risq5ext_b32mode.read() # Pick up current mode setting
wb.regs.risq5ext_b32mode.write(mode | 16) # Adjust PC, will load L1 2nd time now
wb.regs.risq5ext_b1_wb_reg_we.write(0) # Reset write requests (if any pending)
run_Qt5_GUI(wb) # Now switch to GUI (will never return!)
@ -64,8 +64,4 @@ def main():
risq5dbg(args.csr_csv) # Point of no return ...
if __name__ == "__main__":
a = 0xffffffff
b = 0xffffffff
c = a * b
print(hex(c))
main()

@ -119,25 +119,25 @@ class Risq5Decoder(Module):
).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]),
NextValue(regs.rd_wrport.dat_w, regs.rd_mul64s[0:32]),
),
).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]),
NextValue(regs.rd_wrport.dat_w, regs.rd_mul64s[32:64]),
)
).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.f7 == 0x01, # mulhsu rd, rs1, rs2 (rs1 signed, rs2 unsigned)
NextValue(regs.rd_wrport.dat_w, regs.rd_mul64su[32:64]),
)
).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]),
NextValue(regs.rd_wrport.dat_w, regs.rd_mul64u[32:64]),
)
).Elif(regs.f3 == 0x04, # xor rd, rs1, rs2
NextValue(regs.rd_wrport.dat_w, regs.xs1u ^ regs.xs2u),

@ -73,14 +73,10 @@ 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.rd_mul64u = Signal(64, reset_less=True) # M extension multiply result (unsigned)
self.rd_mul64s = Signal((64,True), reset_less=True) # M extension multiply result (signed)
self.rd_mul64su = Signal((64,True), reset_less=True) # M extension multiply result (signed x unsigned)
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
@ -118,14 +114,10 @@ class Risq5RegisterFile(Module):
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)
self.comb += [ # M extension (TODO: Improve brutal implementation ...)
self.rd_mul64s.eq(self.xs1s * self.xs2s),
self.rd_mul64u.eq(self.xs1u * self.xs2u),
self.rd_mul64su.eq(self.xs1s * self.xs2u),
]
# ------------------------- CSRs ----------------------------------------------------

@ -12,18 +12,12 @@ static void start(void)
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\
repeat: mulh t2,t0,t1 # => 0xFFFFFFFE/00000001 \n\
mulhu t2,t0,t1 # \n\
mulhsu t2,t0,t1 # \n\
mul t3,t0,t1 # \n\
beq t3,t3,repeat # \n\
nop # \n\
li t0,0x123 # x = 123 * 2 \n\
li t1,0x2 # ... \n\
mul t2,t0,t1 # => 246 (F6h) \n\

Loading…
Cancel
Save