From ae8378bb6ea79d0623a5eca28df4962e356df7b6 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Mon, 6 May 2019 15:06:39 +0100 Subject: [PATCH] add issue unit --- src/scoreboard/issue_unit.py | 110 +++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 src/scoreboard/issue_unit.py diff --git a/src/scoreboard/issue_unit.py b/src/scoreboard/issue_unit.py new file mode 100644 index 00000000..3506b9e3 --- /dev/null +++ b/src/scoreboard/issue_unit.py @@ -0,0 +1,110 @@ +from nmigen.compat.sim import run_simulation +from nmigen.cli import verilog, rtlil +from nmigen import Module, Signal, Cat, Array, Const, Record, Elaboratable +from nmutil.latch import SRLatch +from nmigen.lib.coding import Decoder + +from shadow_fn import ShadowFn + + +class IssueUnit(Elaboratable): + """ implements 11.4.14 issue unit, p50 + + Inputs + + * :wid: register file width + """ + def __init__(self, wid, n_insns): + self.reg_width = wid + self.n_insns = n_insns + + # inputs + self.store_i = Signal(reset_less=True) # instruction is a store + self.dest_i = Signal(max=wid, reset_less=True) # Dest R# in + self.src1_i = Signal(max=wid, reset_less=True) # oper1 R# in + self.src2_i = Signal(max=wid, reset_less=True) # oper2 R# in + + self.g_wr_pend_i = Signal(wid, reset_less=True) # write pending vector + + self.insn_i = Array(Signal(reset_less=True, name="insn_i") \ + for i in range(n_insns)) + self.busy_i = Array(Signal(reset_less=True, name="busy_i") \ + for i in range(n_insns)) + + # outputs + self.fn_issue_o = Array(Signal(reset_less=True, name="fn_issue_o") \ + for i in range(n_insns)) + self.g_issue_o = Signal(reset_less=True) + + def elaborate(self, platform): + m = Module() + m.submodules.dest_d = dest_d = Decoder(self.reg_width) + + # temporaries + waw_stall = Signal(reset_less=True) + fu_stall = Signal(reset_less=True) + pend = Signal(self.reg_width, reset_less=True) + + # dest decoder: write-pending + m.d.comb += dest_d.i.eq(self.dest_i) + m.d.comb += dest_d.n.eq(~self.store_i) # decode is inverted + m.d.comb += pend.eq(dest_d.o & self.g_wr_pend_i) + m.d.comb += waw_stall.eq(pend.bool()) + + ib_l = [] + for i in range(self.n_insns): + ib_l.append(self.insn_i[i] & self.busy_i[i]) + m.d.comb += fu_stall.eq(Cat(*ib_l).bool()) + m.d.comb += self.g_issue_o.eq(~(waw_stall | fu_stall)) + for i in range(self.n_insns): + m.d.comb += self.fn_issue_o[i].eq(self.g_issue_o & self.insn_i[i]) + + return m + + def __iter__(self): + yield self.store_i + yield self.dest_i + yield self.src1_i + yield self.src2_i + yield self.g_wr_pend_i + yield from self.insn_i + yield from self.busy_i + yield from self.fn_issue_o + yield self.g_issue_o + + def ports(self): + return list(self) + + +def issue_unit_sim(dut): + yield dut.dest_i.eq(1) + yield dut.issue_i.eq(1) + yield + yield dut.issue_i.eq(0) + yield + yield dut.src1_i.eq(1) + yield dut.issue_i.eq(1) + yield + yield + yield + yield dut.issue_i.eq(0) + yield + yield dut.go_read_i.eq(1) + yield + yield dut.go_read_i.eq(0) + yield + yield dut.go_write_i.eq(1) + yield + yield dut.go_write_i.eq(0) + yield + +def test_issue_unit(): + dut = IssueUnit(32, 3) + vl = rtlil.convert(dut, ports=dut.ports()) + with open("test_issue_unit.il", "w") as f: + f.write(vl) + + run_simulation(dut, issue_unit_sim(dut), vcd_name='test_issue_unit.vcd') + +if __name__ == '__main__': + test_issue_unit() -- 2.30.2