self.fpregs = RegFileArray(rwid, n_regs)
# inputs
- self.int_store_i = Signal(reset_less=True) # instruction is a store
self.int_dest_i = Signal(max=n_regs, reset_less=True) # Dest R# in
self.int_src1_i = Signal(max=n_regs, reset_less=True) # oper1 R# in
self.int_src2_i = Signal(max=n_regs, reset_less=True) # oper2 R# in
# INT/FP Issue Unit
regdecode = RegDecode(self.n_regs)
m.submodules.regdecode = regdecode
- issueunit = IntFPIssueUnit(self.n_regs, n_int_fus, n_fp_fus)
+ issueunit = IntFPIssueUnit(n_int_fus, n_fp_fus)
m.submodules.issueunit = issueunit
# Shadow Matrix. currently n_int_fus shadows, to be used for
#---------
# Issue Unit is where it starts. set up some in/outs for this module
#---------
- comb += [issueunit.i.store_i.eq(self.int_store_i),
- regdecode.dest_i.eq(self.int_dest_i),
+ comb += [ regdecode.dest_i.eq(self.int_dest_i),
regdecode.src1_i.eq(self.int_src1_i),
regdecode.src2_i.eq(self.int_src2_i),
regdecode.enable_i.eq(self.reg_enable_i),
- issueunit.i.dest_i.eq(regdecode.dest_o),
self.issue_o.eq(issueunit.issue_o)
]
self.int_insn_i = issueunit.i.insn_i # enabled by instruction decode
- # connect global rd/wr pending vector (for WaW detection)
- sync += issueunit.i.g_wr_pend_i.eq(intfus.g_int_wr_pend_o)
# TODO: issueunit.f (FP)
# and int function issue / busy arrays, and dest/src1/src2
def __iter__(self):
yield from self.intregs
yield from self.fpregs
- yield self.int_store_i
yield self.int_dest_i
yield self.int_src1_i
yield self.int_src2_i
iseed = 3
- yield dut.int_store_i.eq(1)
-
for i in range(1):
print ("rseed", iseed)
seed(0)
- yield dut.int_store_i.eq(1)
-
- for i in range(1):
+ for i in range(20):
# set random values in the registers
for i in range(1, dut.n_regs):
# create some instructions (some random, some regression tests)
instrs = []
- if False:
+ if True:
instrs = create_random_ops(dut, 10, True, 4)
if False:
instrs.append((5, 3, 3, 4, (0, 0)))
instrs.append((4, 2, 1, 2, (1, 0)))
- if True:
+ if False:
instrs.append( (4, 3, 5, 1, (0, 0)) )
instrs.append( (5, 2, 3, 1, (0, 0)) )
instrs.append( (7, 1, 5, 2, (0, 0)) )
busy_i is a vector of signals that indicate, in this cycle, which
of the units are currently busy.
- g_issue_o indicates whether it is "safe to proceed" i.e. whether
+ busy_o indicates whether it is "safe to proceed" i.e. whether
there is a unit here that can *be* issued an instruction
fn_issue_o indicates, out of the available (non-busy) units,
# outputs
self.fn_issue_o = Signal(n_insns, reset_less=True, name="fn_issue_o")
- self.g_issue_o = Signal(reset_less=True)
+ self.busy_o = Signal(reset_less=True)
def elaborate(self, platform):
m = Module()
m.d.comb += pick.i.eq(~self.busy_i & allissue)
# "Safe to issue" condition is basically when all units are not busy
- m.d.comb += self.g_issue_o.eq((self.busy_i != all1))
+ m.d.comb += self.g_issue_o.eq((self.busy_i == all1))
# Picker only raises one signal, therefore it's also the fn_issue
m.d.comb += self.fn_issue_o.eq(pick.o)
Inputs
- * :wid: register file width
* :n_insns: number of instructions in this issue unit.
"""
- def __init__(self, wid, n_insns):
- self.reg_width = wid
+ def __init__(self, n_insns):
self.n_insns = n_insns
# inputs
- self.store_i = Signal(reset_less=True) # instruction is a store
- self.dest_i = Signal(wid, reset_less=True) # Dest R in (unary)
-
- self.g_wr_pend_i = Signal(wid, reset_less=True) # write pending vector
-
self.insn_i = Signal(n_insns, reset_less=True, name="insn_i")
self.busy_i = Signal(n_insns, reset_less=True, name="busy_i")
return m
# 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 += pend.eq(self.dest_i & self.g_wr_pend_i)
- m.d.comb += waw_stall.eq(pend.bool() & (~self.store_i))
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))
+ m.d.comb += self.g_issue_o.eq(~(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.reg_enable_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.insn_i
+ yield self.busy_i
+ yield self.fn_issue_o
yield self.g_issue_o
def ports(self):
class IntFPIssueUnit(Elaboratable):
- def __init__(self, wid, n_int_insns, n_fp_insns):
- self.i = IssueUnit(wid, n_int_insns)
- self.f = IssueUnit(wid, n_fp_insns)
+ def __init__(self, n_int_insns, n_fp_insns):
+ self.i = IssueUnit(n_int_insns)
+ self.f = IssueUnit(n_fp_insns)
self.issue_o = Signal(reset_less=True)
- # some renames
- self.int_wr_pend_i = self.i.g_wr_pend_i
- self.fp_wr_pend_i = self.f.g_wr_pend_i
- self.int_wr_pend_i.name = 'int_wr_pend_i'
- self.fp_wr_pend_i.name = 'fp_wr_pend_i'
-
def elaborate(self, platform):
m = Module()
m.submodules.intissue = self.i