1 from nmigen
.compat
.sim
import run_simulation
2 from nmigen
.cli
import verilog
, rtlil
3 from nmigen
import Module
, Signal
, Cat
, Array
, Const
, Record
, Elaboratable
4 from nmigen
.lib
.coding
import Decoder
6 from .shadow_fn
import ShadowFn
9 class RegDecode(Elaboratable
):
10 """ decodes registers into unary
14 * :wid: register file width
16 def __init__(self
, wid
):
20 self
.enable_i
= Signal(reset_less
=True) # enable decoders
21 self
.dest_i
= Signal(max=wid
, reset_less
=True) # Dest R# in
22 self
.src1_i
= Signal(max=wid
, reset_less
=True) # oper1 R# in
23 self
.src2_i
= Signal(max=wid
, reset_less
=True) # oper2 R# in
26 self
.dest_o
= Signal(wid
, reset_less
=True) # Dest unary out
27 self
.src1_o
= Signal(wid
, reset_less
=True) # oper1 unary out
28 self
.src2_o
= Signal(wid
, reset_less
=True) # oper2 unary out
30 def elaborate(self
, platform
):
32 m
.submodules
.dest_d
= dest_d
= Decoder(self
.reg_width
)
33 m
.submodules
.src1_d
= src1_d
= Decoder(self
.reg_width
)
34 m
.submodules
.src2_d
= src2_d
= Decoder(self
.reg_width
)
36 # dest decoder: write-pending
37 for d
, i
, o
in [(dest_d
, self
.dest_i
, self
.dest_o
),
38 (src1_d
, self
.src1_i
, self
.src1_o
),
39 (src2_d
, self
.src2_i
, self
.src2_o
)]:
41 m
.d
.comb
+= d
.n
.eq(~self
.enable_i
)
59 class IssueUnit(Elaboratable
):
60 """ implements 11.4.14 issue unit, p50
64 * :wid: register file width
65 * :n_insns: number of instructions in this issue unit.
67 def __init__(self
, wid
, n_insns
):
69 self
.n_insns
= n_insns
72 self
.store_i
= Signal(reset_less
=True) # instruction is a store
73 self
.dest_i
= Signal(wid
, reset_less
=True) # Dest R in (unary)
75 self
.g_wr_pend_i
= Signal(wid
, reset_less
=True) # write pending vector
77 self
.insn_i
= Array(Signal(reset_less
=True, name
="insn_i") \
78 for i
in range(n_insns
))
79 self
.busy_i
= Array(Signal(reset_less
=True, name
="busy_i") \
80 for i
in range(n_insns
))
83 self
.fn_issue_o
= Array(Signal(reset_less
=True, name
="fn_issue_o") \
84 for i
in range(n_insns
))
85 self
.g_issue_o
= Signal(reset_less
=True)
87 def elaborate(self
, platform
):
94 waw_stall
= Signal(reset_less
=True)
95 fu_stall
= Signal(reset_less
=True)
96 pend
= Signal(self
.reg_width
, reset_less
=True)
98 # dest decoder: write-pending
99 m
.d
.comb
+= pend
.eq(self
.dest_i
& self
.g_wr_pend_i
& (~self
.store_i
))
100 m
.d
.comb
+= waw_stall
.eq(pend
.bool())
103 for i
in range(self
.n_insns
):
104 ib_l
.append(self
.insn_i
[i
] & self
.busy_i
[i
])
105 m
.d
.comb
+= fu_stall
.eq(Cat(*ib_l
).bool())
106 m
.d
.comb
+= self
.g_issue_o
.eq(~
(waw_stall | fu_stall
))
107 for i
in range(self
.n_insns
):
108 m
.d
.comb
+= self
.fn_issue_o
[i
].eq(self
.g_issue_o
& self
.insn_i
[i
])
117 yield self
.g_wr_pend_i
118 yield from self
.insn_i
119 yield from self
.busy_i
120 yield from self
.fn_issue_o
127 class IntFPIssueUnit(Elaboratable
):
128 def __init__(self
, wid
, n_int_insns
, n_fp_insns
):
129 self
.i
= IssueUnit(wid
, n_int_insns
)
130 self
.f
= IssueUnit(wid
, n_fp_insns
)
131 self
.issue_o
= Signal(reset_less
=True)
134 self
.int_write_pending_i
= self
.i
.g_wr_pend_i
135 self
.fp_write_pending_i
= self
.f
.g_wr_pend_i
136 self
.int_write_pending_i
.name
= 'int_write_pending_i'
137 self
.fp_write_pending_i
.name
= 'fp_write_pending_i'
139 def elaborate(self
, platform
):
141 m
.submodules
.intissue
= self
.i
142 m
.submodules
.fpissue
= self
.f
144 m
.d
.comb
+= self
.issue_o
.eq(self
.i
.g_issue_o | self
.f
.g_issue_o
)
154 def issue_unit_sim(dut
):
155 yield dut
.dest_i
.eq(1)
156 yield dut
.issue_i
.eq(1)
158 yield dut
.issue_i
.eq(0)
160 yield dut
.src1_i
.eq(1)
161 yield dut
.issue_i
.eq(1)
165 yield dut
.issue_i
.eq(0)
167 yield dut
.go_rd_i
.eq(1)
169 yield dut
.go_rd_i
.eq(0)
171 yield dut
.go_wr_i
.eq(1)
173 yield dut
.go_wr_i
.eq(0)
176 def test_issue_unit():
177 dut
= IssueUnit(32, 3)
178 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
179 with
open("test_issue_unit.il", "w") as f
:
182 dut
= IntFPIssueUnit(32, 3, 3)
183 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
184 with
open("test_intfp_issue_unit.il", "w") as f
:
187 run_simulation(dut
, issue_unit_sim(dut
), vcd_name
='test_issue_unit.vcd')
189 if __name__
== '__main__':