From: Luke Kenneth Casson Leighton Date: Thu, 9 May 2019 12:44:39 +0000 (+0100) Subject: get scoreboard reasonably working X-Git-Tag: div_pipeline~2091 X-Git-Url: https://git.libre-soc.org/?p=soc.git;a=commitdiff_plain;h=7b923454817d85424aae7a92c715265b83981aee get scoreboard reasonably working --- diff --git a/src/experiment/compalu.py b/src/experiment/compalu.py index 1c9248fd..f1322a06 100644 --- a/src/experiment/compalu.py +++ b/src/experiment/compalu.py @@ -51,17 +51,26 @@ class ComputationUnitNoDelay(Elaboratable): # outputs m.d.comb += self.busy_o.eq(opc_l.qn) # busy out - m.d.comb += self.req_rel_o.eq(req_l.qn & opc_l.q) # request release out + m.d.comb += self.req_rel_o.eq(req_l.q & opc_l.qn) # request release out with m.If(src_l.q): m.d.comb += self.alu.a.eq(self.src1_i) m.d.comb += self.alu.b.eq(self.src2_i) - + with m.Else(): + m.d.comb += self.alu.a.eq(self.alu.a) + m.d.comb += self.alu.b.eq(self.alu.b) #with m.If(opc_l.q): # XXX operand type in at same time as src1/src2 m.d.comb += self.alu.op.eq(self.oper_i) - with m.If(req_l.qn): - m.d.comb += self.data_o.eq(self.alu.o) + data_o = Signal(self.rwid, reset_less=True) # Dest register + data_r = Signal(self.rwid, reset_less=True) # Dest register + with m.If(req_l.q): + m.d.comb += data_o.eq(self.alu.o) + m.d.sync += data_r.eq(self.alu.o) + with m.Else(): + m.d.comb += data_o.eq(data_r) + with m.If(self.go_wr_i): + m.d.comb += self.data_o.eq(data_o) return m diff --git a/src/experiment/cscore.py b/src/experiment/cscore.py index f6f79d7a..d83a0ad1 100644 --- a/src/experiment/cscore.py +++ b/src/experiment/cscore.py @@ -142,12 +142,12 @@ class Scoreboard(Elaboratable): for i, fu in enumerate(if_l): fn_issue_l.append(fu.issue_i) fn_busy_l.append(fu.busy_o) - m.d.comb += fu.issue_i.eq(issueunit.i.fn_issue_o[i]) + m.d.sync += fu.issue_i.eq(issueunit.i.fn_issue_o[i]) m.d.comb += fu.dest_i.eq(issueunit.i.dest_i) m.d.comb += fu.src1_i.eq(issueunit.i.src1_i) m.d.comb += fu.src2_i.eq(issueunit.i.src2_i) # XXX sync, so as to stop a simulation infinite loop - m.d.sync += issueunit.i.busy_i[i].eq(fu.busy_o) + m.d.comb += issueunit.i.busy_i[i].eq(fu.busy_o) #--------- # connect Function Units @@ -157,10 +157,10 @@ class Scoreboard(Elaboratable): # Group Picker... done manually for now. TODO: cat array of pick sigs m.d.sync += if_l[0].go_rd_i.eq(intpick1.go_rd_o[0]) # add rd - m.d.comb += if_l[0].go_wr_i.eq(intpick1.go_wr_o[0]) # add wr + m.d.sync += if_l[0].go_wr_i.eq(intpick1.go_wr_o[0]) # add wr m.d.sync += if_l[1].go_rd_i.eq(intpick1.go_rd_o[1]) # subtract rd - m.d.comb += if_l[1].go_wr_i.eq(intpick1.go_wr_o[1]) # subtract wr + m.d.sync += if_l[1].go_wr_i.eq(intpick1.go_wr_o[1]) # subtract wr # Connect INT Fn Unit global wr/rd pending for fu in if_l: @@ -179,7 +179,7 @@ class Scoreboard(Elaboratable): #--------- # Connect Register File(s) #--------- - m.d.comb += int_dest.wen.eq(g_int_wr_pend_v.g_pend_o) + m.d.sync += int_dest.wen.eq(g_int_wr_pend_v.g_pend_o) m.d.comb += int_src1.ren.eq(g_int_src1_pend_v.g_pend_o) m.d.comb += int_src2.ren.eq(g_int_src2_pend_v.g_pend_o) @@ -232,9 +232,9 @@ class RegSim: src1 = self.regs[src1] src2 = self.regs[src2] if op == IADD: - val = (src1 + src2) & ((1<<(self.rwidth+1))-1) + val = (src1 + src2) & ((1<<(self.rwidth))-1) elif op == ISUB: - val = (src1 - src2) & ((1<<(self.rwidth+1))-1) + val = (src1 - src2) & ((1<<(self.rwidth))-1) self.regs[dest] = val def setval(self, dest, val): @@ -274,42 +274,61 @@ def print_reg(dut, rnums): def scoreboard_sim(dut, alusim): + yield dut.int_store_i.eq(0) + for i in range(1, dut.n_regs): yield dut.intregs.regs[i].reg.eq(i) alusim.setval(i, i) - yield from int_instr(dut, alusim, IADD, 4, 3, 5) - yield from print_reg(dut, [3,4,5]) - yield - yield from int_instr(dut, alusim, IADD, 5, 2, 5) - yield from print_reg(dut, [3,4,5]) - yield - yield from int_instr(dut, alusim, ISUB, 5, 1, 3) - yield from print_reg(dut, [3,4,5]) - yield - for i in range(len(dut.int_insn_i)): - yield dut.int_insn_i[i].eq(0) - yield from print_reg(dut, [3,4,5]) - yield - yield from print_reg(dut, [3,4,5]) - yield - yield from print_reg(dut, [3,4,5]) - yield + if False: + yield from int_instr(dut, alusim, IADD, 4, 3, 5) + yield from print_reg(dut, [3,4,5]) + yield + yield from int_instr(dut, alusim, IADD, 5, 2, 5) + yield from print_reg(dut, [3,4,5]) + yield + yield from int_instr(dut, alusim, ISUB, 5, 1, 3) + yield from print_reg(dut, [3,4,5]) + yield + for i in range(len(dut.int_insn_i)): + yield dut.int_insn_i[i].eq(0) + yield from print_reg(dut, [3,4,5]) + yield + yield from print_reg(dut, [3,4,5]) + yield + yield from print_reg(dut, [3,4,5]) + yield - yield from alusim.check(dut) + yield from alusim.check(dut) for i in range(100): - src1 = randint(0, dut.n_regs-1) - src2 = randint(0, dut.n_regs-1) - dest = randint(1, dut.n_regs-1) + src1 = randint(1, dut.n_regs-1) + src2 = randint(1, dut.n_regs-1) + while True: + dest = randint(1, dut.n_regs-1) + break + if dest not in [src1, src2]: + break + #src1 = 7 + #src2 = 7 + dest = src2 + op = randint(0, 1) print ("random %d: %d %d %d %d\n" % (i, op, src1, src2, dest)) yield from int_instr(dut, alusim, op, src1, src2, dest) + yield from print_reg(dut, [3,4,5]) + yield + yield from print_reg(dut, [3,4,5]) + for i in range(len(dut.int_insn_i)): + yield dut.int_insn_i[i].eq(0) + yield yield - for i in range(len(dut.int_insn_i)): - yield dut.int_insn_i[i].eq(0) + yield + yield from print_reg(dut, [3,4,5]) + yield + yield from print_reg(dut, [3,4,5]) yield yield yield @@ -317,6 +336,18 @@ def scoreboard_sim(dut, alusim): yield from alusim.check(dut) +def explore_groups(dut): + from nmigen.hdl.ir import Fragment + from nmigen.hdl.xfrm import LHSGroupAnalyzer + + fragment = dut.elaborate(platform=None) + fr = Fragment.get(fragment, platform=None) + + groups = LHSGroupAnalyzer()(fragment._statements) + + print (groups) + + def test_scoreboard(): dut = Scoreboard(32, 8) alusim = RegSim(32, 8) diff --git a/src/scoreboard/fn_unit.py b/src/scoreboard/fn_unit.py index a21911d3..220eee7b 100644 --- a/src/scoreboard/fn_unit.py +++ b/src/scoreboard/fn_unit.py @@ -160,7 +160,7 @@ class FnUnit(Elaboratable): wo = Signal(reset_less=True) m.d.comb += g_wr_v.eq(g_pend_i & xx_pend_o) m.d.comb += g_wr.eq(~g_wr_v.bool()) - m.d.comb += wo.eq(g_wr & rd_l.q & self.req_rel_i & shadown) + m.d.comb += wo.eq(g_wr & rd_l.qn & self.req_rel_i & shadown) m.d.comb += writable_o.eq(wo) return m