From: Luke Kenneth Casson Leighton Date: Sun, 23 Aug 2020 20:39:25 +0000 (+0100) Subject: add algebraic ld tests lwax, lwaux X-Git-Tag: semi_working_ecp5~272^2~2 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=96d7deda2d9392c57464e9e589cb667f1a8cfb85;p=soc.git add algebraic ld tests lwax, lwaux --- diff --git a/src/soc/experiment/compldst_multi.py b/src/soc/experiment/compldst_multi.py index 5109ad25..41739ed4 100644 --- a/src/soc/experiment/compldst_multi.py +++ b/src/soc/experiment/compldst_multi.py @@ -85,6 +85,7 @@ from nmigen.hdl.rec import Record, Layout from nmutil.latch import SRLatch, latchregister from nmutil.byterev import byte_reverse +from nmutil.extend import exts from soc.experiment.compalu_multi import go_record, CompUnitRecord from soc.experiment.l0_cache import PortInterface @@ -301,6 +302,17 @@ class LDSTCompUnit(RegSpecAPI, Elaboratable): p_st_go = Signal(reset_less=True) sync += p_st_go.eq(self.st.go_i) + # decode bits of operand (latched) + oper_r = CompLDSTOpSubset(name="oper_r") # Dest register + comb += op_is_st.eq(oper_r.insn_type == MicrOp.OP_STORE) # ST + comb += op_is_ld.eq(oper_r.insn_type == MicrOp.OP_LOAD) # LD + op_is_update = oper_r.ldst_mode == LDSTMode.update # UPDATE + op_is_cix = oper_r.ldst_mode == LDSTMode.cix # cache-inhibit + comb += self.load_mem_o.eq(op_is_ld & self.go_ad_i) + comb += self.stwd_mem_o.eq(op_is_st & self.go_st_i) + comb += self.ld_o.eq(op_is_ld) + comb += self.st_o.eq(op_is_st) + ########################## # FSM implemented through sequence of latches. approximately this: # - opc_l : opcode @@ -340,7 +352,9 @@ class LDSTCompUnit(RegSpecAPI, Elaboratable): # dest operand latch comb += wri_l.s.eq(issue_i) - sync += wri_l.r.eq(reset_w | Repl(self.done_o, self.n_dst)) + sync += wri_l.r.eq(reset_w | Repl(self.done_o | + (self.pi.busy_o & op_is_update), + self.n_dst)) # update-mode operand latch (EA written to reg 2) sync += upd_l.s.eq(reset_i) @@ -359,7 +373,6 @@ class LDSTCompUnit(RegSpecAPI, Elaboratable): comb += rst_l.r.eq(issue_i) # create a latch/register for the operand - oper_r = CompLDSTOpSubset(name="oper_r") # Dest register with m.If(self.issue_i): sync += oper_r.eq(self.oper_i) with m.If(self.done_o): @@ -398,16 +411,6 @@ class LDSTCompUnit(RegSpecAPI, Elaboratable): comb += alu_o.eq(src1_or_z + src2_or_imm) # actual EA m.d.sync += alu_ok.eq(alu_valid) # keep ack in sync with EA - # decode bits of operand (latched) - comb += op_is_st.eq(oper_r.insn_type == MicrOp.OP_STORE) # ST - comb += op_is_ld.eq(oper_r.insn_type == MicrOp.OP_LOAD) # LD - op_is_update = oper_r.ldst_mode == LDSTMode.update # UPDATE - op_is_cix = oper_r.ldst_mode == LDSTMode.cix # cache-inhibit - comb += self.load_mem_o.eq(op_is_ld & self.go_ad_i) - comb += self.stwd_mem_o.eq(op_is_st & self.go_st_i) - comb += self.ld_o.eq(op_is_ld) - comb += self.st_o.eq(op_is_st) - ############################ # Control Signal calculation @@ -490,13 +493,21 @@ class LDSTCompUnit(RegSpecAPI, Elaboratable): comb += addr_ok.eq(self.pi.addr_ok_o) # no exc, address fine # byte-reverse on LD + revnorev = Signal(64, reset_less=True) with m.If(oper_r.byte_reverse): # byte-reverse the data based on ld/st width (turn it to LE) data_len = oper_r.data_len lddata_r = byte_reverse(m, 'lddata_r', pi.ld.data, data_len) - comb += ldd_o.eq(lddata_r) # put reversed- data out + comb += revnorev.eq(lddata_r) # put reversed- data out with m.Else(): - comb += ldd_o.eq(pi.ld.data) # put data out, straight (as BE) + comb += revnorev.eq(pi.ld.data) # put data out, straight (as BE) + + # then check sign-extend + with m.If(oper_r.sign_extend): + comb += ldd_o.eq(exts(revnorev, 32, 64)) # sign-extend + with m.Else(): + comb += ldd_o.eq(revnorev) + # ld - ld gets latched in via lod_l comb += ld_ok.eq(pi.ld.ok) # ld.ok *closes* (freezes) ld data diff --git a/src/soc/fu/ldst/test/test_pipe_caller.py b/src/soc/fu/ldst/test/test_pipe_caller.py index 31ddfc52..dc32e9d6 100644 --- a/src/soc/fu/ldst/test/test_pipe_caller.py +++ b/src/soc/fu/ldst/test/test_pipe_caller.py @@ -167,3 +167,42 @@ class LDSTTestCase(TestAccumulatorBase): self.add_case(Program(lst, bigendian), initial_regs, initial_mem=initial_mem) + def case_9_load_algebraic_1(self): + lst = ["lwax 3, 4, 2"] + initial_regs = [0] * 32 + initial_regs[1] = 0x5678 + initial_regs[2] = 0x001c + initial_regs[4] = 0x0008 + initial_mem = {0x0000: (0x5432123412345678, 8), + 0x0008: (0xabcdef0187654321, 8), + 0x0020: (0xf000000f0000ffff, 8), + } + self.add_case(Program(lst, bigendian), initial_regs, + initial_mem=initial_mem) + + def case_9_load_algebraic_2(self): + lst = ["lwax 3, 4, 2"] + initial_regs = [0] * 32 + initial_regs[1] = 0x5678 + initial_regs[2] = 0x001c + initial_regs[4] = 0x0008 + initial_mem = {0x0000: (0x5432123412345678, 8), + 0x0008: (0xabcdef0187654321, 8), + 0x0020: (0x7000000f0000ffff, 8), + } + self.add_case(Program(lst, bigendian), initial_regs, + initial_mem=initial_mem) + + def case_9_load_algebraic_3(self): + lst = ["lwaux 3, 4, 2"] + initial_regs = [0] * 32 + initial_regs[1] = 0x5678 + initial_regs[2] = 0x001c + initial_regs[4] = 0x0008 + initial_mem = {0x0000: (0x5432123412345678, 8), + 0x0008: (0xabcdef0187654321, 8), + 0x0020: (0xf000000f0000ffff, 8), + } + self.add_case(Program(lst, bigendian), initial_regs, + initial_mem=initial_mem) + diff --git a/src/soc/litex/florent/sim.py b/src/soc/litex/florent/sim.py index e62f0649..e4a1fbbf 100755 --- a/src/soc/litex/florent/sim.py +++ b/src/soc/litex/florent/sim.py @@ -50,7 +50,7 @@ class LibreSoCSim(SoCSDRAM): # "hello_world/hello_world.bin" ram_fname = "/home/lkcl/src/libresoc/microwatt/" \ "tests/1.bin" - ram_fname = None + #ram_fname = None ram_init = [] if ram_fname: @@ -221,7 +221,7 @@ class LibreSoCSim(SoCSDRAM): ), # also check if this is a "stat" If(dbg_addr == 1, # requested a STAT - Display(" stat: %x", dbg_dout), + #Display(" stat: %x", dbg_dout), If(dbg_dout & 2, # bit 2 of STAT is "stopped" mode dmirunning.eq(1), # continue running dmi_monitor.eq(0), # and stop monitor mode