def make_hazard_vec(self, rf, name):
if isinstance(rf, VirtualRegPort):
- vec = RegFileArray(1, rf.nregs)
+ vec = VirtualRegPort(rf.nregs, rf.nregs, wr2=True)
else:
- vec = RegFileArray(1, rf.depth)
+ vec = VirtualRegPort(rf.depth, rf.depth, wr2=True)
# get read/write port specs and create bitvector ports with same names
wr_spec, rd_spec = rf.get_port_specs()
# ok, this is complicated/fun.
# bitvector *ALSO* needs to be wrtten (a 0). therefore we need to
# MERGE the wr_spec and rd_spec with some appropriate name prefixes
# to make sure they do not clash
- rd_bvspec = {'issue': 'issue'}
- wr_bvspec = {'set': 'set', 'clr': 'clr'}
- #for k, port in wr_spec.items():
- # wr_bvspec["wr_%s" % k] = "wr_%s" % port
- #for k, port in rd_spec.items():
- # wr_bvspec["rd_%s" % k] = "rd_%s" % port
+ rd_bvspec = {'issue': 'full_rd'}
+ wr_bvspec = {'set': 'full_wr', 'clr': 'full_wr2'}
create_ports(vec, wr_bvspec, rd_bvspec)
return vec
class VirtualRegPort(RegFileArray):
- def __init__(self, bitwidth, n_regs, rd2=False):
+ def __init__(self, bitwidth, n_regs, rd2=False, wr2=False):
self.bitwidth = bitwidth
self.nregs = n_regs
self.rd2 = rd2 # eurgh hack
+ self.wr2 = wr2 # eurgh hack
self.regwidth = regwidth = bitwidth // n_regs
super().__init__(self.regwidth, n_regs)
self.full_rd = RecordObject([("ren", n_regs),
("o_data", bitwidth)], # *full* wid
name="full_rd")
- if not rd2:
- return
- self.full_rd2 = RecordObject([("ren", n_regs),
+ if wr2:
+ self.full_wr2 = RecordObject([("wen", n_regs),
+ ("i_data", bitwidth)], # *full* wid
+ name="full_wr2")
+ if rd2:
+ self.full_rd2 = RecordObject([("ren", n_regs),
("o_data", bitwidth)], # *full* wid
name="full_rd2")
+ def connect_full_wr(self, m, wfull, name):
+ comb = m.d.comb
+ wr_regs = self.write_reg_port(name)
+
+ # wire up the enable signals from the large (full) port
+ l = map(lambda port: port.i_data, wr_regs)
+ le = map(lambda port: port.wen, wr_regs) # get port wen(s)
+
+ # get list of all i_data (and wens) and assign to them via Cat
+ comb += Cat(*l).eq(wfull.i_data)
+ comb += Cat(*le).eq(wfull.wen)
+
def connect_full_rd(self, m, rfull, name):
comb = m.d.comb
rd_regs = self.read_reg_port(name)
m = super().elaborate(platform)
comb = m.d.comb
- # for internal use only.
- wr_regs = self.write_reg_port(f"w")
+ # connect up full write port
+ self.connect_full_wr(m, self.full_wr, "w")
+ if self.wr2:
+ self.connect_full_wr(m, self.full_wr2, "w2")
# connect up full read port
self.connect_full_rd(m, self.full_rd, "r")
if self.rd2: # hack!
self.connect_full_rd(m, self.full_rd2, "r2")
- # connect up full write port
- wfull = self.full_wr
-
- # wire up the enable signals from the large (full) port
- l = map(lambda port: port.i_data, wr_regs)
- le = map(lambda port: port.wen, wr_regs) # get port wen(s)
-
- # get list of all i_data (and wens) and assign to them via Cat
- comb += Cat(*l).eq(wfull.i_data)
- comb += Cat(*le).eq(wfull.wen)
-
return m
def __iter__(self):
for i, fspec in enumerate(fspecs):
# connect up the FU req/go signals and the reg-read to the FU
# these are arbitrated by Data.ok signals
- (rf, wf, read, write, wid, fuspec) = fspec
+ (rf, wf, read, _write, wid, fuspec) = fspec
+ wrname = "write_%s_%s_%d" % (regfile, regname, i)
+ write = Signal.like(_write, name=wrname)
+ comb += write.eq(_write)
for pi, (funame, fu, idx) in enumerate(fuspec):
pi += ppoffs[i]
comb += wvaddr_en.eq(1<<addr_en)
wvclren.append(wvaddr_en)
- continue
# now connect up the bitvector write hazard. unlike the
# regfile writeports, a ONE must be written to the corresponding
# bit of the hazard bitvector (to indicate the existence of
comb += issue_active.eq(fu.issue_i & fu_active & wrflags[i])
with m.If(issue_active):
if rfile.unary:
- comb += wvaddr_en.eq(addr_en)
+ comb += wvaddr_en.eq(write)
else:
- comb += wvaddr_en.eq(1<<addr_en)
- wvsetens.append(wvaddr_en)
+ comb += wvaddr_en.eq(1<<write)
+ wvseten.append(wvaddr_en)
+ wvsets.append(wvaddr_en)
# here is where we create the Write Broadcast Bus. simple, eh?
comb += wport.i_data.eq(ortreereduce_sig(wsigs))
comb += wport.wen.eq(ortreereduce_sig(wens))
# for write-vectors
- comb += wvclr.wen.eq(ortreereduce_sig(wvclren))
- #comb += wvset.wen.eq(ortreereduce_sig(wvens))
- #comb += wvset.i_data.eq(ortreereduce_sig(wvsets))
+ comb += wvclr.wen.eq(ortreereduce_sig(wvclren)) # clear (regfile write)
+ comb += wvset.wen.eq(ortreereduce_sig(wvseten)) # set (issue time)
+ comb += wvset.i_data.eq(ortreereduce_sig(wvsets))
def connect_wrports(self, m, fu_bitdict):
"""connect write ports