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