Skip to content

Commit ca33d73

Browse files
authored
Merge pull request #173 from yyan7223/CtrlMem
Issue #55: PR2
2 parents cb597d9 + 49b640b commit ca33d73

3 files changed

Lines changed: 106 additions & 38 deletions

File tree

lib/cmd_type.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
# Total number of commands that are supported/recognized by controller.
1616
# Needs to be updated once more commands are added/supported.
17-
NUM_CMDS = 16
17+
NUM_CMDS = 17
1818

1919
CMD_LAUNCH = 0
2020
CMD_PAUSE = 1
@@ -32,6 +32,7 @@
3232
CMD_CONST = 13
3333
CMD_COMPLETE = 14
3434
CMD_RESUME = 15
35+
CMD_RECORD_INIT_PHI_ADDR = 16
3536

3637
CMD_SYMBOL_DICT = {
3738
CMD_LAUNCH: "(LAUNCH_KERNEL)",
@@ -49,6 +50,7 @@
4950
CMD_STORE_REQUEST: "(STORE_REQUEST)",
5051
CMD_CONST: "(CONST_DATA)",
5152
CMD_COMPLETE: "(COMPLETE_EXECUTION)",
52-
CMD_RESUME: "(RESUME_EXECUTION)"
53+
CMD_RESUME: "(RESUME_EXECUTION)",
54+
CMD_RECORD_INIT_PHI_ADDR: "(RECORD_INIT_PHI_ADDR)"
5355
}
5456

mem/ctrl/ContextSwitchRTL.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@
1818

1919
class ContextSwitchRTL(Component):
2020

21-
def construct(s, data_nbits):
21+
def construct(s, data_nbits, ctrl_addr_nbits):
2222

2323
# Constant
2424
CmdType = mk_bits(clog2(NUM_CMDS))
2525
StatusType = mk_bits(clog2(NUM_STATUS))
2626
DataType = mk_data(data_nbits)
27+
CtrlAddrType = mk_bits(ctrl_addr_nbits)
2728
OptType = mk_bits(clog2(NUM_OPTS))
2829

2930
# Interface
@@ -38,10 +39,17 @@ def construct(s, data_nbits):
3839
# During the PAUSING status, FU's output when executing PHI_CONST operation
3940
# should always have predicate=0, so as to avoid initiating new iteration.
4041
s.overwrite_fu_output_predicate = OutPort(b1)
42+
# CPU should preload the unique ctrl mem address of the DFG's first PHI_CONST
43+
# through the port 'init_phi_addr' to the register 'init_phi_addr_reg'.
44+
# Then compare with the read address of ctrl mem at each cycle to make sure
45+
# progress is only recorded when executing the first PHI_CONST during PAUSING status.
46+
s.init_phi_addr = InPort(CtrlAddrType)
47+
s.ctrl_mem_rd_addr = InPort(CtrlAddrType)
4148

4249
# Component
4350
s.progress_reg = Wire(DataType)
4451
s.status_reg = Wire(StatusType)
52+
s.init_phi_addr_reg = Wire(CtrlAddrType)
4553
s.progress_is_null = Wire(b1)
4654
s.is_pausing = Wire(b1)
4755
s.is_resuming = Wire(b1)
@@ -53,7 +61,7 @@ def update_msg():
5361
s.progress_is_null @= (s.progress_reg == DataType(0, 0))
5462
s.is_pausing @= (s.status_reg == STATUS_PAUSING)
5563
s.is_resuming @= (s.status_reg == STATUS_RESUMING)
56-
s.is_executing_phi @= (s.recv_opt == OPT_PHI_CONST)
64+
s.is_executing_phi @= ((s.recv_opt == OPT_PHI_CONST) and (s.init_phi_addr_reg == s.ctrl_mem_rd_addr))
5765

5866
# Updates progress_out with the recorded progress.
5967
if (~s.progress_is_null & s.is_resuming & s.is_executing_phi):
@@ -92,12 +100,20 @@ def update_regs():
92100
# Keeps the progress.
93101
s.progress_reg <<= s.progress_reg
94102

103+
# Records the PHI_CONST's unqiue ctrl mem address to the register.
104+
if (s.recv_cmd_vld & (s.recv_cmd == CMD_RECORD_INIT_PHI_ADDR)):
105+
s.init_phi_addr_reg <<= s.init_phi_addr
106+
else:
107+
s.init_phi_addr_reg <<= s.init_phi_addr_reg
108+
95109
def line_trace(s):
96110
recv_cmd_str = f'|| recv_cmd_vld: {s.recv_cmd_vld} | recv_cmd: {s.recv_cmd} '
97111
recv_opt_str = f'|| recv_opt: {s.recv_opt} '
98112
progress_in_str = f'|| progress_in: {s.progress_in} '
99113
progress_out_str = f'|| progress_out: {s.progress_out} '
114+
init_phi_addr_str = f'|| init_phi_addr: {s.init_phi_addr} '
115+
ctrl_mem_rd_addr_str = f'|| ctrl_mem_rd_addr: {s.ctrl_mem_rd_addr} '
100116
overwrite_fu_output_predicate_str = f'|| overwrite_fu_output_predicate: {s.overwrite_fu_output_predicate} '
101-
register_content_str = f'|| progress_reg: {s.progress_reg} | status_reg: {s.status_reg} '
117+
register_content_str = f'|| progress_reg: {s.progress_reg} | status_reg: {s.status_reg}i | init_phi_addr_reg: {s.init_phi_addr_reg} '
102118
condition_str = f'|| condition: {s.progress_is_null}{s.is_pausing}{s.is_executing_phi} '
103-
return recv_cmd_str + recv_opt_str + progress_in_str + progress_out_str + overwrite_fu_output_predicate_str + register_content_str + condition_str
119+
return recv_cmd_str + recv_opt_str + progress_in_str + progress_out_str + init_phi_addr_str + ctrl_mem_rd_addr_str + overwrite_fu_output_predicate_str + register_content_str + condition_str

mem/ctrl/test/ContextSwitchRTL_test.py

Lines changed: 82 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,24 @@
2121

2222
class TestHarness(Component):
2323

24-
def construct(s, Module, data_nbits, src_cmds, src_opts, src_progress_in, sink_progress_out, sink_overwrite_fu_output_predicate):
24+
def construct(s, Module, data_nbits, ctrl_addr_nbits, src_cmds, src_opts, src_init_phi_addr, src_ctrl_mem_rd_addr, src_progress_in, sink_progress_out, sink_overwrite_fu_output_predicate):
2525

2626
CmdType = mk_bits(clog2(NUM_CMDS))
2727
StatusType = mk_bits(clog2(NUM_STATUS))
2828
DataType = mk_data(data_nbits)
29+
CtrlAddrType = mk_bits(ctrl_addr_nbits)
2930
ValidType = mk_bits(1)
3031
OptType = mk_bits(clog2(NUM_OPTS))
3132

3233
s.src_cmds = TestSrcRTL(CmdType, src_cmds)
3334
s.src_opts = TestSrcRTL(OptType, src_opts)
35+
s.src_init_phi_addr = TestSrcRTL(CtrlAddrType, src_init_phi_addr)
36+
s.src_ctrl_mem_rd_addr = TestSrcRTL(CtrlAddrType, src_ctrl_mem_rd_addr)
3437
s.src_progress_in = TestSrcRTL(DataType, src_progress_in)
3538
s.sink_progress_out = TestSinkRTL(DataType, sink_progress_out)
3639
s.sink_overwrite_fu_output_predicate = TestSinkRTL(ValidType, sink_overwrite_fu_output_predicate)
37-
38-
s.context_switch = Module(data_nbits)
40+
41+
s.context_switch = Module(data_nbits, ctrl_addr_nbits)
3942

4043
@update
4144
def issue_inputs():
@@ -46,13 +49,17 @@ def issue_inputs():
4649
s.src_opts.send.rdy @= 1
4750
s.context_switch.progress_in @= s.src_progress_in.send.msg
4851
s.src_progress_in.send.rdy @= 1
52+
s.context_switch.init_phi_addr @= s.src_init_phi_addr.send.msg
53+
s.src_init_phi_addr.send.rdy @= 1
54+
s.context_switch.ctrl_mem_rd_addr @= s.src_ctrl_mem_rd_addr.send.msg
55+
s.src_ctrl_mem_rd_addr.send.rdy @= 1
4956
s.sink_progress_out.recv.val @= 1
5057
s.sink_progress_out.recv.msg @= s.context_switch.progress_out
5158
s.sink_overwrite_fu_output_predicate.recv.val @= 1
5259
s.sink_overwrite_fu_output_predicate.recv.msg @= s.context_switch.overwrite_fu_output_predicate
5360

5461
def done(s):
55-
return s.src_cmds.done() and s.src_opts.done() and s.src_progress_in.done() and s.sink_progress_out.done() and s.sink_overwrite_fu_output_predicate.done()
62+
return s.src_cmds.done() and s.src_opts.done() and s.src_init_phi_addr.done() and s.src_ctrl_mem_rd_addr.done() and s.src_progress_in.done() and s.sink_progress_out.done() and s.sink_overwrite_fu_output_predicate.done()
5663

5764
def line_trace(s):
5865
return s.context_switch.line_trace()
@@ -83,77 +90,117 @@ def run_sim(test_harness, max_cycles = 20):
8390
def test():
8491
Module = ContextSwitchRTL
8592
data_nbits = 16
93+
ctrl_addr_nbits = 16
8694
CmdType = mk_bits(clog2(NUM_CMDS))
8795
DataType = mk_data(data_nbits)
96+
CtrlAddrType = mk_bits(ctrl_addr_nbits)
8897
OptType = mk_bits(clog2(NUM_OPTS))
8998

90-
src_cmds = [# Assumes that tile receives the PAUSE command at clock cycle 1.
91-
CmdType(CMD_PAUSE), # cycle 1
99+
src_cmds = [# Preloads the ctrl mem address of DFG's initial PHI_CONST at clock cycle 1.
100+
CmdType(CMD_RECORD_INIT_PHI_ADDR), # cycle 1
101+
# Tile receives the PAUSE command at clock cycle 2.
102+
CmdType(CMD_PAUSE), # cycle 2
92103
# Some random commands that might be issued during pausing.
93-
CmdType(CMD_CONFIG_TOTAL_CTRL_COUNT), # cycle 2
94-
CmdType(CMD_CONFIG_COUNT_PER_ITER), # cycle 3
95-
CmdType(CMD_CONFIG_CTRL_LOWER_BOUND), # cycle 4
96-
# Assumes that tile receives the RESUME command at clock cycle 5.
104+
CmdType(CMD_CONST), # cycle 3
105+
CmdType(CMD_CONST), # cycle 4
106+
# Tile receives the RESUME command at clock cycle 5.
97107
CmdType(CMD_RESUME), # cycle 5
98108
# Some random commands that might be issued during resuming.
99-
CmdType(CMD_CONFIG_TOTAL_CTRL_COUNT), # cycle 6
100-
CmdType(CMD_CONFIG_COUNT_PER_ITER), # cycle 7
101-
CmdType(CMD_CONFIG_CTRL_LOWER_BOUND) # cycle 8
109+
CmdType(CMD_CONST), # cycle 6
110+
CmdType(CMD_CONST), # cycle 7
111+
CmdType(CMD_CONST) # cycle 8
102112
]
113+
103114
src_opts = [
104-
# Some random operations executed in FU,
115+
# Some random operations executed in FU.
105116
OptType(OPT_NAH),
106117
OptType(OPT_NAH),
107-
# Assumes that FU executes PHI_CONST at clock cycle 3
108-
# for the first time after receiving PAUSE command.
118+
# FU executes PHI_CONST at clock cycle 3.
119+
OptType(OPT_PHI_CONST),
120+
# FU executes the initial PHI_CONST at clock cycle 4
121+
# for the first time duing PAUSING status.
109122
OptType(OPT_PHI_CONST),
110123
# Some random operations executed in FU.
111124
OptType(OPT_NAH),
112125
OptType(OPT_NAH),
113-
OptType(OPT_NAH),
114-
# Assumes that FU executes PHI_CONST at clock cycle 7
115-
# for the first time after receiving RESUME command.
126+
# FU executes PHI_CONST at clock cycle 7
127+
OptType(OPT_PHI_CONST),
128+
# FU executes the initial PHI_CONST at clock cycle 8
129+
# for the first time during RESUMING status.
116130
OptType(OPT_PHI_CONST),
117-
# Simulates some random operations.
118-
OptType(OPT_NAH)
119131
]
132+
133+
# Ctrl mem has 4 configurations,
134+
# so ctrl mem address iterates bewteen 0 and 3.
135+
# Address 2 contains PHI_CONST (Output other data, i.e., the operand of +=).
136+
# Address 3 contains the initial PHI_CONST (Output iteration indexs).
137+
src_ctrl_mem_rd_addr = [
138+
CtrlAddrType(0),
139+
CtrlAddrType(1),
140+
CtrlAddrType(2),
141+
CtrlAddrType(3),
142+
CtrlAddrType(0),
143+
CtrlAddrType(1),
144+
CtrlAddrType(2),
145+
CtrlAddrType(3)
146+
]
147+
148+
# Preloads the address 3 of the initial PHI_CONST.
149+
src_init_phi_addr = [
150+
CtrlAddrType(3),
151+
CtrlAddrType(0),
152+
CtrlAddrType(0),
153+
CtrlAddrType(0),
154+
CtrlAddrType(0),
155+
CtrlAddrType(0),
156+
CtrlAddrType(0),
157+
CtrlAddrType(0)
158+
]
159+
120160
src_progress_in = [
121-
# A fake progress "4321", should not be recorded.
161+
# A fake progress "4321", should not be recorded because not in the PAUSING status.
122162
DataType(4321, 1),
123163
# Some random FU's outputs.
124164
DataType(0, 0),
165+
# A fake progress "8765", should not be recorded
166+
# because FU is executing PHI_CONST.
167+
DataType(8765, 1),
125168
# The target progress (loop iteration)
126-
# output by FU when executing PHI_CONST for
127-
# the first time after receiving PAUSE command.
169+
# output by FU when executing the initial PHI_CONST for
170+
# the first time during the PAUSING status.
128171
# Should be recorded to progress register at the rising
129-
# edge of clock cycle 4
172+
# edge of clock cycle 5
130173
DataType(1234, 1),
131174
# Some random FU's outputs.
132175
DataType(0, 0),
133176
DataType(0, 0),
134177
DataType(0, 0),
135-
DataType(0, 0),
136178
DataType(0, 0)
137179
]
180+
138181
sink_progress_out = [
139182
DataType(0, 0),
140183
DataType(0, 0),
141184
DataType(0, 0),
142185
DataType(0, 0),
143186
DataType(0, 0),
144187
DataType(0, 0),
188+
DataType(0, 0),
145189
# ContextSiwtch module should output the target progress
146-
# when executing PHI_CONST for the first time after
147-
# receiving RESUME command.
148-
DataType(1234, 1),
149-
DataType(0, 0)
190+
# when FU executes the initail PHI_CONST for the first time
191+
# during the RESUMING status at cycle 8.
192+
# The 'predicate' bit alone can inidicates that the progress_out is valid,
193+
# we therefore omit the 'valid' bit for simplicity.
194+
DataType(1234, 1)
150195
]
196+
151197
sink_overwrite_fu_output_predicate = [
152198
0,
153199
0,
154-
# clock cycle 3 has overwrite_fu_output_predicate = 1, as in the PAUSING status and executing the PHI_CONST.
155-
1,
156200
0,
201+
# clock cycle 4 has overwrite_fu_output_predicate = 1,
202+
# as in the PAUSING status and executing the initial PHI_CONST.
203+
1,
157204
0,
158205
0,
159206
0,
@@ -162,8 +209,11 @@ def test():
162209

163210
th = TestHarness(Module,
164211
data_nbits,
212+
ctrl_addr_nbits,
165213
src_cmds,
166214
src_opts,
215+
src_init_phi_addr,
216+
src_ctrl_mem_rd_addr,
167217
src_progress_in,
168218
sink_progress_out,
169219
sink_overwrite_fu_output_predicate)

0 commit comments

Comments
 (0)