Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "ccu_microcode_v1.h"
12 :
13 : #include <unordered_map>
14 :
15 : #include "log.h"
16 : #include <string_util.h>
17 :
18 : namespace {
19 : constexpr uint16_t LOAD_TYPE = 0x0;
20 :
21 : constexpr uint16_t LOADSQEARGSTOX_CODE = 0x1;
22 : constexpr uint16_t LOADIMDTOX_CODE = 0x2;
23 : constexpr uint16_t LOADX_CODE = 0x6;
24 : constexpr uint16_t STOREX_CODE = 0x7;
25 : constexpr uint16_t CLEARX_CODE = 0x8;
26 : constexpr uint16_t NOP_CODE = 0x9;
27 : constexpr uint16_t LOAD_CODE = 0xA;
28 : constexpr uint16_t STORE_CODE = 0xB;
29 : constexpr uint16_t ADD_CODE = 0xD;
30 : constexpr uint16_t SUB_CODE = 0xE;
31 : constexpr uint16_t MUL_CODE = 0xF;
32 : constexpr uint16_t AND_CODE = 0x10;
33 : constexpr uint16_t OR_CODE = 0x11;
34 : constexpr uint16_t NOT_CODE = 0x12;
35 : constexpr uint16_t XOR_CODE = 0x13;
36 : constexpr uint16_t SHL_CODE = 0x14;
37 : constexpr uint16_t SHR_CODE = 0x15;
38 : constexpr uint16_t POPCNT_CODE = 0x16;
39 :
40 : constexpr uint16_t CTRL_TYPE = 0x1;
41 :
42 : constexpr uint16_t LOOP_CODE = 0x0;
43 : constexpr uint16_t LOOPGROUP_CODE = 0x1;
44 : constexpr uint16_t SETCKBIT_CODE = 0x2;
45 : constexpr uint16_t CLEARCKBIT_CODE = 0x4;
46 : constexpr uint16_t JMP_CODE = 0x5;
47 : constexpr uint16_t WAIT_CODE = 0x7;
48 : constexpr uint16_t FENCE_CODE = 0x8;
49 :
50 : constexpr uint16_t TRANS_TYPE = 0x2;
51 :
52 : constexpr uint16_t TRANSLOCMEMTOLOCMS_CODE = 0x0;
53 : constexpr uint16_t TRANSLOCMSTOLOCMEM_CODE = 0x2;
54 : constexpr uint16_t TRANSLOCMSTOLOCMS_CODE = 0x5;
55 : constexpr uint16_t TRANSLOCMEMTOLOCMEM_CODE = 0x6;
56 : constexpr uint16_t TRANSMEM_CODE = 0x10;
57 : constexpr uint16_t SYNCWTX_CODE = 0xD;
58 : constexpr uint16_t SYNCATX_CODE = 0xE;
59 :
60 : constexpr uint16_t REDUCE_TYPE = 0x3;
61 :
62 : constexpr uint16_t REDUCE_ADD_CODE = 0x0;
63 : constexpr uint16_t REDUCE_MAX_CODE = 0x1;
64 : constexpr uint16_t REDUCE_MIN_CODE = 0x2;
65 :
66 : constexpr uint16_t JMP_TARGET_PC_IF_BRANCH = 5; // Jmp跳转到IF分支的目标PC
67 : constexpr uint16_t JMP_TARGET_PC_NOP_BRANCH = 3; // Jmp跳转到Nop的目标PC
68 : constexpr uint16_t JMP_COND_TYPE_IF = 2; // Jmp条件类型: IF分支
69 : constexpr uint16_t JMP_COND_TYPE_UNCOND = 6; // Jmp条件类型: 无条件
70 : } // namespace
71 :
72 : namespace hcomm {
73 : namespace CcuRep {
74 : namespace CcuV2 {
75 : // *XnId = *sqeArgsId
76 15 : void LoadSqeArgsToX(CcuInstr* instr, uint16_t xnId, uint16_t sqeArgsId, uint16_t setCKEId, uint16_t setCKEMask)
77 : {
78 15 : instr->header = InstrHeader(LOAD_TYPE, LOADSQEARGSTOX_CODE);
79 15 : instr->v2.loadSqeArgsToX.xnId = xnId;
80 15 : instr->v2.loadSqeArgsToX.sqeArgsId = sqeArgsId;
81 15 : instr->v2.loadSqeArgsToX.setCKEId = setCKEId;
82 15 : instr->v2.loadSqeArgsToX.setCKEMask = setCKEMask;
83 15 : }
84 :
85 : // *XnId = immediate
86 266 : void LoadImdToXn(CcuInstr* instr, uint16_t xnId, uint64_t immediate, uint16_t setCKEId, uint16_t setCKEMask)
87 : {
88 266 : instr->header = InstrHeader(LOAD_TYPE, LOADIMDTOX_CODE);
89 266 : instr->v2.loadImdToX.xnId = xnId;
90 266 : instr->v2.loadImdToX.immediate = immediate;
91 266 : instr->v2.loadImdToX.setCKEId = setCKEId;
92 266 : instr->v2.loadImdToX.setCKEMask = setCKEMask;
93 266 : }
94 :
95 0 : void ClearX(
96 : CcuInstr* instr, uint16_t xnId, uint16_t xmId, uint16_t xnIdMode, uint16_t xmIdMode, uint16_t setCKEId,
97 : uint16_t setCKEMask)
98 : {
99 0 : instr->header = InstrHeader(LOAD_TYPE, CLEARX_CODE);
100 0 : instr->v2.clearX.xnId = xnId & 0x7FFF;
101 0 : instr->v2.clearX.xnIdMode = xnIdMode & 0x1;
102 0 : instr->v2.clearX.xmId = xmId & 0x7FFF;
103 0 : instr->v2.clearX.xmIdMode = xmIdMode & 0x1;
104 0 : instr->v2.clearX.setCKEId = setCKEId;
105 0 : instr->v2.clearX.setCKEMask = setCKEMask;
106 0 : }
107 :
108 181 : void Nop(CcuInstr* instr) { instr->header = InstrHeader(LOAD_TYPE, NOP_CODE); }
109 :
110 : inline void
111 178 : Operator(CcuInstr* instr, uint16_t xdId, uint16_t xnId, uint16_t xmId, uint16_t setCKEId, uint16_t setCKEMask)
112 : {
113 178 : instr->v2.operate.xdId = xdId;
114 178 : instr->v2.operate.xnId = xnId;
115 178 : instr->v2.operate.xmId = xmId;
116 178 : instr->v2.operate.setCKEId = setCKEId;
117 178 : instr->v2.operate.setCKEMask = setCKEMask;
118 178 : }
119 :
120 59 : void Assign(CcuInstr* instr, uint16_t result, uint16_t operand, uint16_t setCKEId, uint16_t setCKEMask)
121 : {
122 59 : AddI(instr, result, operand, 0, setCKEId, setCKEMask);
123 59 : }
124 :
125 131 : void AssignI(CcuInstr* instr, uint16_t result, uint64_t operand, uint16_t setCKEId, uint16_t setCKEMask)
126 : {
127 131 : LoadImdToXn(instr, result, operand, setCKEId, setCKEMask);
128 131 : }
129 :
130 : void
131 57 : Add(CcuInstr* instr, uint16_t result, uint16_t operand1, uint16_t operand2, uint16_t setCKEId,
132 : uint16_t setCKEMask)
133 : {
134 57 : instr->header = InstrHeader(LOAD_TYPE, ADD_CODE);
135 57 : instr->v2.operate.parMode = 1;
136 57 : Operator(instr, result, operand1, operand2, setCKEId, setCKEMask);
137 57 : }
138 :
139 : void
140 64 : AddI(CcuInstr* instr, uint16_t result, uint16_t operand, uint16_t imm, uint16_t setCKEId, uint16_t setCKEMask)
141 : {
142 64 : instr->header = InstrHeader(LOAD_TYPE, ADD_CODE);
143 64 : instr->v2.operate.parMode = 0;
144 64 : Operator(instr, result, operand, imm, setCKEId, setCKEMask);
145 64 : }
146 :
147 : void
148 5 : Sub(CcuInstr* instr, uint16_t result, uint16_t operand1, uint16_t operand2, uint16_t setCKEId,
149 : uint16_t setCKEMask)
150 : {
151 5 : instr->header = InstrHeader(LOAD_TYPE, SUB_CODE);
152 :
153 : // 设置指令模式,Par_Mode = 1’b1时,*Xd = *Xn – *Xm
154 5 : instr->v2.operate.parMode = 1;
155 5 : Operator(instr, result, operand1, operand2, setCKEId, setCKEMask);
156 5 : }
157 :
158 : void
159 3 : SubI(CcuInstr* instr, uint16_t result, uint16_t operand, uint16_t imm, uint16_t setCKEId, uint16_t setCKEMask)
160 : {
161 3 : instr->header = InstrHeader(LOAD_TYPE, SUB_CODE);
162 :
163 : // 设置指令模式,Par_Mode = 1’b0时,*Xd = *Xn - {48’b0,Immedata[15:0]}
164 3 : instr->v2.operate.parMode = 0;
165 3 : Operator(instr, result, operand, imm, setCKEId, setCKEMask);
166 3 : }
167 :
168 : void
169 5 : Mul(CcuInstr* instr, uint16_t result, uint16_t operand1, uint16_t operand2, uint16_t setCKEId,
170 : uint16_t setCKEMask)
171 : {
172 5 : instr->header = InstrHeader(LOAD_TYPE, MUL_CODE);
173 5 : instr->v2.operate.parMode = 1;
174 5 : Operator(instr, result, operand1, operand2, setCKEId, setCKEMask);
175 5 : }
176 :
177 : void
178 3 : MulI(CcuInstr* instr, uint16_t result, uint16_t operand, uint16_t imm, uint16_t setCKEId, uint16_t setCKEMask)
179 : {
180 3 : instr->header = InstrHeader(LOAD_TYPE, MUL_CODE);
181 3 : instr->v2.operate.parMode = 0;
182 3 : Operator(instr, result, operand, imm, setCKEId, setCKEMask);
183 3 : }
184 :
185 : void
186 13 : And(CcuInstr* instr, uint16_t result, uint16_t operand1, uint16_t operand2, uint16_t setCKEId,
187 : uint16_t setCKEMask)
188 : {
189 13 : instr->header = InstrHeader(LOAD_TYPE, AND_CODE);
190 13 : instr->v2.operate.parMode = 1;
191 13 : Operator(instr, result, operand1, operand2, setCKEId, setCKEMask);
192 13 : }
193 :
194 : void
195 4 : Or(CcuInstr* instr, uint16_t result, uint16_t operand1, uint16_t operand2, uint16_t setCKEId,
196 : uint16_t setCKEMask)
197 : {
198 4 : instr->header = InstrHeader(LOAD_TYPE, OR_CODE);
199 4 : instr->v2.operate.parMode = 1;
200 4 : Operator(instr, result, operand1, operand2, setCKEId, setCKEMask);
201 4 : }
202 :
203 : void
204 2 : Xor(CcuInstr* instr, uint16_t result, uint16_t operand1, uint16_t operand2, uint16_t setCKEId,
205 : uint16_t setCKEMask)
206 : {
207 2 : instr->header = InstrHeader(LOAD_TYPE, XOR_CODE);
208 2 : instr->v2.operate.parMode = 1;
209 2 : Operator(instr, result, operand1, operand2, setCKEId, setCKEMask);
210 2 : }
211 :
212 1 : void Not(CcuInstr* instr, uint16_t result, uint16_t operand, uint16_t setCKEId, uint16_t setCKEMask)
213 : {
214 1 : instr->header = InstrHeader(LOAD_TYPE, NOT_CODE);
215 1 : instr->v2.operate.parMode = 0;
216 1 : Operator(instr, result, operand, 0, setCKEId, setCKEMask);
217 1 : }
218 :
219 : void
220 8 : SLL(CcuInstr* instr, uint16_t result, uint16_t operand1, uint16_t operand2, uint16_t setCKEId,
221 : uint16_t setCKEMask)
222 : {
223 8 : instr->header = InstrHeader(LOAD_TYPE, SHL_CODE);
224 8 : instr->v2.operate.shiftType = 0;
225 8 : Operator(instr, result, operand1, operand2, setCKEId, setCKEMask);
226 8 : }
227 :
228 : void
229 13 : SRL(CcuInstr* instr, uint16_t result, uint16_t operand1, uint16_t operand2, uint16_t setCKEId,
230 : uint16_t setCKEMask)
231 : {
232 13 : instr->header = InstrHeader(LOAD_TYPE, SHR_CODE);
233 13 : instr->v2.operate.shiftType = 0;
234 13 : Operator(instr, result, operand1, operand2, setCKEId, setCKEMask);
235 13 : }
236 :
237 : void
238 0 : SLA(CcuInstr* instr, uint16_t result, uint16_t operand1, uint16_t operand2, uint16_t setCKEId,
239 : uint16_t setCKEMask)
240 : {
241 0 : instr->header = InstrHeader(LOAD_TYPE, SHL_CODE);
242 0 : instr->v2.operate.shiftType = 1;
243 0 : Operator(instr, result, operand1, operand2, setCKEId, setCKEMask);
244 0 : }
245 :
246 : void
247 0 : SRA(CcuInstr* instr, uint16_t result, uint16_t operand1, uint16_t operand2, uint16_t setCKEId,
248 : uint16_t setCKEMask)
249 : {
250 0 : instr->header = InstrHeader(LOAD_TYPE, SHR_CODE);
251 0 : instr->v2.operate.shiftType = 1;
252 0 : Operator(instr, result, operand1, operand2, setCKEId, setCKEMask);
253 0 : }
254 :
255 : // LoadChannel、LoadInstruction暂不实现
256 :
257 0 : void LoadFromMem(
258 : CcuInstr* instr, uint16_t dst, uint16_t src, uint16_t srcToken, uint16_t len,
259 : const CacheConfig& cacheConfig, uint16_t setCKEId, uint16_t setCKEMask)
260 : {
261 0 : instr->header = InstrHeader(LOAD_TYPE, LOAD_CODE);
262 0 : instr->v2.load.xdId = dst;
263 0 : instr->v2.load.xsId = src;
264 0 : instr->v2.load.xstId = srcToken;
265 0 : instr->v2.load.xlId = len;
266 :
267 0 : instr->v2.load.allocHint = cacheConfig.allocHint & 0x3;
268 0 : instr->v2.load.victimHint = cacheConfig.victimHint & 0x3;
269 :
270 0 : instr->v2.load.setCKEId = setCKEId;
271 0 : instr->v2.load.setCKEMask = setCKEMask;
272 0 : }
273 :
274 0 : void LoadXFromMem(
275 : CcuInstr* instr, uint16_t dst, uint16_t src, uint16_t srcToken, uint16_t len,
276 : const CacheConfig& cacheConfig, uint16_t setCKEId, uint16_t setCKEMask)
277 : {
278 0 : if (instr == nullptr) {
279 0 : HCCL_ERROR("[CcuV2::LoadXFromMem] instr is nullptr!");
280 0 : return;
281 : }
282 0 : LoadFromMem(instr, dst, src, srcToken, len, cacheConfig, setCKEId, setCKEMask);
283 0 : instr->v2.load.dstType = 0x0;
284 : }
285 :
286 : // HSCB Store暂不实现
287 :
288 0 : void StoreXToMem(
289 : CcuInstr* instr, uint16_t dst, uint16_t dstToken, uint16_t src, uint16_t len,
290 : const CacheConfig& cacheConfig, uint16_t setCKEId, uint16_t setCKEMask)
291 : {
292 0 : instr->header = InstrHeader(LOAD_TYPE, STORE_CODE);
293 0 : instr->v2.store.xdId = dst;
294 0 : instr->v2.store.xdtId = dstToken;
295 0 : instr->v2.store.xsId = src;
296 0 : instr->v2.store.xlId = len;
297 0 : instr->v2.store.xhId = 0x0;
298 :
299 0 : instr->v2.store.srcType = 0x0;
300 0 : instr->v2.store.storeType = 0b0;
301 0 : instr->v2.store.hscbBroadCastDstType = 0x0;
302 :
303 0 : instr->v2.store.allocHint = cacheConfig.allocHint & 0x3;
304 0 : instr->v2.store.victimHint = cacheConfig.victimHint & 0x3;
305 :
306 0 : instr->v2.store.setCKEId = setCKEId;
307 0 : instr->v2.store.setCKEMask = setCKEMask;
308 0 : }
309 :
310 : // HSCB Broadcast 暂不实现
311 0 : void HSCBStoreXToMem(
312 : CcuInstr* instr, uint16_t dst, uint16_t src, uint16_t len, const CacheConfig& cacheConfig,
313 : uint16_t setCKEId, uint16_t setCKEMask)
314 : {
315 0 : instr->header = InstrHeader(LOAD_TYPE, STORE_CODE);
316 0 : instr->v2.store.xdId = dst;
317 0 : instr->v2.store.xdtId = 0x0;
318 0 : instr->v2.store.xsId = src;
319 0 : instr->v2.store.xlId = len;
320 0 : instr->v2.store.xhId = 0x0;
321 :
322 0 : instr->v2.store.srcType = 0x0;
323 0 : instr->v2.store.storeType = 0b1;
324 0 : instr->v2.store.hscbType = 0b0;
325 0 : instr->v2.store.hscbBroadCastDstType = 0x0;
326 :
327 0 : instr->v2.store.allocHint = cacheConfig.allocHint & 0x3;
328 0 : instr->v2.store.victimHint = cacheConfig.victimHint & 0x3;
329 :
330 0 : instr->v2.store.setCKEId = setCKEId;
331 0 : instr->v2.store.setCKEMask = setCKEMask;
332 0 : }
333 :
334 : // startInstrId ~ endInstrId之间的指令构成loop
335 : // Xm寄存器中的内容:LoopCtxId[52:45], Offset[44:13], IterNum[12:0]
336 : // IterNum[12:0] loop执行IterNum次 loop每次执行, 地址偏移为Offset loop在第LoopCtxId个LoopEngine上执行
337 19 : void Loop(
338 : CcuInstr* instr, uint16_t startInstrId, uint16_t endInstrId, uint16_t iterNum, uint16_t offset,
339 : uint16_t contextId)
340 : {
341 19 : instr->header = InstrHeader(CTRL_TYPE, LOOP_CODE);
342 19 : instr->v2.loop.startInstrId = startInstrId;
343 19 : instr->v2.loop.endInstrId = endInstrId;
344 19 : instr->v2.loop.xmId = iterNum;
345 19 : instr->v2.loop.xnId = offset;
346 19 : instr->v2.loop.xpId = contextId;
347 19 : instr->v2.loop.mode = 0;
348 19 : instr->v2.loop.wishCKEBit = 0;
349 19 : }
350 :
351 : // startLoopInstrId为LoopGroup所包含的Loop的起始地址
352 : // Xn寄存器中的内容:ExtendNum[22:16], RepeatLoopIndex[15:9], LoopNum[8:0]
353 : // Xm寄存器中的内容:gsaOffset[52:21], MSOffset[20:10], ckeOffset[9:0]
354 : // xnOffset[52:21], xnOffset[31:0]
355 : // 从startLoopInstrId开始,共LoopNum个Loop,并且从RepeatLoopIndex个开始,展开ExtendNum次
356 : // 每个展开的Loop,使用的MSId偏移为msOffset,使用的CKEId偏移为ckeOffset,使用的地址偏移为gsaOffset,
357 : // 使用的XnId偏移为xnOffset
358 9 : void LoopGroup(
359 : CcuInstr* instr, uint16_t startLoopInstrId, uint16_t loopGroupConfig, uint16_t resOffset, uint16_t xnOffset)
360 : {
361 9 : instr->header = InstrHeader(CTRL_TYPE, LOOPGROUP_CODE);
362 9 : instr->v2.loopGroup.startLoopInstrId = startLoopInstrId;
363 9 : instr->v2.loopGroup.xnId = loopGroupConfig;
364 9 : instr->v2.loopGroup.xmId = resOffset;
365 9 : instr->v2.loopGroup.xpId = xnOffset;
366 9 : }
367 :
368 : // 后续函数中, 均需要wait到<waitCKEId, waitCKEMask>后, 再执行相关操作, 执行完之后再set<setCKEId, setCKEMask>
369 : // clearType = 1时, wait到之后需要对<waitCKEId, waitCKEMask>清零, 否则不清零
370 :
371 4 : void SetCKE(
372 : CcuInstr* instr, uint16_t setCKEId, uint16_t setCKEMask, uint16_t waitCKEId, uint16_t waitCKEMask,
373 : uint16_t clearType)
374 : {
375 4 : instr->header = InstrHeader(CTRL_TYPE, SETCKBIT_CODE);
376 4 : instr->v2.setCKE.clearType = clearType & 0x1;
377 4 : instr->v2.setCKE.setCKEId = setCKEId;
378 4 : instr->v2.setCKE.setCKEMask = setCKEMask;
379 4 : instr->v2.setCKE.waitCKEId = waitCKEId;
380 4 : instr->v2.setCKE.waitCKEMask = waitCKEMask;
381 4 : instr->v2.setCKE.userData = 0;
382 4 : }
383 :
384 6 : void ClearCKE(
385 : CcuInstr* instr, uint16_t clearCKEId, uint16_t clearMask, uint16_t waitCKEId, uint16_t waitCKEMask,
386 : uint16_t clearType)
387 : {
388 6 : instr->header = InstrHeader(CTRL_TYPE, CLEARCKBIT_CODE);
389 6 : instr->v2.clearCKE.clearType = clearType & 0x1;
390 6 : instr->v2.clearCKE.clearCKEId = clearCKEId;
391 6 : instr->v2.clearCKE.clearMask = clearMask;
392 6 : instr->v2.clearCKE.waitCKEId = waitCKEId;
393 6 : instr->v2.clearCKE.waitCKEMask = waitCKEMask;
394 6 : }
395 :
396 40 : void Jump(
397 : CcuInstr* instr, uint16_t relTarInstrXnId, uint16_t conditionXnId, uint16_t expectedXnId,
398 : uint16_t conditionType)
399 : {
400 40 : instr->header = InstrHeader(CTRL_TYPE, JMP_CODE);
401 40 : instr->v2.jmp.expectedXnId = expectedXnId;
402 40 : instr->v2.jmp.conditionXnId = conditionXnId;
403 40 : instr->v2.jmp.relTarInstrXnId = relTarInstrXnId;
404 40 : instr->v2.jmp.conditionType = conditionType & 0xF;
405 40 : }
406 :
407 0 : void Wait(CcuInstr* instr, uint16_t conditionXnId, uint16_t expectedXnId, uint16_t conditionType)
408 : {
409 0 : instr->header = InstrHeader(CTRL_TYPE, WAIT_CODE);
410 0 : instr->v2.wait.expectedXnId = expectedXnId;
411 0 : instr->v2.wait.conditionXnId = conditionXnId;
412 0 : instr->v2.wait.conditionType = conditionType & 0xF;
413 0 : }
414 :
415 0 : void Fence(CcuInstr* instr) { instr->header = InstrHeader(CTRL_TYPE, FENCE_CODE); }
416 :
417 : // 本端Memory传输到本端MS
418 4 : void TransLocMemToLocMS(
419 : CcuInstr* instr, uint16_t ms, uint16_t src, uint16_t srcToken, uint16_t len, uint16_t offset,
420 : uint16_t setCKEId, uint16_t setCKEMask, const CacheConfig& cacheConfig)
421 : {
422 4 : instr->header = InstrHeader(TRANS_TYPE, TRANSLOCMEMTOLOCMS_CODE);
423 4 : instr->v2.transLocMemToLocMS.msId = ms;
424 4 : instr->v2.transLocMemToLocMS.xsId = src;
425 4 : instr->v2.transLocMemToLocMS.xstId = srcToken;
426 4 : instr->v2.transLocMemToLocMS.xlId = len;
427 4 : instr->v2.transLocMemToLocMS.xoId = offset;
428 4 : instr->v2.transLocMemToLocMS.allocHint = cacheConfig.allocHint & 0x3;
429 4 : instr->v2.transLocMemToLocMS.victimHint = cacheConfig.victimHint & 0x3;
430 4 : instr->v2.transLocMemToLocMS.setCKEId = setCKEId;
431 4 : instr->v2.transLocMemToLocMS.setCKEMask = setCKEMask;
432 4 : }
433 :
434 : // 本端MS传输到本端Memory
435 2 : void TransLocMSToLocMem(
436 : CcuInstr* instr, uint16_t dst, uint16_t dstToken, uint16_t ms, uint16_t len, uint16_t offset,
437 : uint16_t setCKEId, uint16_t setCKEMask, const CacheConfig& cacheConfig)
438 : {
439 2 : instr->header = InstrHeader(TRANS_TYPE, TRANSLOCMSTOLOCMEM_CODE);
440 2 : instr->v2.transLocMSToLocMem.xdId = dst;
441 2 : instr->v2.transLocMSToLocMem.xdtId = dstToken;
442 2 : instr->v2.transLocMSToLocMem.msId = ms;
443 2 : instr->v2.transLocMSToLocMem.xlId = len;
444 2 : instr->v2.transLocMSToLocMem.xoId = offset;
445 2 : instr->v2.transLocMSToLocMem.allocHint = cacheConfig.allocHint & 0x3;
446 2 : instr->v2.transLocMSToLocMem.victimHint = cacheConfig.victimHint & 0x3;
447 2 : instr->v2.transLocMSToLocMem.setCKEId = setCKEId;
448 2 : instr->v2.transLocMSToLocMem.setCKEMask = setCKEMask;
449 2 : }
450 :
451 0 : void TransLocMemToLocMem(
452 : CcuInstr* instr, uint16_t dst, uint16_t dstToken, uint16_t src, uint16_t srcToken, uint16_t len,
453 : uint16_t usedMSId, uint16_t usedMSNum, uint16_t setCKEId, uint16_t setCKEMask,
454 : const CacheConfig& srcCacheConfig, const CacheConfig& dstcacheConfig)
455 : {
456 0 : instr->header = InstrHeader(TRANS_TYPE, TRANSLOCMEMTOLOCMEM_CODE);
457 0 : instr->v2.transLocMemToLocMem.xdId = dst;
458 0 : instr->v2.transLocMemToLocMem.xdtId = dstToken;
459 0 : instr->v2.transLocMemToLocMem.xsId = src;
460 0 : instr->v2.transLocMemToLocMem.xstId = srcToken;
461 0 : instr->v2.transLocMemToLocMem.xlId = len;
462 0 : instr->v2.transLocMemToLocMem.usedMSId = usedMSId;
463 0 : instr->v2.transLocMemToLocMem.msNum = usedMSNum;
464 :
465 0 : instr->v2.transLocMemToLocMem.srcAllocHint = srcCacheConfig.allocHint & 0x3;
466 0 : instr->v2.transLocMemToLocMem.srcVictimHint = srcCacheConfig.victimHint & 0x3;
467 0 : instr->v2.transLocMemToLocMem.dstAllocHint = dstcacheConfig.allocHint & 0x3;
468 0 : instr->v2.transLocMemToLocMem.dstVictimHint = dstcacheConfig.victimHint & 0x3;
469 :
470 0 : instr->v2.transLocMemToLocMem.setCKEId = setCKEId;
471 0 : instr->v2.transLocMemToLocMem.setCKEMask = setCKEMask;
472 0 : }
473 :
474 1 : void TransMem(
475 : CcuInstr* instr, uint16_t dst, uint16_t dstToken, uint16_t src, uint16_t srcToken, uint16_t len,
476 : uint16_t channel, const TransMemNotifyInfo& notify, const TransMemReduceInfo& reduce,
477 : const TransMemConfig& config, uint16_t setCKEId, uint16_t setCKEMask)
478 : {
479 1 : instr->header = InstrHeader(TRANS_TYPE, TRANSMEM_CODE);
480 1 : instr->v2.transMem.xdId = dst;
481 1 : instr->v2.transMem.xdtId = dstToken;
482 1 : instr->v2.transMem.xsId = src;
483 1 : instr->v2.transMem.xstId = srcToken;
484 1 : instr->v2.transMem.xlId = len;
485 1 : instr->v2.transMem.xcId = channel;
486 1 : instr->v2.transMem.xnId = notify.xnId;
487 1 : instr->v2.transMem.xntId = notify.xntId;
488 1 : instr->v2.transMem.value = notify.value;
489 1 : instr->v2.transMem.udfType = reduce.udfType & 0xFF;
490 1 : instr->v2.transMem.reduceDataType = reduce.reduceDataType & 0xF;
491 1 : instr->v2.transMem.reduceOpCode = reduce.reduceOpCode & 0xF;
492 1 : instr->v2.transMem.dmaOpCode = config.dmaOpCode & 0xFF;
493 :
494 1 : instr->v2.transMem.order = config.order & 0x7;
495 1 : instr->v2.transMem.fence = config.fence & 0x1;
496 1 : instr->v2.transMem.cqe = config.cqe & 0x1;
497 1 : instr->v2.transMem.nf = config.nf & 0x1;
498 1 : instr->v2.transMem.udfEnable = config.udfEnable & 0x1;
499 1 : instr->v2.transMem.splitMode = config.splitMode & 0x1;
500 1 : instr->v2.transMem.se = config.se & 0x1;
501 1 : instr->v2.transMem.rmtJettyType = config.rmtJettyType & 0x3;
502 :
503 1 : instr->v2.transMem.src_mode = config.src_mode & 0x1;
504 1 : instr->v2.transMem.dst_mode = config.dst_mode & 0x1;
505 1 : instr->v2.transMem.msIdMode = config.msIdMode & 0x1;
506 :
507 1 : instr->v2.transMem.targetHint = 0x0;
508 :
509 1 : instr->v2.transMem.setCKEId = setCKEId;
510 1 : instr->v2.transMem.setCKEMask = setCKEMask;
511 1 : }
512 :
513 : // 将本端Xn的值写入远端8B地址
514 4 : inline void SyncWtX(
515 : CcuInstr* instr, uint16_t dst, uint16_t dstToken, uint16_t xn, uint16_t channelId, uint16_t setCKEId,
516 : uint16_t setCKEMask)
517 : {
518 4 : instr->header = InstrHeader(TRANS_TYPE, SYNCWTX_CODE);
519 4 : instr->v2.syncWtX.xdId = dst;
520 4 : instr->v2.syncWtX.xdtId = dstToken;
521 4 : instr->v2.syncWtX.xsId = xn;
522 4 : instr->v2.syncWtX.xcId = channelId;
523 :
524 4 : instr->v2.syncWtX.setCKEId = setCKEId;
525 4 : instr->v2.syncWtX.setCKEMask = setCKEMask;
526 4 : }
527 :
528 : // 将本端Xn的值写入远端8B地址并置位远端CKE
529 3 : void SyncWtX(
530 : CcuInstr* instr, uint16_t dst, uint16_t dstToken, uint16_t xn, uint16_t channelId,
531 : const TransMemNotifyInfo& notify, uint16_t setCKEId, uint16_t setCKEMask)
532 : {
533 3 : SyncWtX(instr, dst, dstToken, xn, channelId, setCKEId, setCKEMask);
534 3 : instr->v2.syncWtX.xnId = notify.xnId;
535 3 : instr->v2.syncWtX.xntId = notify.xntId;
536 3 : instr->v2.syncWtX.value = notify.value;
537 :
538 3 : instr->v2.syncWtX.notifyValid = 1;
539 3 : instr->v2.syncWtX.parMode = 1;
540 3 : }
541 :
542 : // 置位远端CKE
543 1 : void SyncWtX(
544 : CcuInstr* instr, const TransMemNotifyInfo& notify, uint16_t channelId, uint16_t setCKEId,
545 : uint16_t setCKEMask)
546 : {
547 1 : SyncWtX(instr, notify.xnId, notify.xntId, notify.value, channelId, setCKEId, setCKEMask);
548 :
549 1 : instr->v2.syncWtX.notifyValid = 0;
550 1 : instr->v2.syncWtX.parMode = 0;
551 1 : }
552 :
553 : // 将本端Xn的值以atomic store add的方式写入远端8B地址
554 0 : void SyncAtX(
555 : CcuInstr* instr, uint16_t dstAddr, uint16_t dstToken, uint16_t srcId, uint16_t channelId, uint16_t setCKEId,
556 : uint16_t setCKEMask)
557 : {
558 0 : instr->header = InstrHeader(TRANS_TYPE, SYNCATX_CODE);
559 0 : instr->v2.syncAtX.xdId = dstAddr;
560 0 : instr->v2.syncAtX.xdtId = dstToken;
561 0 : instr->v2.syncAtX.xsId = srcId;
562 0 : instr->v2.syncAtX.xcId = channelId;
563 :
564 0 : instr->v2.syncAtX.parMode = 1;
565 :
566 0 : instr->v2.syncAtX.setCKEId = setCKEId;
567 0 : instr->v2.syncAtX.setCKEMask = setCKEMask;
568 0 : }
569 :
570 : // MSA~MSH Reduce到 MSA
571 2 : inline void Reduce(
572 : CcuInstr* instr, const uint16_t* ms, uint16_t count, uint16_t castEn, uint16_t dataType, uint16_t setCKEId,
573 : uint16_t setCKEMask, uint16_t XnIdLength)
574 : {
575 : // 由调用者保证传入的count >= 2(reduce的数据源)
576 2 : if (count < CCU_REDUCE_MIN_MS) {
577 0 : HCCL_ERROR("[CcuV2::Reduce] count %u < min %u", count, CCU_REDUCE_MIN_MS);
578 0 : return;
579 : }
580 2 : count -= 2; // CCU指令中指定count数为实际参与运算的MS数减2
581 :
582 18 : for (uint16_t index = 0; index < CCU_REDUCE_MAX_MS; index++) {
583 16 : instr->v2.reduce.msId[index] = ms[index];
584 : }
585 2 : instr->v2.reduce.XnIdLength = XnIdLength;
586 2 : instr->v2.reduce.count = count & 0x7;
587 2 : instr->v2.reduce.castEn = castEn & 0x3;
588 2 : instr->v2.reduce.dataType = dataType & 0x1f;
589 2 : instr->v2.reduce.setCKEId = setCKEId;
590 2 : instr->v2.reduce.setCKEMask = setCKEMask;
591 : }
592 :
593 2 : void ReduceAdd(
594 : CcuInstr* instr, const uint16_t* ms, uint16_t count, uint16_t castEn, uint16_t dataType, uint16_t setCKEId,
595 : uint16_t setCKEMask, uint16_t XnIdLength)
596 : {
597 2 : if (instr == nullptr) {
598 0 : HCCL_ERROR("[CcuV2::ReduceAdd] instr is nullptr!");
599 0 : return;
600 : }
601 2 : instr->header = InstrHeader(REDUCE_TYPE, REDUCE_ADD_CODE);
602 2 : Reduce(instr, ms, count, castEn, dataType, setCKEId, setCKEMask, XnIdLength);
603 : }
604 :
605 0 : void ReduceMax(
606 : CcuInstr* instr, const uint16_t* ms, uint16_t count, uint16_t dataType, uint16_t setCKEId,
607 : uint16_t setCKEMask, uint16_t XnIdLength)
608 : {
609 0 : if (instr == nullptr) {
610 0 : HCCL_ERROR("[CcuV2::ReduceMax] instr is nullptr!");
611 0 : return;
612 : }
613 0 : instr->header = InstrHeader(REDUCE_TYPE, REDUCE_MAX_CODE);
614 0 : Reduce(instr, ms, count, 0, dataType, setCKEId, setCKEMask, XnIdLength);
615 : }
616 :
617 0 : void ReduceMin(
618 : CcuInstr* instr, const uint16_t* ms, uint16_t count, uint16_t dataType, uint16_t setCKEId,
619 : uint16_t setCKEMask, uint16_t xnIdLength)
620 : {
621 0 : if (instr == nullptr) {
622 0 : HCCL_ERROR("[CcuV2::ReduceMin] instr is nullptr!");
623 0 : return;
624 : }
625 0 : instr->header = InstrHeader(REDUCE_TYPE, REDUCE_MIN_CODE);
626 0 : Reduce(instr, ms, count, 0, dataType, setCKEId, setCKEMask, xnIdLength);
627 : }
628 :
629 30 : std::string ParseLoadSqeArgsToX(const CcuInstr* instr)
630 : {
631 30 : uint16_t xnId = instr->v2.loadSqeArgsToX.xnId;
632 30 : uint16_t sqeArgsId = instr->v2.loadSqeArgsToX.sqeArgsId;
633 30 : uint16_t setCKEId = instr->v2.loadSqeArgsToX.setCKEId;
634 30 : uint16_t setCKEMask = instr->v2.loadSqeArgsToX.setCKEMask;
635 :
636 : // 使用 StringFormat 格式化字符串
637 : return Hccl::StringFormat(
638 30 : "Load SqeArg[%u] to Xn[%u], Set CKE[%u:%04x]", sqeArgsId, xnId, setCKEId, setCKEMask);
639 : }
640 :
641 499 : std::string ParseLoadImdToXn(const CcuInstr* instr)
642 : {
643 499 : uint16_t xnId = instr->v2.loadImdToX.xnId;
644 499 : uint64_t immediate = instr->v2.loadImdToX.immediate;
645 499 : uint16_t setCKEId = instr->v2.loadImdToX.setCKEId;
646 499 : uint16_t setCKEMask = instr->v2.loadImdToX.setCKEMask;
647 :
648 : // 使用 StringFormat 格式化字符串
649 : return Hccl::StringFormat(
650 499 : "Load immediate[%llu] to Xn[%u], Set CKE[%u:%04x]", immediate, xnId, setCKEId, setCKEMask);
651 : }
652 :
653 0 : std::string ParseClearX(const CcuInstr* instr)
654 : {
655 0 : uint16_t xnId = instr->v2.clearX.xnId;
656 0 : uint16_t xmId = instr->v2.clearX.xmId;
657 0 : uint16_t setCKEId = instr->v2.clearX.setCKEId;
658 0 : uint16_t setCKEMask = instr->v2.clearX.setCKEMask;
659 :
660 : // 使用 StringFormat 格式化字符串
661 : return Hccl::StringFormat(
662 0 : "CleanX: xnId[%u] to xmId[%u], Set CKE[%u:%04x]", xnId, xmId, setCKEId, setCKEMask);
663 : }
664 :
665 212 : std::string ParseNop(const CcuInstr* instr)
666 : {
667 : (void)instr;
668 212 : return Hccl::StringFormat("Nop");
669 : }
670 :
671 232 : std::string ParseAdd(const CcuInstr* instr)
672 : {
673 232 : uint16_t xdId = instr->v2.operate.xdId;
674 232 : uint16_t xnId = instr->v2.operate.xnId;
675 232 : uint16_t xmId = instr->v2.operate.xmId;
676 232 : uint16_t setCKEId = instr->v2.operate.setCKEId;
677 232 : uint16_t setCKEMask = instr->v2.operate.setCKEMask;
678 232 : uint16_t parMode = instr->v2.operate.parMode;
679 :
680 : // 使用 StringFormat 格式化字符串
681 232 : if (instr->v2.operate.parMode == 0) {
682 : return Hccl::StringFormat(
683 : "AddI:xdId[%u] = xnId[%u] + immediata[%u], Set CKE[%u:%04x], parMode[%u]", xdId, xnId, xmId,
684 122 : setCKEId, setCKEMask, parMode);
685 : } else {
686 : return Hccl::StringFormat(
687 : "Add:xdId[%u] = xnId[%u] + xmId[%u], Set CKE[%u:%04x], parMode[%u]", xdId, xnId, xmId, setCKEId,
688 110 : setCKEMask, parMode);
689 : }
690 : }
691 :
692 8 : std::string ParseSub(const CcuInstr* instr)
693 : {
694 8 : uint16_t xdId = instr->v2.operate.xdId;
695 8 : uint16_t xnId = instr->v2.operate.xnId;
696 8 : uint16_t xmId = instr->v2.operate.xmId;
697 8 : uint16_t setCKEId = instr->v2.operate.setCKEId;
698 8 : uint16_t setCKEMask = instr->v2.operate.setCKEMask;
699 8 : uint16_t parMode = instr->v2.operate.parMode;
700 :
701 : // 使用 StringFormat 格式化字符串
702 8 : if (instr->v2.operate.parMode == 0) {
703 : return Hccl::StringFormat(
704 : "SubI:xdId[%u] = xnId[%u] - immediata[%u], Set CKE[%u:%04x], parMode[%u]", xdId, xnId, xmId,
705 4 : setCKEId, setCKEMask, parMode);
706 : } else {
707 : return Hccl::StringFormat(
708 : "Sub:xdId[%u] = xnId[%u] - xmId[%u], Set CKE[%u:%04x], parMode[%u]", xdId, xnId, xmId, setCKEId,
709 4 : setCKEMask, parMode);
710 : }
711 : }
712 :
713 8 : std::string ParseMul(const CcuInstr* instr)
714 : {
715 8 : uint16_t xdId = instr->v2.operate.xdId;
716 8 : uint16_t xnId = instr->v2.operate.xnId;
717 8 : uint16_t xmId = instr->v2.operate.xmId;
718 8 : uint16_t setCKEId = instr->v2.operate.setCKEId;
719 8 : uint16_t setCKEMask = instr->v2.operate.setCKEMask;
720 8 : uint16_t parMode = instr->v2.operate.parMode;
721 :
722 : // 使用 StringFormat 格式化字符串
723 8 : if (instr->v2.operate.parMode == 0) {
724 : return Hccl::StringFormat(
725 : "MulI:xdId[%u] = xnId[%u] * immediata[%u], Set CKE[%u:%04x], parMode[%u]", xdId, xnId, xmId,
726 4 : setCKEId, setCKEMask, parMode);
727 : } else {
728 : return Hccl::StringFormat(
729 : "Mul:xdId[%u] = xnId[%u] * xmId[%u], Set CKE[%u:%04x], parMode[%u]", xdId, xnId, xmId, setCKEId,
730 4 : setCKEMask, parMode);
731 : }
732 : }
733 :
734 26 : std::string ParseAnd(const CcuInstr* instr)
735 : {
736 26 : uint16_t xdId = instr->v2.operate.xdId;
737 26 : uint16_t xnId = instr->v2.operate.xnId;
738 26 : uint16_t xmId = instr->v2.operate.xmId;
739 26 : uint16_t setCKEId = instr->v2.operate.setCKEId;
740 26 : uint16_t setCKEMask = instr->v2.operate.setCKEMask;
741 :
742 : // 使用 StringFormat 格式化字符串
743 : return Hccl::StringFormat(
744 26 : "And:xdId[%u] = xnId[%u] & xmId[%u], Set CKE[%u:%04x]", xdId, xnId, xmId, setCKEId, setCKEMask);
745 : }
746 :
747 8 : std::string ParseOr(const CcuInstr* instr)
748 : {
749 8 : uint16_t xdId = instr->v2.operate.xdId;
750 8 : uint16_t xnId = instr->v2.operate.xnId;
751 8 : uint16_t xmId = instr->v2.operate.xmId;
752 8 : uint16_t setCKEId = instr->v2.operate.setCKEId;
753 8 : uint16_t setCKEMask = instr->v2.operate.setCKEMask;
754 :
755 : // 使用 StringFormat 格式化字符串
756 : return Hccl::StringFormat(
757 8 : "Or:xdId[%u] = xnId[%u] | xmId[%u], Set CKE[%u:%04x]", xdId, xnId, xmId, setCKEId, setCKEMask);
758 : }
759 :
760 4 : std::string ParseXor(const CcuInstr* instr)
761 : {
762 4 : uint16_t xdId = instr->v2.operate.xdId;
763 4 : uint16_t xnId = instr->v2.operate.xnId;
764 4 : uint16_t xmId = instr->v2.operate.xmId;
765 4 : uint16_t setCKEId = instr->v2.operate.setCKEId;
766 4 : uint16_t setCKEMask = instr->v2.operate.setCKEMask;
767 :
768 : // 使用 StringFormat 格式化字符串
769 : return Hccl::StringFormat(
770 4 : "Xor:xdId[%u] = xnId[%u] ^ xmId[%u], Set CKE[%u:%04x]", xdId, xnId, xmId, setCKEId, setCKEMask);
771 : }
772 :
773 2 : std::string ParseNot(const CcuInstr* instr)
774 : {
775 2 : uint16_t xdId = instr->v2.operate.xdId;
776 2 : uint16_t xnId = instr->v2.operate.xnId;
777 2 : uint16_t setCKEId = instr->v2.operate.setCKEId;
778 2 : uint16_t setCKEMask = instr->v2.operate.setCKEMask;
779 :
780 : // 使用 StringFormat 格式化字符串
781 2 : return Hccl::StringFormat("Not:xdId[%u] = ~xnId[%u], Set CKE[%u:%04x]", xdId, xnId, setCKEId, setCKEMask);
782 : }
783 :
784 8 : std::string ParseShl(const CcuInstr* instr)
785 : {
786 8 : uint16_t xdId = instr->v2.operate.xdId;
787 8 : uint16_t xnId = instr->v2.operate.xnId;
788 8 : uint16_t xmId = instr->v2.operate.xmId;
789 8 : uint16_t shiftType = instr->v2.operate.shiftType;
790 8 : uint16_t setCKEId = instr->v2.operate.setCKEId;
791 8 : uint16_t setCKEMask = instr->v2.operate.setCKEMask;
792 :
793 : // 使用 StringFormat 格式化字符串
794 8 : if (shiftType == 0) {
795 : return Hccl::StringFormat(
796 : "logic left shift:xdId[%u] = xnId[%u] << xmId[%u], Set CKE[%u:%04x]", xdId, xnId, xmId, setCKEId,
797 8 : setCKEMask);
798 : } else {
799 : return Hccl::StringFormat(
800 : "arithmetic left shift:xdId[%u] = xnId[%u] << xmId[%u], Set CKE[%u:%04x]", xdId, xnId, xmId,
801 0 : setCKEId, setCKEMask);
802 : }
803 : }
804 :
805 18 : std::string ParseShr(const CcuInstr* instr)
806 : {
807 18 : uint16_t xdId = instr->v2.operate.xdId;
808 18 : uint16_t xnId = instr->v2.operate.xnId;
809 18 : uint16_t xmId = instr->v2.operate.xmId;
810 18 : uint16_t shiftType = instr->v2.operate.shiftType;
811 18 : uint16_t setCKEId = instr->v2.operate.setCKEId;
812 18 : uint16_t setCKEMask = instr->v2.operate.setCKEMask;
813 :
814 : // 使用 StringFormat 格式化字符串
815 18 : if (shiftType == 0) {
816 : return Hccl::StringFormat(
817 : "logic right shift:xdId[%u] = xnId[%u] >> xmId[%u], Set CKE[%u:%04x]", xdId, xnId, xmId, setCKEId,
818 18 : setCKEMask);
819 : } else {
820 : return Hccl::StringFormat(
821 : "arithmetic right shift:xdId[%u] = xnId[%u] >> xmId[%u], Set CKE[%u:%04x]", xdId, xnId, xmId,
822 0 : setCKEId, setCKEMask);
823 : }
824 : }
825 :
826 0 : std::string ParseLoadFromMem(const CcuInstr* instr)
827 : {
828 0 : uint16_t xdId = instr->v2.load.xdId;
829 0 : uint16_t xsId = instr->v2.load.xsId;
830 0 : uint16_t xstId = instr->v2.load.xstId;
831 0 : uint16_t xlId = instr->v2.load.xlId;
832 0 : uint16_t allocHint = instr->v2.load.allocHint;
833 0 : uint16_t victimHint = instr->v2.load.victimHint;
834 0 : uint16_t setCKEId = instr->v2.load.setCKEId;
835 0 : uint16_t setCKEMask = instr->v2.load.setCKEMask;
836 0 : uint16_t dstType = instr->v2.load.dstType;
837 :
838 : return Hccl::StringFormat(
839 : "LoadFromMem: xdId[%u] xsId[%u] xstId[%u] xlId[%u], allocHint[%u], victimHint[%u], setCKEId[%u], "
840 : "setCKEMask[%u] dstType[%u]",
841 0 : xdId, xsId, xstId, xlId, allocHint, victimHint, setCKEId, setCKEMask, dstType);
842 : }
843 :
844 0 : std::string ParseStoreXToMem(const CcuInstr* instr)
845 : {
846 0 : uint16_t xdId = instr->v2.store.xdId;
847 0 : uint16_t xdtId = instr->v2.store.xdtId;
848 0 : uint16_t xsId = instr->v2.store.xsId;
849 0 : uint16_t xlId = instr->v2.store.xlId;
850 0 : uint16_t xhId = instr->v2.store.xhId;
851 0 : uint16_t srcType = instr->v2.store.srcType;
852 0 : uint16_t allocHint = instr->v2.store.allocHint;
853 0 : uint16_t victimHint = instr->v2.store.victimHint;
854 0 : uint16_t storeType = instr->v2.store.storeType;
855 0 : uint16_t hscbType = instr->v2.store.hscbType;
856 0 : uint16_t hscbBroadCastDstType = instr->v2.store.hscbBroadCastDstType;
857 0 : uint16_t setCKEId = instr->v2.store.setCKEId;
858 0 : uint16_t setCKEMask = instr->v2.store.setCKEMask;
859 :
860 : // 使用 StringFormat 格式化字符串
861 : return Hccl::StringFormat(
862 : "StoreXToMem: xdId[%u] xdtId[%u], xsId[%u], xlId[%u], xhId[%u], srcType[%u], allocHint[%u], "
863 : "victimHint[%u], storeType[%u], hscbType[%u], hscbBroadCastDstType[%u], set CKE[%u:%04x]",
864 : xdId, xdtId, xsId, xlId, xhId, srcType, allocHint, victimHint, storeType, hscbType,
865 0 : hscbBroadCastDstType, setCKEId, setCKEMask);
866 : }
867 :
868 38 : std::string ParseLoop(const CcuInstr* instr)
869 : {
870 38 : uint16_t startInstrId = instr->v2.loop.startInstrId;
871 38 : uint16_t endInstrId = instr->v2.loop.endInstrId;
872 38 : uint16_t xmId = instr->v2.loop.xmId;
873 38 : uint16_t xnId = instr->v2.loop.xnId;
874 38 : uint16_t xpId = instr->v2.loop.xpId;
875 38 : uint16_t wishCKEBit = instr->v2.loop.wishCKEBit;
876 38 : uint16_t mode = instr->v2.loop.mode;
877 :
878 : // 使用 StringFormat 格式化字符串
879 : return Hccl::StringFormat(
880 : "Loop From startInstrId[%u] to endInstrId[%u] with iterNumXn[%u], OffsetXn[%u], ContextIdXn[%u],"
881 : "wishCKEBit[%u], mode[%u]",
882 38 : startInstrId, endInstrId, xmId, xnId, xpId, wishCKEBit, mode);
883 : }
884 :
885 18 : std::string ParseLoopGroup(const CcuInstr* instr)
886 : {
887 18 : uint16_t startLoopInstrId = instr->v2.loopGroup.startLoopInstrId;
888 18 : uint16_t xnId = instr->v2.loopGroup.xnId;
889 18 : uint16_t xmId = instr->v2.loopGroup.xmId;
890 18 : uint16_t xpId = instr->v2.loopGroup.xpId;
891 :
892 : // 使用 StringFormat 格式化字符串
893 : return Hccl::StringFormat(
894 : "LoopGroup From startLoopInstrId[%u] with loopGroupXn[%u], resOffsetXn[%u], xnOffset[%u]",
895 18 : startLoopInstrId, xnId, xmId, xpId);
896 : }
897 :
898 80 : std::string ParseJump(const CcuInstr* instr)
899 : {
900 80 : uint16_t relTarInstrXnId = instr->v2.jmp.relTarInstrXnId;
901 80 : uint16_t conditionXnId = instr->v2.jmp.conditionXnId;
902 80 : uint16_t expectedXnId = instr->v2.jmp.expectedXnId;
903 80 : uint16_t conditionType = instr->v2.jmp.conditionType;
904 :
905 : // 使用 StringFormat 格式化字符串
906 : return Hccl::StringFormat(
907 : "When conditionXn[%u] condition with[%u] expectedXn[%u], Jump To RelInstrIdXn[%u]", conditionXnId,
908 80 : conditionType, expectedXnId, relTarInstrXnId);
909 : }
910 :
911 0 : std::string ParseWait(const CcuInstr* instr)
912 : {
913 0 : uint16_t conditionXnId = instr->v2.wait.conditionXnId;
914 0 : uint16_t expectedXnId = instr->v2.wait.expectedXnId;
915 0 : uint16_t conditionType = instr->v2.wait.conditionType;
916 :
917 : // 使用 StringFormat 格式化字符串
918 : return Hccl::StringFormat(
919 0 : "Wait conditionXn[%u] condition with[%u] expectedXn[%u]", conditionXnId, conditionType, expectedXnId);
920 : }
921 :
922 0 : std::string ParseFence(const CcuInstr* instr)
923 : {
924 : (void)instr;
925 0 : return Hccl::StringFormat("Fence");
926 : }
927 :
928 23 : std::string ParseSetCKE(const CcuInstr* instr)
929 : {
930 23 : uint16_t setCKEId = instr->v2.setCKE.setCKEId;
931 23 : uint16_t setCKEMask = instr->v2.setCKE.setCKEMask;
932 23 : uint16_t waitCKEId = instr->v2.setCKE.waitCKEId;
933 23 : uint16_t waitCKEMask = instr->v2.setCKE.waitCKEMask;
934 23 : uint16_t clearType = instr->v2.setCKE.clearType;
935 23 : uint64_t userData = instr->v2.setCKE.userData;
936 :
937 : // 使用 StringFormat 格式化字符串
938 : return Hccl::StringFormat(
939 : "Wait CKE[%u:%04x], Set CKE[%u:%04x], clearType[%u], userData[%llu]", waitCKEId, waitCKEMask, setCKEId,
940 23 : setCKEMask, clearType, userData);
941 : }
942 :
943 12 : std::string ParseClearCKE(const CcuInstr* instr)
944 : {
945 12 : uint16_t clearCKEId = instr->v2.clearCKE.clearCKEId;
946 12 : uint16_t clearMask = instr->v2.clearCKE.clearMask;
947 12 : uint16_t waitCKEId = instr->v2.clearCKE.waitCKEId;
948 12 : uint16_t waitCKEMask = instr->v2.clearCKE.waitCKEMask;
949 12 : uint16_t clearType = instr->v2.clearCKE.clearType & 0x1;
950 :
951 : // 使用 StringFormat 格式化字符串
952 : return Hccl::StringFormat(
953 : "Wait CKE[%u:%04x], Clear CKE[%u:%04x], clearType[%u]", waitCKEId, waitCKEMask, clearCKEId, clearMask,
954 12 : clearType);
955 : }
956 :
957 8 : std::string ParseTransLocMemToLocMS(const CcuInstr* instr)
958 : {
959 8 : uint16_t ms = instr->v2.transLocMemToLocMS.msId;
960 8 : uint16_t src = instr->v2.transLocMemToLocMS.xsId;
961 8 : uint16_t srcToken = instr->v2.transLocMemToLocMS.xstId;
962 8 : uint16_t len = instr->v2.transLocMemToLocMS.xlId;
963 8 : uint16_t offset = instr->v2.transLocMemToLocMS.xoId;
964 8 : uint16_t allocHint = instr->v2.transLocMemToLocMS.allocHint;
965 8 : uint16_t victimHint = instr->v2.transLocMemToLocMS.victimHint;
966 8 : uint16_t setCKEId = instr->v2.transLocMemToLocMS.setCKEId;
967 8 : uint16_t setCKEMask = instr->v2.transLocMemToLocMS.setCKEMask;
968 :
969 : // 使用 StringFormat 格式化字符串
970 : return Hccl::StringFormat(
971 : "Trans LocMem[%u:%u] To LocMS[%u] With LengthXn[%u], Offset[%u], Set CKE[%u:%04x], "
972 : "allocHint[%u], victimHint[%u]",
973 8 : src, srcToken, ms, len, offset, setCKEId, setCKEMask, allocHint, victimHint);
974 : }
975 :
976 4 : std::string ParseTransLocMSToLocMem(const CcuInstr* instr)
977 : {
978 4 : uint16_t dst = instr->v2.transLocMSToLocMem.xdId;
979 4 : uint16_t dstToken = instr->v2.transLocMSToLocMem.xdtId;
980 4 : uint16_t ms = instr->v2.transLocMSToLocMem.msId;
981 4 : uint16_t len = instr->v2.transLocMSToLocMem.xlId;
982 4 : uint16_t offset = instr->v2.transLocMSToLocMem.xoId;
983 4 : uint16_t allocHint = instr->v2.transLocMSToLocMem.allocHint;
984 4 : uint16_t victimHint = instr->v2.transLocMSToLocMem.victimHint;
985 4 : uint16_t setCKEId = instr->v2.transLocMSToLocMem.setCKEId;
986 4 : uint16_t setCKEMask = instr->v2.transLocMSToLocMem.setCKEMask;
987 :
988 : // 使用 StringFormat 格式化字符串
989 : return Hccl::StringFormat(
990 : "Trans LocMS[%u] To LocMem[%u:%u] With LengthXn[%u], Offset[%u], Set CKE[%u:%04x], "
991 : "allocHint[%u], victimHint[%u]",
992 4 : ms, dst, dstToken, len, offset, setCKEId, setCKEMask, allocHint, victimHint);
993 : }
994 :
995 0 : std::string ParseTransLocMemToLocMem(const CcuInstr* instr)
996 : {
997 0 : uint16_t dst = instr->v2.transLocMemToLocMem.xdId;
998 0 : uint16_t dstToken = instr->v2.transLocMemToLocMem.xdtId;
999 0 : uint16_t src = instr->v2.transLocMemToLocMem.xsId;
1000 0 : uint16_t srcToken = instr->v2.transLocMemToLocMem.xstId;
1001 0 : uint16_t len = instr->v2.transLocMemToLocMem.xlId;
1002 0 : uint16_t usedMSId = instr->v2.transLocMemToLocMem.usedMSId;
1003 0 : uint16_t msNum = instr->v2.transLocMemToLocMem.msNum;
1004 :
1005 0 : uint16_t srcAllocHint = instr->v2.transLocMemToLocMem.srcAllocHint;
1006 0 : uint16_t srcVictimHint = instr->v2.transLocMemToLocMem.srcVictimHint;
1007 0 : uint16_t dstAllocHint = instr->v2.transLocMemToLocMem.dstAllocHint;
1008 0 : uint16_t dstVictimHint = instr->v2.transLocMemToLocMem.dstVictimHint;
1009 :
1010 0 : uint16_t setCKEId = instr->v2.transLocMemToLocMem.setCKEId;
1011 0 : uint16_t setCKEMask = instr->v2.transLocMemToLocMem.setCKEMask;
1012 :
1013 : // 使用 StringFormat 格式化字符串
1014 : return Hccl::StringFormat(
1015 : "Trans LocMem[%u:%u] To LocMem[%u:%u] With Length[%u], Set CKE[%u:%04x], usedMSId[%u], msNum[%u],"
1016 : "srcAllocHint[%u], srcVictimHint[%u], dstAllocHint[%u], dstVictimHint[%u]",
1017 : src, srcToken, dst, dstToken, len, setCKEId, setCKEMask, usedMSId, msNum, srcAllocHint, srcVictimHint,
1018 0 : dstAllocHint, dstVictimHint);
1019 : }
1020 :
1021 2 : std::string ParseTransMem(const CcuInstr* instr)
1022 : {
1023 2 : uint16_t dst = instr->v2.transMem.xdId;
1024 2 : uint16_t dstToken = instr->v2.transMem.xdtId;
1025 2 : uint16_t src = instr->v2.transMem.xsId;
1026 2 : uint16_t srcToken = instr->v2.transMem.xstId;
1027 2 : uint16_t len = instr->v2.transMem.xlId;
1028 2 : uint16_t channel = instr->v2.transMem.xcId;
1029 :
1030 2 : uint16_t notifyXnId = instr->v2.transMem.xnId;
1031 2 : uint16_t notifyXntId = instr->v2.transMem.xntId;
1032 2 : uint16_t notifyValue = instr->v2.transMem.value;
1033 :
1034 2 : uint16_t reduceUdfType = instr->v2.transMem.udfType;
1035 2 : uint16_t reduceDataType = instr->v2.transMem.reduceDataType;
1036 2 : uint16_t reduceOpCode = instr->v2.transMem.reduceOpCode;
1037 :
1038 2 : uint16_t configOpCode = instr->v2.transMem.dmaOpCode;
1039 2 : uint16_t configOrder = instr->v2.transMem.order;
1040 2 : uint16_t configFence = instr->v2.transMem.fence;
1041 2 : uint16_t configCqe = instr->v2.transMem.cqe;
1042 2 : uint16_t configNf = instr->v2.transMem.nf;
1043 2 : uint16_t configUdfEnable = instr->v2.transMem.udfEnable;
1044 2 : uint16_t configSplitMode = instr->v2.transMem.splitMode;
1045 2 : uint16_t configSe = instr->v2.transMem.se;
1046 2 : uint16_t configRmtJettyType = instr->v2.transMem.rmtJettyType;
1047 2 : uint16_t configTargetHint = instr->v2.transMem.targetHint;
1048 :
1049 2 : uint16_t setCKEId = instr->v2.transMem.setCKEId;
1050 2 : uint16_t setCKEMask = instr->v2.transMem.setCKEMask;
1051 :
1052 2 : uint16_t srcMode = instr->v2.transMem.src_mode;
1053 2 : uint16_t dstMode = instr->v2.transMem.dst_mode;
1054 2 : uint16_t msIdMode = instr->v2.transMem.msIdMode;
1055 :
1056 : // 使用 StringFormat 格式化字符串
1057 : return Hccl::StringFormat(
1058 : "Trans Mem[%u:%u] To Mem[%u:%u] With Len[%u] Use Channel[%u] Set CKE[%u:%04x], notifyXnId[%u], "
1059 : "notifyXntId[%u], notifyValue[%u], reduceUdfType[%u], reduceDataType[%u], reduceOpCode[%u], "
1060 : "configOpCode[%u], Order[%u], Fence[%u], Cqe[%u], Nf[%u], UdfEnable[%u], SplitMode[%u], Se[%u], "
1061 : "RmtJettyType[%u], configTargetHint[%u], srcMode[%u], dstMode[%u], msIdMode[%u]",
1062 : src, srcToken, dst, dstToken, len, channel, setCKEId, setCKEMask, notifyXnId, notifyXntId, notifyValue,
1063 : reduceUdfType, reduceDataType, reduceOpCode, configOpCode, configOrder, configFence, configCqe,
1064 : configNf, configUdfEnable, configSplitMode, configSe, configRmtJettyType, configTargetHint, srcMode,
1065 2 : dstMode, msIdMode);
1066 : }
1067 :
1068 8 : std::string ParseSyncWtX(const CcuInstr* instr)
1069 : {
1070 8 : uint16_t dst = instr->v2.syncWtX.xdId;
1071 8 : uint16_t dstToken = instr->v2.syncWtX.xdtId;
1072 8 : uint16_t xn = instr->v2.syncWtX.xsId;
1073 8 : uint16_t channelId = instr->v2.syncWtX.xcId;
1074 :
1075 8 : uint16_t setCKEId = instr->v2.syncWtX.setCKEId;
1076 8 : uint16_t setCKEMask = instr->v2.syncWtX.setCKEMask;
1077 :
1078 : // 检查是否包含通知信息
1079 8 : bool hasNotify = (instr->v2.syncWtX.notifyValid != 0);
1080 8 : uint16_t parMode = instr->v2.syncWtX.parMode;
1081 8 : uint16_t notifyXnId = hasNotify ? instr->v2.syncWtX.xnId : 0;
1082 8 : uint16_t notifyXntId = hasNotify ? instr->v2.syncWtX.xntId : 0;
1083 8 : uint16_t notifyValue = hasNotify ? instr->v2.syncWtX.value : 0;
1084 :
1085 : // 使用 StringFormat 格式化字符串
1086 8 : if (hasNotify) {
1087 : return Hccl::StringFormat(
1088 : "Sync Xn[%u] To Mem[%u:%u] Use ChannelXn[%u], with notify[%u:%u:%04x], and Set CKE[%u:%04x], "
1089 : "parMode[%u]",
1090 6 : xn, dst, dstToken, channelId, notifyXnId, notifyXntId, notifyValue, setCKEId, setCKEMask, parMode);
1091 : } else {
1092 : return Hccl::StringFormat(
1093 : "Sync Xn[%u] To Mem[%u:%u] Use ChannelXn[%u], and Set CKE[%u:%04x], parMode[%u]", xn, dst, dstToken,
1094 2 : channelId, setCKEId, setCKEMask, parMode);
1095 : }
1096 : }
1097 :
1098 0 : std::string ParseSyncAtX(const CcuInstr* instr)
1099 : {
1100 0 : uint16_t xdId = instr->v2.syncAtX.xdId;
1101 0 : uint16_t xdtId = instr->v2.syncAtX.xdtId;
1102 0 : uint16_t xsId = instr->v2.syncAtX.xsId;
1103 0 : uint16_t xcId = instr->v2.syncAtX.xcId;
1104 0 : uint16_t parMode = instr->v2.syncAtX.parMode;
1105 0 : uint16_t setCKEId = instr->v2.syncAtX.setCKEId;
1106 0 : uint16_t setCKEMask = instr->v2.syncAtX.setCKEMask;
1107 :
1108 : return Hccl::StringFormat(
1109 : "Atomic Sync xsId[%u] To Mem[%u:%u] Use ChannelXn[%u], parMode[%u], setCKEId[%u:%04x]", xsId, xdId,
1110 0 : xdtId, xcId, parMode, setCKEId, setCKEMask);
1111 : }
1112 :
1113 4 : std::string ParseMSListV2(const uint16_t* msId, uint16_t msNum)
1114 : {
1115 4 : std::string res = "MS[";
1116 12 : for (uint16_t i = 0; i < msNum + 2 && i < CCU_REDUCE_MAX_MS; i++) { // 循环范围 0 ~ count+ 2,防止越界
1117 8 : if (i == msNum + 1) {
1118 4 : res += std::to_string(msId[i] / 0x8000) + ":" + std::to_string(msId[i] % 0x8000) + "]";
1119 : } else {
1120 4 : res += std::to_string(msId[i] / 0x8000) + ":" + std::to_string(msId[i] % 0x8000) + ", ";
1121 : }
1122 : }
1123 :
1124 4 : return res;
1125 0 : }
1126 :
1127 4 : std::string ParseReduce(const CcuInstr* instr)
1128 : {
1129 4 : uint16_t reduceType = instr->header.code;
1130 4 : uint16_t count = instr->v2.reduce.count;
1131 4 : uint16_t castEn = instr->v2.reduce.castEn;
1132 4 : uint16_t dataType = instr->v2.reduce.dataType;
1133 4 : uint16_t setCKEId = instr->v2.reduce.setCKEId;
1134 4 : uint16_t setCKEMask = instr->v2.reduce.setCKEMask;
1135 :
1136 : return Hccl::StringFormat(
1137 : "Reduce %s, count[%u], reduceType[%u], castEn[%u] and dataType[%u], Set CKE[%u:%04x]",
1138 4 : ParseMSListV2(instr->v2.reduce.msId, count).c_str(), count, reduceType, castEn, dataType, setCKEId,
1139 8 : setCKEMask);
1140 : }
1141 :
1142 : using ParseInstrFunc = std::string (*)(const CcuInstr*);
1143 : static const std::unordered_map<uint16_t, ParseInstrFunc> g_parseInstrSqeMapV2
1144 : = {{InstrHeader(LOAD_TYPE, LOADSQEARGSTOX_CODE).header, &ParseLoadSqeArgsToX},
1145 : {InstrHeader(LOAD_TYPE, LOADIMDTOX_CODE).header, &ParseLoadImdToXn},
1146 : {InstrHeader(LOAD_TYPE, CLEARX_CODE).header, &ParseClearX},
1147 : {InstrHeader(LOAD_TYPE, NOP_CODE).header, &ParseNop},
1148 : {InstrHeader(LOAD_TYPE, ADD_CODE).header, &ParseAdd},
1149 : {InstrHeader(LOAD_TYPE, SUB_CODE).header, &ParseSub},
1150 : {InstrHeader(LOAD_TYPE, MUL_CODE).header, &ParseMul},
1151 : {InstrHeader(LOAD_TYPE, AND_CODE).header, &ParseAnd},
1152 : {InstrHeader(LOAD_TYPE, OR_CODE).header, &ParseOr},
1153 : {InstrHeader(LOAD_TYPE, XOR_CODE).header, &ParseXor},
1154 : {InstrHeader(LOAD_TYPE, NOT_CODE).header, &ParseNot},
1155 : {InstrHeader(LOAD_TYPE, SHL_CODE).header, &ParseShl},
1156 : {InstrHeader(LOAD_TYPE, SHR_CODE).header, &ParseShr},
1157 : {InstrHeader(LOAD_TYPE, LOAD_CODE).header, &ParseLoadFromMem},
1158 : {InstrHeader(LOAD_TYPE, STORE_CODE).header, &ParseStoreXToMem},
1159 : {InstrHeader(CTRL_TYPE, LOOP_CODE).header, &ParseLoop},
1160 : {InstrHeader(CTRL_TYPE, LOOPGROUP_CODE).header, &ParseLoopGroup},
1161 : {InstrHeader(CTRL_TYPE, JMP_CODE).header, &ParseJump},
1162 : {InstrHeader(CTRL_TYPE, WAIT_CODE).header, &ParseWait},
1163 : {InstrHeader(CTRL_TYPE, FENCE_CODE).header, &ParseFence},
1164 : {InstrHeader(CTRL_TYPE, SETCKBIT_CODE).header, &ParseSetCKE},
1165 : {InstrHeader(CTRL_TYPE, CLEARCKBIT_CODE).header, &ParseClearCKE},
1166 : {InstrHeader(TRANS_TYPE, TRANSLOCMEMTOLOCMS_CODE).header, &ParseTransLocMemToLocMS},
1167 : {InstrHeader(TRANS_TYPE, TRANSLOCMSTOLOCMEM_CODE).header, &ParseTransLocMSToLocMem},
1168 : {InstrHeader(TRANS_TYPE, TRANSLOCMEMTOLOCMEM_CODE).header, &ParseTransLocMemToLocMem},
1169 : {InstrHeader(TRANS_TYPE, TRANSMEM_CODE).header, &ParseTransMem},
1170 : {InstrHeader(TRANS_TYPE, SYNCWTX_CODE).header, &ParseSyncWtX},
1171 : {InstrHeader(TRANS_TYPE, SYNCATX_CODE).header, &ParseSyncAtX},
1172 : {InstrHeader(REDUCE_TYPE, REDUCE_ADD_CODE).header, &ParseReduce},
1173 : {InstrHeader(REDUCE_TYPE, REDUCE_MAX_CODE).header, &ParseReduce},
1174 : {InstrHeader(REDUCE_TYPE, REDUCE_MIN_CODE).header, &ParseReduce}};
1175 :
1176 1252 : std::string ParseInstrV2(const CcuInstr* instr)
1177 : {
1178 1252 : if (instr == nullptr) {
1179 0 : HCCL_ERROR("ParseInstr input nullptr!");
1180 0 : return std::string();
1181 : }
1182 :
1183 1252 : auto it = g_parseInstrSqeMapV2.find(instr->header.header);
1184 1252 : if (it == g_parseInstrSqeMapV2.end()) {
1185 0 : HCCL_ERROR("Not support instr type %u code %u", instr->header.type, instr->header.code);
1186 0 : return std::string();
1187 : }
1188 :
1189 1252 : return it->second(instr);
1190 : }
1191 :
1192 0 : void RelJmp(CcuInstr* instr, uint16_t targetXnId, uint32_t jmpInstrId, uint16_t xn0, uint16_t xn1)
1193 : {
1194 0 : CcuV2::LoadImdToXn(instr++, xn0, jmpInstrId);
1195 0 : CcuV2::LoadImdToXn(instr++, xn1, JMP_TARGET_PC_IF_BRANCH);
1196 0 : CcuV2::Jump(instr++, xn1, targetXnId, xn0, JMP_COND_TYPE_IF);
1197 0 : CcuV2::LoadImdToXn(instr++, xn0, 0x10000 - jmpInstrId);
1198 0 : CcuV2::Add(instr++, targetXnId, targetXnId, xn0);
1199 0 : CcuV2::LoadImdToXn(instr++, xn1, JMP_TARGET_PC_NOP_BRANCH);
1200 0 : CcuV2::Jump(instr++, xn1, 0, 0, JMP_COND_TYPE_UNCOND);
1201 0 : CcuV2::Sub(instr++, targetXnId, targetXnId, xn0);
1202 0 : CcuV2::Nop(instr++);
1203 0 : }
1204 : }; // namespace CcuV2
1205 :
1206 : }; // namespace CcuRep
1207 : }; // namespace hcomm
|