from nmutil.latch import SRLatch, latchregister
from nmutil.iocontrol import RecordObject
+from nmutil.util import rising_edge
from soc.fu.regspec import RegSpec, RegSpecALUAPI
# to trigger *from* the opcode latch instead.
src_or_imm = Signal(self.cu._get_srcwid(i), reset_less=True)
src_sel = Signal(reset_less=True)
- m.d.comb += src_sel.eq(Mux(op_is_imm, self.opc_l.q, self.src_l.q[i]))
+ m.d.comb += src_sel.eq(Mux(op_is_imm, self.opc_l.q, sl[i][2]))
m.d.comb += src_or_imm.eq(Mux(op_is_imm, imm, self.src_i[i]))
# overwrite 1st src-latch with immediate-muxed stuff
sl[i][0] = src_or_imm
(((~self.rd.rel_o) | self.rd.go_i).all()))
# generate read-done pulse
- all_rd_dly = Signal(reset_less=True)
all_rd_pulse = Signal(reset_less=True)
- m.d.sync += all_rd_dly.eq(all_rd)
- m.d.comb += all_rd_pulse.eq(all_rd & ~all_rd_dly)
+ m.d.comb += all_rd_pulse.eq(rising_edge(m, all_rd))
# create rising pulse from alu valid condition.
alu_done = Signal(reset_less=True)
- alu_done_dly = Signal(reset_less=True)
alu_pulse = Signal(reset_less=True)
alu_pulsem = Signal(self.n_dst, reset_less=True)
m.d.comb += alu_done.eq(self.alu.n.valid_o)
- m.d.sync += alu_done_dly.eq(alu_done)
- m.d.comb += alu_pulse.eq(alu_done & ~alu_done_dly)
+ m.d.comb += alu_pulse.eq(rising_edge(m, alu_done))
m.d.comb += alu_pulsem.eq(Repl(alu_pulse, self.n_dst))
# sigh bug where req_l gets both set and reset raised at same time
m.d.comb += reset_r.eq(self.rd.go_i | Repl(self.go_die_i, self.n_src))
# read-done,wr-proceed latch
- m.d.comb += rok_l.s.eq(self.issue_i) # set up when issue starts
+ m.d.sync += rok_l.s.eq(self.issue_i) # set up when issue starts
m.d.sync += rok_l.r.eq(self.alu.n.valid_o & self.busy_o) # ALU done
# wr-done, back-to-start latch
- m.d.comb += rst_l.s.eq(all_rd) # set when read-phase is fully done
- m.d.comb += rst_l.r.eq(rst_r) # *off* on issue
+ m.d.sync += rst_l.s.eq(all_rd) # set when read-phase is fully done
+ m.d.sync += rst_l.r.eq(rst_r) # *off* on issue
# opcode latch (not using go_rd_i) - inverted so that busy resets to 0
m.d.sync += opc_l.s.eq(self.issue_i) # set on issue
m.d.sync += src_l.r.eq(reset_r)
# dest operand latch (not using issue_i)
- m.d.comb += req_l.s.eq(alu_pulsem & self.wrmask)
- m.d.comb += req_l.r.eq(reset_w | prev_wr_go)
+ m.d.sync += req_l.s.eq(alu_pulsem & self.wrmask)
+ m.d.sync += req_l.r.eq(reset_w | prev_wr_go)
- # create a latch/register for the operand
- oper_r = self.opsubsetkls(name="oper_r")
- latchregister(m, self.oper_i, oper_r, self.issue_i, "oper_l")
+ # pass operation to the ALU (sync: plenty time to wait for src reads)
+ op = self.get_op()
+ with m.If(self.issue_i):
+ m.d.sync += op.eq(self.oper_i)
# and for each output from the ALU: capture when ALU output is valid
drl = []
# bye-bye abstract interface design..
fname = find_ok(data_r.fields)
if fname:
- ok = data_r[fname]
+ ok = getattr(lro, fname)
else:
data_r = Signal.like(lro, name=name, reset_less=True)
wrok.append(ok & self.busy_o)
- latchregister(m, lro, data_r, alu_pulsem, name + "_l")
+ with m.If(alu_pulse):
+ m.d.sync += data_r.eq(lro)
+ with m.If(self.issue_i):
+ m.d.sync += data_r.eq(0)
drl.append(data_r)
# ok, above we collated anything with an "ok" on the output side
# a regfile port because this particular output is not valid"
m.d.comb += self.wrmask.eq(Cat(*wrok))
- # pass the operation to the ALU
- m.d.comb += self.get_op().eq(oper_r)
-
# create list of src/alu-src/src-latch. override 1st and 2nd one below.
# in the case, for ALU and Logical pipelines, we assume RB is the
# 2nd operand in the input "regspec". see for example
# if the operand subset has "zero_a" we implicitly assume that means
# src_i[0] is an INT reg type where zero can be multiplexed in, instead.
# see https://bugs.libre-soc.org/show_bug.cgi?id=336
- if hasattr(oper_r, "zero_a"):
+ if hasattr(op, "zero_a"):
# select zero imm if opcode says so. however also change the latch
# to trigger *from* the opcode latch instead.
- self._mux_op(m, sl, oper_r.zero_a, 0, 0)
+ self._mux_op(m, sl, op.zero_a, 0, 0)
# if the operand subset has "imm_data" we implicitly assume that means
# "this is an INT ALU/Logical FU jobbie, RB is muxed with the immediate"
- if hasattr(oper_r, "imm_data"):
+ if hasattr(op, "imm_data"):
# select immediate if opcode says so. however also change the latch
# to trigger *from* the opcode latch instead.
- op_is_imm = oper_r.imm_data.imm_ok
- imm = oper_r.imm_data.imm
+ op_is_imm = op.imm_data.imm_ok
+ imm = op.imm_data.imm
self._mux_op(m, sl, op_is_imm, imm, 1)
# create a latch/register for src1/src2 (even if it is a copy of imm)