3986.net
小网站 大容量 大智慧
相关标签
当前位置:首页 >> 计算机硬件及网络 >>

DSP汇编指令学习笔记


Knowledge
问题
谁在 DSP 的汇编语言中加入了 NOP 指令? NOP 指令加入的条件是什么?

About DSP
1. 2. 3. DSP 是实时数字信号处理的核心和标志。 DSP 分为专用和通用两种类型。专用 DSP 一般采用定点数据结构(一般不支持小数) , 数据结构简单,处理速度快;通用 DSP 灵活性好,但是处理速度有所降低。 DSP 采用取指、译码、执行三个阶段的流水线(Pipeline)技术,缩短了执行时间,提高了 运行速率。 DSP 具有 8 个 Functional unit, 如果并行处理的话, 600MHz 的时钟计算, 以 如果执行的指令是 single cycle 指令,则可以 4800MIPS(指令每秒) 。 DSP 的 8 个 functional Unit,具有独特的功能,对滤波、矩阵运算、FFT(傅里叶变换) 具有

4.

哈弗结构
把指令空间与数据空间隔离的存储方式。 这样实现是为了实现指令的连续读取,而实现 pipeline 流水线结构。 传统哈弗结构:两个独立的存储空间,还使用独立总线。让取指与执行存储独立,加快执行 速度。 改进型哈弗结构:指令与数据的存储空间还是独立的。但是使用公共的总线(地址总线与数 据总线) 。这样实现的原因是因为出现了 CACHE,数据的存储动作大部分被内部的 CACHE 总线承接了, 所以总线冲突的情况会大大减少。 同时让总线的结构与控制变得简单, CACHE 存储的速度也明显快于外设存储器。

冯诺依曼结构:是指令空间与数据空间共享的存放方式。它不能实现 pipeline 的执行过程。

Pipeline(流水线)技术
是把指令的取指-译码和指令的执行独立开来的技术。虽然每条指令的过程还是要经过取指译码-执行三个阶段最少 3 个 CPU Cycle。但是多个指令同时并行先后进行,保证总体的指

1

令吞吐速率理想情况下可以保证在每个指令只要一个 CPU CYCLE。 Pipeline 技术必须要有哈弗结构支持,即必须把指令空间与数据空间隔离存放。

流水线阻断
流水线中阻断现象也十分普遍,下面就各种阻断情况下的流水线性能进行详细分析。 流水线阻断总体有两种情况: 1. 资源冲突阻断: a) 如果前一指令的某 Stage 与后一指令某 Stage 在同一个 Cycle 执行,但是 前一指令此 Stage 占用了后一指此 Stage 的资源,则后一指令此 Stage 的 工作会被延迟执行。 b) 被延迟执行的动作会停留在前一个 Stage 状态,则前一个 Stage 的状态就 不能进入新的指令的动作。 c) 依次前推,则总有一个取指 Stage 的指令被阻断,那么其后一个指令也被阻 断而不能被取指。 d) 所以,每产生一个 Cycle 的阻断,就会让 CPU 的执行延迟一个 Cycle。即此 指令后面的所有指令都会被延迟一个 Cycle 被执行。 e) 解决的方法是:使用 Cache 让存放变得更快;变量集群使用,记录减少变量 存放到 memory 的需要。 2. 跳转阻断: a) 跳转阻断有很多情况产生,比如函数调用/返回,循环的 break/continue, if 等条件判断,循环跳转,中断跳转的产生。 b) 一旦某条指令要进行跳转时, 它就会设置 LR 寄存器, 阻止后续的指令进入执 行 Stage,并修改 PC 指针,执行跳转后的目标代码。 c) 解决的方法是:减少循环、条件判断、分支结构的使用。

DSP Pipeline 技术
DSP 具有 8 个独立的执行单元,所以每个 CYCLE 可以执行 8 条指令(要求其总线宽度是 256bit) 。 即 DSP 是 8 个 pipeline 并行处理的技术。所以 DSP 每个阶段取 8 个指令,然后在译码阶段 把 8 个指令分配到 8 个执行单元去处理。 所以必须保证被同时取的指令之间没有相关性 (即一个指令的执行不需要其他指令的结果参

2

与) ,否则会得到错误的结果。所以,DSP 引入了 NOP 指令,如果不能实现这一的要求, 则 DSP 的编译器, DSP 优化器会在其编译的指令后面添加 NOP 指令。 则 表示此 Cycle 不能 执行 8 条有效指令,只能擦入空指令。则这样就会有某些执行单元在此 CYCLE 空闲了。

DSP Pipeline 阻断
DSP Pipleline 的阻断处理相对比较复杂一些,因为它涉及到 8 独立执行单元的阻断。 1. 资源冲突阻断: a) 如果某个 Unit 因为资源冲突阻断,或者因为一个指令需要多个 Cycle 执行。则此 Unit 会被阻断。 b) 当某个 Unit 被阻断时,其上一个阶段的指令就不能往下传递。一直阻断到此 Unit 的取值动作。 c) 所以当有阻断发生是,FG 并不会请求 8 条指令,而是请求 1-7 条,或者不请求(8 个 Unit 全部阻断了) 。这样没有被阻断的 Unit 还是能够充分运行的。 2. 跳转阻断:http://www.doc88.com/p-908395009795.html a)

NOP
Not dispatched instruction It is an empty instruction in DP packet. 如果一个指令标识需要 Delay N 个 slot,则需要在这个指令后面跟 N 个 NOP 指令(对 于那些自身不带 NOP 的指令,比如 B) (但是对于 BNOP 则不需要的) 。

通过寄存器的定位技巧
1. 查看 NRP 寄存器的值,则可以直接查看在哪个周期的指令异常了(NRP 指令的前一周期就是 crash 的指令) (使用 A10/B10??可以看到此函数的参数) 2. 查看 B3 寄存器的值,跳到此代码段查看前面一个的 Jump 指令。看是 jump 到哪个函数了,则是在此 函数中出异常了。则可以看到是谁调用的此 crash 的函数。 (使用 A4/B4??可以看到 parent 的参数) 3. 如果参数是二维指针,则此参数所在类存一般都是栈内的某个地址。 (可以根据栈空间的特点知道具 体应该是哪个地址)

3

CPU data path & control

说明: 1. Register A 也是由两片寄存器组组成的,A0:A1/ … /A30:A31 的 pair 是分布在两个组片 中的 2. ST path 是把寄存器的值写入内存的路径 3. LD path 是把内存的值加载到寄存器中的路径 4. DA path 是读写寄存器的路径 5. X path 是跨组读写寄存器的路径

A & B path general purpose registers
1. Each A & B path has 32 32-bit register, named A0-A31, B0-B31. 2. It supports 40bit & 64bit value. If value is larger than 32 bit, it needs register-pair. The 32LSB stores in even-numbered register, such A0, and the 8 or 32 MSB stores in odd-numbered register, such A1. 3. General purpose registers can be used for data, address pointers,

4

condition registers.

8 functional units
1. 8 functional units can be divided into 2 groups, G1: L1, S1, M1, D1 for A register path, and G2: L2, S2, M2, D2 for B register path. 2. Each function units has its special function, such as +/-/*/>/<. But some operations can be deal in all units

Unit path
The C6000 CPU has 2 generous purpose register files ( A & B), 8 function units (L1/S1/D1/M1 & L2/S2/M2/D1). The 8 function units have different path to access data or data address: 1. L Path:LD1/LD2: Access data path of A & B register files a) 从 A/B 中读取数据 2. DA1/DA2: access data address path of A & B register files a) 把数据保存到 A/B 中 3. ST1/ST2: write data path of A & B register files a) 把立即数或者控制寄存器保存到 A/B 中 4. 1X/2X: cross path of A & B register files, to access opposite-side. a) 跨 A/B 读取数据 5. 说明: a) 前面三个路径统称为 T 路径(LD、ST、DA) 。在具体汇编指

5

令上,只会显示为 T 或者 X 路径,不会具体显示某一种 T 路 径。 b) X 路径是在跨 A/B 寄存器使用的,用或不用情况是一定的 c) 现在只有使用了 X 路径, 或者 LDW、 STW 指令会显示具体使 用的路径名称。

Register File Cross Paths
1. G1 units can read/write data from/into A registers. And the G2 units can read/write data from/into B registers. So G1 units have cross path to A registers, and G2 units have cross path to B register. 2. At the same time, A registers have cross paths to opposite-B registers, such as Ax is connect to Bx. So function units of A registers can access B register.

6

Normal registers

Reserved by 表示谁负责保存这个寄存器中的值,如果是 Parent,则是 Caller;如果是 Child 则是 called function。 这里的 Parent 与 child 是与某此调用动作相关。如果脱离具体的某此调用,基本所有的函数 都即是 parent 又是 child。或者说,在某此函数调用时,哪些寄存器是在调用之前就要压栈 保存(可能同时赋值的)——parent 类的寄存器;哪些寄存器是在调用后如果使用到了才需 要压栈保存的——child 类寄存器。 寄存器中的值,始终是根据此次调用(即 Crash 时的调用)的参数状态。即 Parent 寄存器保

7

存的 Crash function 的 Caller 的参数;而 child 寄存器保存的是 crash 本函数的参数。所以可 以查看 A10、B10??查看异常函数的参数;查看 A4/B4??查看上层函数的参数。 同一指令周期并行执行的指令,不能同时使用同一寄存器。

SP /B15 & FP/A15 & PC & DP
1. 2. 3. 4. 5. SP /B15:是栈顶指针(B15 可以在 gPdb 查看) 。启动时需要手动初始化。 FP/A15:是本函数的栈底指针。现在没有使用,FP 始终等于 SP。A15 没有使用。 PC:是 PFC(program fetch counter) ,是取指位置,是 jump 指令操作的寄存器(不能在 gPdb 中查看,也没有具体意义,因为异常处理时 PC 也会变) DP:初始化是.bss(为全局变量和静态变量保留(不包含 const 类全局变量) )段的起始 地址。用于指示全局变量的基址。启动时需要手动初始化。

SP & B15 (stack pointer)
B15 就是 SP 的值,它们是同一个寄存器。表示栈顶指针。 SP 指针必须是 8 字节对齐的。Unaligned SP Can Cause Application Crash。 B15 is the stack pointer (SP), which points to the next unused location on the stack。

FP & A15 (frame pointer)
A15 就是 SP 寄存器。
The frame pointer is used to read arguments from the stack and to handle register spilling instructions.

A4:A5 & A3 (function return value)
A4 (或者 A4:A5):是函数返回值(非结构体返回值)存放的寄存器。通常其值的来源是上 一函数的返回值。 A3:如果返回的是一个结构,则返回结构的支持存放在这里。

B3 & IRP & NRP (function return address)
B3:普通函数,当前调用的返回地址。之前调用的返回值已经压入栈中了。 IRP:可掩中断调用返回地址。 NRP:不可掩中断调用返回地址。 B3:
836178A0 AaSysComMsgRelay:

8

836178A0 2246 836178A2 0247

MV.L1 || MV.L2

A4,A1//T1 B4,B0 B3,*SP--[4] C$L37 (PC+40 = 0x836178c8),5//T2 *+A1[0],A0 C$L37 (PC+40 = 0x836178c8),5//T3

836178A4 01BC94F6 || STW.D2T2 836178A8 9014A121 [!A1] BNOP.S1

836178AC 80040264 || [ A1] LDW.D1T1 836178B0 D014A120 836178B4 1000C813 [!A0] BNOP.S1

CALLP.S2

$Tramp$L$PI$$_AaSysComMsgSend (PC+1600 = 0x83617ee0),B3//T4

//跳转到 AaSysComMsgSend 函数(FP? AaSysComMsgSend),并把 T5 的代码的地址保存在 B3 中 836178B8 00002276 || 836178BC E0200003 836178C0 01BC92E6 836178C4 6C6E STW.D1T2 .fphead LDW.D2T2 NOP B0,*+A0[1] n, l, W, BU, nobr, nosat, 0000001 *++SP[4],B3//下一周期 T5 4

PFC & retPC & PCE1
1. 2. 3. PFC is the program fetch counter retPC represents the address of the first instruction of the execute packet in the DC stage of the pipeline PCE1 (program counter) represents the address of the first instruction in the fetch packet in the E1 stage of the pipeline..

Control register file
Table 2-6. Control Registers Acronym Register Name Section AMR Addressing mode register Section 2.8.3 CSR Control status register Section 2.8.4 GFPGFR Galois field multiply control register Section 2.8.5 ICR Interrupt clear register Section 2.8.6 IER Interrupt enable register Section 2.8.7 IFR Interrupt flag register Section 2.8.8 IRP Interrupt return pointer register Section 2.8.9 ISR Interrupt set register Section 2.8.10 ISTP Interrupt service table pointer register Section 2.8.11 NRP Nonmaskable interrupt return pointer register Section 2.8.12 PCE1 Program counter, E1 phase Section 2.8.13 Control Register File Extensions (C64x+ DSP) DIER Debug interrupt enable register Section 2.9.1 DNUM DSP core number register Section 2.9.2 ECR Exception clear register Section 2.9.3 EFR Exception flag register Section 2.9.4 GPLYA GMPY A-side polynomial register Section 2.9.5

9

GPLYB GMPY B-side polynomial register Section 2.9.6 IERR Internal exception report register Section 2.9.7 ILC Inner loop count register Section 2.9.8 ITSR Interrupt task state register Section 2.9.9 NTSR NMI/Exception task state register Section 2.9.10 REP Restricted entry point address register Section 2.9.11 RILC Reload inner loop count register Section 2.9.12 SSR Saturation status register Section 2.9.13 TSCH Time-stamp counter (high 32) register Section 2.9.14 TSCL Time-stamp counter (low 32) register Section 2.9.14 TSR Task state register 这些控制寄存器,直接使用就可以了。TI 会把他们定义为全局变量。比如 extern __cregister volatile unsigned int EFR; 这任何时刻,EFR 表示“EFR”寄存器的值。

Exceptions
Exceptions
1. 2. 3. 4. 外部中断:由 CPU 的外围设备产生的,输入到 CPU 内,产生的中断叫外部中断。如果 是外部严重错误(Fatal error)将会产生 NMI 中断。 内部中断:CPU 内部自己产生的,比如溢出异常、指令异常、内存访问异常、资源冲 突、等,称为内部中断。内部中断会有寄存器记录其产生的原因的。 Reset Interrupt: GPIO 23,强制重启中断。不可掩。 NMI - EXCPHNDL_EFR_NXF(non-maskable interrupt): 是 CPU 硬件错误 a) The NMIE bit in TSR must be set, then NMI will occur b) Setting the global exception enable (GEE) bit in the task state register (TSR) to 1,
this interrupt will behave as an exception.

5. 6. 7. 8.

IXF - EXCPHNDL_EFR_IXF: 是 CPU 计算异常 a) 比如指令异常、内存异常,资源异常、除 0 溢出异常等 EXF - EXCPHNDL_EFR_EXF: 是外设上报到 CPU 的异常 SXF - EXCPHNDL_EFR_SXF: 是软件通过 SWE 指令特意触发的异常,相当于 error2。 所有的异常,在执行结束后都会继续执行(出了断电异常) 。一般芯片的异常后停止运 行的现象,是 APP 软件自己实现的,即在底层运行一个死循环。

CPU control registers
1.PC PCE1) ( 是用来指示下一条要执行的指令的, 即存放的是下一条要执行的指令的地址。

10

几乎所有的 MCU 都不允许 MOV 指令修改 PC 值,这是一个常识。 2.中断服务表指针寄存器 ISTP(interrupt servicetable pointer)用于确定中断服务程序在中断 服务表中的地址。 ISTP 中的字段 ISTB 确定 IST 的地址的基值, 另一字段 HPEINT 确定特定 的中断,并给出这一特定中断取指包在 IST 中的位置。 3.IFR(中断标志寄存器) :显示出有终端请求但尚未得到服务的中断。 4.IER(中断使能寄存器) :使能后禁止中断处理。 5.IRP(可屏蔽中断返回指针寄存器) :包含从可屏蔽中断返回的地址,该中断返回通过指令 BIRP 完成。 6.NRP(不可屏蔽中断返回指针寄存器) :包含从不可屏蔽中断返回的地址,该中断返回通 过指令 BNRP 完成。 7.CSR(控制状态寄存器) :控制全局使能或禁止中断。 8.AMR(寻址模式寄存器) :制定是否使用线性或循环寻址,若循环寻址还指定循环地址大 小。 9.EN(端结方式) :1=小端终结;0=大端终结。 10.Event Encoder (事件编码器) :事件寄存器 ER(包括 ERL 和 ERH)用于捕获对应于 64 个 EDMA 通道的事件。在事件编码器中只是负责提交请求,事件的优先局依赖于 EDMA 通 道参数的设定,并且在 Transfer Crossbar 中才正式排定。 11.协处理器控制位 CR0 中的位 1~4 分别标记位 MP(算术存在位) 、EM(模拟位) 、TS(任务切换位)和 ET (扩展类型位) ,它们控制浮点协处理器的操作。 EM 位控制浮点指令的执行是用软件模拟,还是由硬件执行。EM=0 时,硬件控制浮点指令 传送到协处理器;EM=1 时,浮点指令由软件模拟。 12.中断描述符表寄存器 IDTR IDTR 长 48 位,高 32 位存段基址,低 16 位存段界线。由于 80386 只支持 256 个中断/异常, 所以 IDT 表的最大长度是 2K, 以字节位单位的段界线为 7FFH。 IDTR 表示 IDT 表的方式与 GDTR 表示 GDT 表的方式相同。

11

Pipeline
Pipeline Stages
All instructions require the same number of pipeline phases for fetch and decode, but require a varying number of execute phases.

Fetch -- Decode – Execute

Knowledge points
Network materials
5stage 的 F/D - Fetch (from cache) and decode four instructions G - Group up to four instructions R - Read register file and forward operands E - Execute operations, read memory W - Updates select control registers, complete writes

Fetch packet
就是一次获取的指令。即||获取的指令包。 一个指令包最少 1 条指令,最多 8 条。

Execute packet
是执行单元内部的概念。 即一条被执行的指令。 一个 Fetch packet 可以包含 1-8 个 Execute packet

12

Fetch package steps
1. 2. 3. 4. PG: generate a program address PS: send a request to read program PW: wait for response PR: Receive a program instruction

Decode package steps(P512)
1. 2. DP: Instruction dispatch a) a) 从fetch packet中提取execute packets并送到对应的执行单元中。 在执行单元中的第一个动作,解析DP送进来的execute packet。 DC: Instruction decode

Execute stage
Execute stage has 5 phase, E1-E5. Each phase need which Each phase has its own special functions. Different instructions require different E phases to complete their executions. 执行阶段最多需要 5 个步骤。不同的指令需要的步骤也是不一样的。 从执行的步骤的角度看,DSP 相关的指令,大致可以分为 6 类(包括 NOP 有 7 类) ,下图 是每类指令需要的执行步骤,以及执行完这些步骤所需要的 Slot (CPU Cycle)。 Delay slot:是 E1 步骤执行完后,此类指令后续执(或者等待)行还需要的 CPU Cycle 数。 只有在 Delay Slot 之后,指令的结果才是可用的。 6 类指令的具体情况是: 1. Single Cycle 类:单 Cycle 指令类,只有数据的计算存储。这类指令只需要 E1 步骤,需 要一个 CPU Cycle。这个指令是计算立即数,并把计算的结果保存的 AB 寄存器中。 2. 16bit * 16bit (.M Unit 执行)指令:这个指令需要 2 个 Cycle。 3. store:是指存放到 memory 中。它需要 3 个步骤 E1、E2、E3,但是只需要 1 个 Cycle。 这是因为,在数据 Access memory 后,如果后面是 Load 动作,则直接可以从 E4 开始 了,所以相当于 Store 只用了 1 个 Cycle。

13

Summary
1. 2. 取值是根据PC指令,从内存中取出指令;取数是值根据寄存器记录的内存地址,从此 地址中获取数据。 此DSP指令读取与数据读取是走同一Pipeline中的,但是在不同的阶段完成的。指令获 取是在PG/PS/PW/PR/DP中完成的,它把指令送到执行单元。执行单元经过DC,后开始 执行指令。在执行指令时,如果需要Load数据,则会在E1/.../E5中完成对数据的操作。 取指令的5个阶段与取数据的5个阶段的过程是类似的。如下图:

3.

4.

5.

当数据或者指令都L1cache中(L1D、L1P中) ,则取值与取数都不会有额外的CPU stall 产生。 a) 但是如果指令不在L1P中,则取值会在PW阶段产生大等于1个Cycle的stall。 b) 但是如果指令不在L1D中,则取值会在E3阶段产生大等于1个Cycle的stall。 c) 当CPU产生Stall,则会前向传递进行Stall积压指令。 Stall就是CPU需要额外的N周期去获取资源时,则会停止取指N周期。

14

6 types of instructions Single cycle instructions
Most DSP instructions are single-cycle instructions, which means they have only one execution phase (E1).

Store Instructions

Three steps E1/E2/E3: E1: get target address from register file, and calculate the access address of memory. E2: send this address to Memory controller. Get data from register file and send it to memory controller

15

E3: operating the memory. Write the data into the memory.

Branch Instructions

Instructions
Units of Instruction

16

Conditional Operations

执行条件寄存器判断。

17

A0/A1/A2 B0/B1/B2 为 0(Z=0)时才执行;或者不为 0(Z = 1)是才执行。 Creg 3bit 决定对哪个寄存器进行判断。

Operations
1. 2. 3. Src ? dst : 32 bit data Src_h:Src_l ? dst_h:dst_l : 40 bit data. src_o:Src_e ? dst_o:dst_e : 64 bit data H is 8msb o is 32 msb

Instruction description Description format
EXAMPLE (.unit) src, dst .unit = .L1, .L2, .S1, .S2, .D1, .D2 src and dst indicate source and destination, respectively. The (.unit) dictates which functional unit the instruction is mapped to (.L1, .L2, .S1, .S2, .M1, .M2, .D1, or .D2).

可见, DSP 的汇编已经制定命令执行的 Unit 了, dispatch 动作仅仅是根据指令进行分发而已。 指令格式有以下特点: 1. 在同一个指令中,使用不同的 unit,与操作数的 bit 数什么的都有关系。所以从指令使 用的 unit,可以看到很多关于操作数的性质。 2. 指令中已经包含了指令的 unit,所以 dispatch 动作仅仅是根据指令进行分发 3.

ABS
ABS Absolute Value With Saturation
Syntax ABS (.unit) src2, dst

//for 32bit data //for 40bit data

or ABS (.unit) src2_h:src2_l, dst_h:dst_l unit = .L1 or .L2
Instruction Type Single-cycle Examples Example 1
ABS .L1 A1,A5

Delay Slots 0

Compatibility C62x, C64x, and C64x+ CPU

Examples Example 2
ABS .L1 A1:A0,A5:A4

18

x cross path for src2; 0 = do not use cross path, 1 = use cross path op opfield; field within opcode that specifies a unique instruction: 指令号 p parallel execution; 0 = next instruction is not executed in parallel, 1 = next instruction is executed in parallel s side A or B for destination; 0 = side A, 1 = side B.

ABS2 (for 16bit)
ABS2 Absolute Value With Saturation, Signed, Packed 16-Bit
Syntax ABS2 (.unit) src2, dst

unit = .L1 or .L2
Instruction Type Single-cycle Delay Slots 0 Compatibility C64x and C64x+ CPU

Src2:是两个独立的 16bit 的数据。 Dst:是两个独立的 16bit 的数据。

ADD 系列(ADD/ADDAB/ADDKPC)
ADD
ADD Add Two Signed Integers Without Saturation
Syntax ADD (.unit) src1, src2, dst

or ADD (.L1 or .L2) src1, src2_h:src2_l, dst_h:dst_l or ADD (.D1 or .D2) src2, src1, dst (if the cross path form is not used) or ADD (.D1 or .D2) src1, src2, dst (if the cross path form is used) or ADD (.D1 or .D2) src2, src1, dst (if the cross path form is used with a constant) unit = .D1, .D2, .L1, .L2, .S1, .S2
Instruction Type Single-cycle Delay Slots 0

19

Compatibility C62x, C64x, and C64x+ CPU

Execution:

Src1 + Src2 --> dst

ADDAB
ADDAB Add Using Byte Addressing Mode
Syntax ADDAB (.unit) src2, src1, dst (C64x and C64x+ CPU)

or ADDAB (.unit) B14/B15, ucst15, dst (C64x+ CPU) unit = .D1 or .D2
Compatibility C62x, C64x, and C64x+ CPU

sint Signed 32-bit integer value ucstn n-bit unsigned constant field (for example, ucst5)

Execution:

src2 + src1 → dst

ADDK
Syntax ADDK (.unit) cst, dst

20

unit = .S1 or .S2 Description A 16-bit signed constant, cst16, is added to the dst register specified. The result is

placed in dst.
Execution

if (cond) cst16 + dst → dst else nop

ADDKPC
ADDKPC (.unit) src1, dst, src2

1. 2. 3.

把Src1的值设置到dst中,并NOP src2 个cycle. 即本指令需要src2 + 1个slot才能完成。 这个指令并不是跳转指令, 仅仅是同时完成了高低16bit赋值以及NOP控制的一个指 令。如果NOP为0此,则高低16bit赋值仅仅为1个cycle

SWE
SWE Software Exception
Syntax SWE

unit = none
Compatibility C64x+ CPU Description:

Software sprint an exception by this instruction. It will set SXF bit in EFR to 1.
And when it complete, CPU will continue with the instructions specified by NRP register

SWENR no-return SWE
It is the same as SWE, but NRP will be invalid.

21

MV 系列
1. 2. 3. 4. 5. 6. MV (.unit) src2, dst:Move From Register to Register AB 寄存器之前的 MV MVC (.unit) src2, dst:Move Data from AB register to Control register, such as ARM/IRP MVD (.unit) src2, dst: Move From Register to Register, 和 MV 一样, 但是需要 3 个 NOP。 MVK (.Unit) src dst 把有符号数的立即数赋值到 dst 中 MVKH (.unit) cst, dst:把立即数的 MSB 16bit 赋值到 dst 的 MSB 16bit MVKLH (.unit) cst, dst:把立即数的 LSB 16bit 赋值到 dst 的 MSB 16bit

大小对比操作
1.
CMPLT (.unit) src1, src2, dst if (src1 < src2), 1 → dst
Delay Slots 0

a)
b) c)

else else 0 → dst

src1 是否小于 src2,是的话 dst=1;否则等 0

2.

CMPEQ (.unit) src1, src2, dst

a) b)

if (src1 == src2), 1 → dst else else 0 → dst
Delay Slots 0

逻辑操作系列
AND Src1 Src2 dst:Src1 安位与 Src2 结果赋值到 dst

Store 系列(STDW/)
1. 2. 3. 所有的 store 指令的 delay slot 都是 0,但是数据真正写入内存的 delay slot = 3. 就是说,如果要从内存中直接去看数值的改变需要 4 个 slot 后。 但是在第一个 slot 后,如果代码去 Load 此地址的值,则能够 Load 新的值。因为系统 并没有真正的直接从内存中获取, 而是半路拦截了正在保存的数据 (因为是同一地址) , 所 delay slot 为 0 了。

STB
STB Store Byte to Memory With a 5-Bit Unsigned Constant Offset or Register Offset 存储寄存器的低8bit到内存中。

SIZE = 1B

22

STH
SIZE = 2B

STW
SIZE = 4B

STDW (DW store (8Bytes))
SIZE = 8B STDW (.unit) src, *+baseR[ucst5] DW store
if (cond) src → mem mem = *BaseR + (ucst5 * 8) 或者

STDW (.unit) src, *+baser(ucst5)
if (cond) src → mem mem = *BaseR + ucst5
Delay Slots 0

23

Load 系列(LDW)
LDW
Syntax

Register Offset Unsigned Constant Offset

LDW (.unit) *+baseR[offsetR], dst LDW (.unit) *+baseR[ucst5], dst unit = .D1 or .D2
Delay Slots 4 for loaded value

Example LDW .D1 *A10,B1 把 *A10的值Load到B1.但是B1只有在执行后4 slot后才会有可用的值。 也就是说,这个指令要5个slot才能完成。

jump(B/BNOP/BDEC/ CALLP)
Only PFC jump(B/BNOP/BDEC)
1. B: a) 修改 FP 指针的值,让程序后面从一个新的位置开始取指(PG、PS、PW、PR 的开 始) b) B Src: Src? PFC B IRP: IRP? PFC B NRP: NRP? PFC c) Delay 5 个 slot,即在执行此指令后 5 个 slot 时才开始真正的跳转。 BNOP: a) 修改 PFC 指针的值的同时,后面添加 N 个 NOP 指令。一般都要添加 4 个,因为 B 指令跳转到新的地方取指后,新取的指令需要等待取指、分发才会进入执行阶段, 所以需要等待。 b) Delay 5 个 slot 不包括其包含的 NOP 数) 即在执行此指令后 5 个 slot 时才开始真 ( , 正的跳转。 BDEC (BDEC (.unit) src, dst) : a) 如果 dst>=0,则先 dst -= 1, 后 PFC = src。 b) 否则,直接 PFC = src c) Delay Slots 5

2.

3.

PCE1 jump(CALLP/)
1.
CALLP (.unit) label, A3/B3:

Execution(跳转到label,并把返回值保存在A3或B3中)

24

(cst21 << 2) + PCE1 →PFC (label –> PFC) if (unit = S2), retPC → B3 else if (unit = S1), retPC → A3 nop 5 (Delay Slots 5) (注: cst21 = (label - PCE1) >> 2)

a) b)

这个在修改 FP 的同时,会保存 retPC 指针,用于返回 return 地址。在 return 后会 把这个地址赋值给 PFC,然后从这条指令开始重新执行。
Delay Slots 5

SPLOOP 系列(SPLOOPD/
SPLOOP Software Pipelined Loop (SPLOOP) Buffer Operation With Delayed Testing 是通过延时,获取 L2/Ext 内存的数据 Copy 到 L1 Memory 中。

典型汇编语句解析
STXX REG *B15--[1]
把 REG 的值保存到内存中。 具体的操作 SIZE 要看存储的指令。 STB = 1B; STDW = 8B;

REG *B15- - [x] REG *B15++ [x] 先把 REG 的值赋值到*B15 开始的地址中,然后 B15 减、加 x 个 REG SIZE REG *-- B15[x] REG *++B15[x] 先 B15 减、加 x 个 REG SIZE,然后先把 REG 的值赋值到*B15 开始的地址中。 例子: 83689CB0 8577 STDW.D2T1 A11:A10,*B15--[1] 83689CB2 4646 || MV.L1 A4,A10 //写 A10 会在读 A10 之后执行 *B15 = A11:A10 *B15 -= 8 (A11:A10 是 8Byte) 注:每个 cycle,写是在读之前完成的,所以此语言写入*B15 还是老的 A10 的值。

25

SPLOOP & SPLOOP buff
指令软件流水循环和软件流水缓存 Software Pipelined Loop (SPLOOP) Buffer Operation With Delayed Testing 1. 2. 它是 C64X+新增的一个硬件模块,目的是为了快速完成循环指令。即实现 DSP 汇编指 令循环。 SPLOOP 通过把循环指令的每次循环的 Kernel 指令打包存放在 SPLOOP buff 中,可以 最多存放 14 个指令包(即循环体最多可以有 14 个指令包) : a) SPLOOP buff 最多可以缓存 14 个指令包,每个指令包是一个 8*32bit 的单元,用于 存放多条要被执行的指令。 b) CPU 可以直接从此 buff 中读取指令包,而不需要到 L1P 去获取,这样减少 L1P 取 指令压力。 c)

是通过延时,获取 L2/Ext 内存的数据 Copy 到 L1 Memory 中。

SPLOOP Prolog/Kernel/epilog
做 SPLOOP Prolog 的目的和特点: 1. 会按照需要指令的特点(比如 LWD 指令需要 5 个 cycle) ,对即 Kernel 区域的所有寄存 器进行初始,保证在 Kernel 阶段,所有的寄存器中的值都是有效的。 2. 即会把 SPLOOP 和 SPKERNEL 之间的指令都执行一遍(SPKERNEL 和与 SPKERNEL 并行的指令不会被执行) 做 SPLOOP Kernel 的目的和特点: 1. 会把循环体内所有的指针都运行到。并彻底完成第一次到第 N 此的循环动作。 做 SPLOOP epilog 的目的和特点: 1. 它与 Prolog 是互补的。如果某个指令在 Prolog 中被运行了多次,则在 epilog 中就不会 被运行了。 2. 总之,所有循环体内的指令,在 Prolog/Kernel/epilog 中运行的总次数是一样的,即是循 环的次数。

SPKERNEL
是 SPLOOP 的结尾标志,与主体代码的最后一条指令并行(||)。

26

SPLOOP
SPLOOP ii 1. 它表示一个循环体的开始,会启动 SPLOOP Prolog。 2. ii 表示单循环体单次循环需要的 CPU cycle 的个数 3. 做 SPLOOP Prolog 的目的和特点: a) 会按照需要指令的特点(比如 LWD 指令需要 5 个 cycle) ,对即 Kernel 区域的所有 寄存器进行初始,保证在 Kernel 阶段,所有的寄存器中的值都是有效的值。

Memset 的部分代码

SPLOOPD

27

SPLOOPW

Stalls
就是 CPU 的等待 cycles。 (注意,并不是 IDEL,而是 WAIT) 。区别是 stalls 是硬件加入的, 不需要 NOP 指令。 1. 当 CPU 要用一份数据,而这一份数据还没有准备好,则 CPU 只有等待。 2. 或者为了避免混乱,CPU 的某个 ACTION 就要多个 Cycle 才能完成,CPU 会在那里等 待。

Cross Path register file read Stall
1. 当指令通过Cross path(X path, such as S1X, S2X, D1X, D2X等)读取某寄存器时, 如果此寄存器是在上一个周期被另一path指令更改(LDW指令改变除外,LWD指令 获取的数据本来就要在5个cycles后才可以使用),则此需要等待一个Stall(即一个 Cycle) a) 此Stall是通过硬件插入的,不需要NOP指令 b) 但是如果寄存器的改变是作为LDW指令的目标寄存器而改变时, 则下一指令用 它时不需要插入此stall(具体原因可以参考LDW指令的实现) 避免此stall的方法 a) 通过指令排序,避免读取这样的寄存器 b) TMS320C6000 Optimizing Compiler and Assembly Optimizer automatically perform
this scheduling

2.

Memory stall(L1 Cache miss stall)
A memory stall occurs when memory is not ready to respond to an access from the CPU.

1.

当数据或者指令都L1cache中(L1D、L1P中) ,则取值与取数都不会有额外的CPU stall 产生。 a) 但是如果指令不在L1P中,则取值会在PW阶段产生大等于1个Cycle的stall。 b) 但是如果指令不在L1D中,则取值会在E3阶段产生大等于1个Cycle的stall。

28

2.

Stall就是CPU需要额外的N周期去获取资源时,则会停止取指N周期。

Atomic operation
shared_ctr: //原子操作开始 LL *A8, A6 ; //从目标地址LDW一个Word到A6,此时会HW设置一个原子操 作标志为True, 如果以后目标地址中的值被重写则此标志会变 为False NOP 4 ADD A6,A9,A6 ; SL A6, *A8 ; //准备新值,如果新值buff的地址不是目标地址,标志也会 变为False. 即LL & SL是配对操作 CMTL *A8, A1;//提交新值。此目录会先获取HW标志到A1中,然后把SL buff 的数据提交store到内存中,之后硬件标志也会变为false NOP 4 [!A1] B shared_ctr;//如果目标地址在 CMTL 之前已经被重写,则此过程 重新执行,保证原子操作 可见这是一个通过汇编代码逻辑来实现的原子操作过程。 实际是在汇编层面实现的一种逻辑锁。

Function call conventions
Knowledge about function call
1. 当函数被调用时,栈顶指针的位置,应该与函数 return 后回到 parent 函数时栈顶的位置 一样。即,从 SP 指针看,一个被返回的函数不会对它的位置有任何改变。

Register type
1. Parent type:即由本函数设置的,但是一旦调用了其它函数再返回来时,这些寄存器中 的值就不可再用了(也可以说是不需要了) ,有 A0/B0??A8/B8(包括 A9/B9),和 A16/B16??A31/B31。 child type:即本函数设置的,不管怎么调用 child 函数,只要本函数自己没有修改这些 寄存器的值, 则这些值就不会被改变, 还是可以用的。 A10/B10??A15/B15 (16 对)。 有 除了这些 AB 数据寄存器外,控制寄存器也具有这两种属性。

2. 3.

29

How a parent function makes a call
1. 首先,每次函数调用如果有参数需传入,都是从 A4/B4、A6/B6??A12/B12 的顺序开 始传递参数的。 a) 如果 Parent 函数用到了 A4/B4??A8/B8(比如它自己的入参) ,则要保存这些参 数到 stack 中, 然后开始使用它们传递参数到 child 函数。 child 函数返回的时候, 在 这些寄存器的值不能再使用了,除非进行恢复。 b) 如果参数超过 6 个,则需要使用 A10/B10、A12/B12,则需要先把这些参数保存到 stack 中(不管本函数之前是否使用过这些寄存器) 。在 child 函数返回时,一定要 恢复这些寄存器的值。 i. 因为 A10/B10、A12/B12 此类寄存器是 child 属性的寄存器,所有的 caller 都 认为其中的值时不会变的。但是所有的 child 都可能使用这写寄存器,处理的 办法就是,每层函数(即是 parent 又是 child)使用这些寄存器时,先保存其 中的值,等用完后,再恢复其中的值。则对于其上层函数来说,则其保存在这 些寄存器中的值是没有被改变的。 ii. A4/B4??A8/B8 这些寄存器则是 parent 属性的寄存器。它们用于传递参数。 默认认为, parent 调用了 child 的函数时, child 函数就可以改变其中的值。 当 则 所以当函数进入时, 如果某个传入的参数在调用第一个 child 函数后还要使用, 则这样的参数需要保存。因为不能保证 child 函数返回后,这些寄存器中的值 是没有变化的。 c) 如果参数超过 10 个, 则需要把第 11 个以及之后的所有参数保存到 stack 中。 child 在 的函数中,则从 stack 中获取这些参数。如果这些要参与到运算,则还要 Load 到 寄存器中使用。 i. 参数压栈在 stack 中的哪个位置,而 child 函数又怎么来使用它们,则是编译 器在生成汇编代码是自己控制的。 ii. 在 child 函数返回时, parent 函数要回收这些栈空间。 因为这些栈空间是为 child 函数分配的,再 child 函数返回后,就没有任何作用了。所以要第一时间收回。 iii. 在被压栈的参数中,还有 Parent 函数的 return address 寄存器 B3。因为 parent 需要设置本次调用的返回函数。 d) 如果传入的参数是一个结构体,则函数实际使用寄存器传入的是此结构体在 parent 函数中的指针。Child 函数接收到时,先要通常此寄存器,在栈中分配一片空间, 把整个结构体 copy 下来。 i. 可见结构参数实际传入的是一个指针。 child 函数返回时,如果有返回值,则返回值会被存放在 A4 或者 A3(返回值是结构体, 返回的是结构体的指针)中。 i. 如果返回值是结构体,则返回的是结构体的指针,存放在 A3. Parent 函数需要 在第一时间把这个结构体 copy 过来。

2.

How a child function response a call
注:现在 FP 指针没有使用,都是直接使用 SP 指针的

30

Code optimize
<DSP TMS320C6000 Optimizing Compiler(DSP 编译器优化选项).pdf> In rules.mk file, defined CCFLAGS

For DSP, it has follow optimizations.

Short function will be inline Options
The options 1. When optimizing with the --opt_level=3(High performance optimization level (file level)) option or --opt_level=2 option (aliased as -O3 and -O2,respectively), the compiler automatically inlines small functions.
2. A command-line option,--auto_inline=size, specifies the size threshold for automatic inlining. This option controls only the inlining of functions that are not explicitly declared as inline. 3. 4. 5. 6. when –auto—inline is not set, but optimizing with –O2 or –O3, complier will inline a function that smaller than a default size. If –auto-inline is set to 0, auto-inline optimization will be diabled. if –auto-inline is set to a non-zero value, complier will inline any functions smaller than this size. in rules.mk file, CCFLAGS +=-O3#.

Complier actions
This For GCC complier, if not use

31

Loop What Disqualifies a Loop from Being Software-Pipelined

Interrupt & OS & Chip
1. 中断向量事件寄存器 (INT Vector?Event Id) PRO_INT_MUX_ADDRESS: : 0x01800104。 此寄存器中记录了每个向量的中断 Event Id。每个 Event Id 是 8bit. a) 当触发了某种中断事件,则可以得到其中断向量,便于软件处理。 在 OSE 中,中断是以中断进程 OS_INT_PROC process 的形式运行的。触发一个中断就 是启动对应的进程。 a) create_process 函数创建中断进程并创建中断管理结构 b) pcb_t *odo_vect2pcb[16]是操作系统记录中断向量到中断进程的 MAPPING。 下标是 中断向量号

2.

怎么把外部硬件的 pin 映射到中断向量
http://www.embexperts.com/forum.php?mod=viewthread&tid=11&page=1 硬件设备会连接到 PIN 管脚上。当一个管脚上触发中断后,CPU 可以在指定的寄存器中读 取到一个数字——硬件中断编号(或者叫硬件 Event Id) 。 硬件中断编号应各种 CPU 不一样而不一样。当增加一个外设中断时,就要定义了一个硬件 中断号,则对应要增加一个此硬件中断的处理函数。 注册中断回调函数时, 需要把硬件中号和中断向量号同时传入。 则操作系统会记录硬件中断 号到中断向量的对应关系。 则触发了此硬件中断后,操作系统会读取硬件中断号,然后获取 Vector Id,然后直接跳转到 Vector 的起始地址执行。 Vector 起始地址就是中断回调函数。 各个中断回调函数必须卸载”.vector x” segment 下面,且每个 segment 下只有一个处理函数。 很多时候,为了提高中断回调的速度,这个回调函数直接使用汇编实现。 当然,中断函数不一定就是真正的中断任务完成函数,比如在 OSE 中是向对应的中断任务 发送一个信号量的,触发中断任务。

Interrupt registers(All 32bits)
1. ICR:中断清除寄存器, user for INT type interrupts. If bitX is equal to 1, means vector X interrupt is cleared. a) When create Vector X interrupt, clear it. IER:中断使能掩码寄存器。操作系统中会有一个对应的软件中断使能掩码全局变量。 它只对 INT Type 的中断有效。

2.

32

怎么为芯片定制操作系统
Interrupt 定制
extern cregister volatile unsigned int IER; //interrupt enable register extern cregister volatile unsigned int ICR; //interrupt clear register extern cregister volatile unsigned int ISR; // extern cregister volatile unsigned int CSR;// 1. 2. 中断事件与中断向量: 需要把硬件的中断事件映射到操作系统的中断向量中 (硬件会提 提供最多 16 种中断事件,而操作系统会具有 16 个中断向量) 。 中事件与中断向量的 MAPPING:在芯片中,也有中断向量的概念,或者理解是硬件对 中断事件的编号。 a) 比如在 DSP 中,PRO_INT_MUX_ADDRESS:0x01800104 寄存器就是以中断向量 为下标,记录了中断事件对应的中断向量。 b) 当触发了某种中断事件时就很容易得到其中断向量值。

OSE 进程切换
基于信号量的进程切换 CPU 内切换
OSE 是基于 Signal 的切换的。 如果是 CPU 内的 Signal 进程切换,本质是软件触发的切换。 它的实现方法是在 Send 的时候就触发切换。即 Sender 进程触发切换,看 receiver 进程是否 比自己的优先级高。如果高则切换到 receiver 进程上。

CPU 间切换
中断方式切换

33

中断方式切换

MDMA/SDMA/IDMA
1. CPU 读写内存都要通过 L1 Cache。只是读需要等待,而写不需要等待 a) 读需要等待从外面把数据搬进来 b) 写的话,数据放在 L1 Cache 中,而可以立即再读。再读的时候因为之前的写,已 经可以在 L1 Cache 中命中了,所以会直接从 L1 Cache 中获取(实际外存中还没有 更新) 。 MDMA 是 CPU 访问(读写)核外资源的接口。当 CPU 访问核外资源时,它的访问过 程如下: a) 首先通过 L1 Controller(L1P/L1D Controller)访问 L1 cache. b) (如果自己没有)L1 Controller 则访问 L2 Controller c) (如果自己没有)L2 Controller 则访问 EMC d) EMC 通过 MDMA 接口的 BUS 资源,把数据从外存中直接搬移到 L2 Controller e) (如果是 Cached 数据)L2 controller 把数据保存在自己的 Cache 中,然后通过 IDMA 搬移给 L1 Controller i. (如果不是 Cache 数据)则 L2 controller 直接通过 IDMA 搬移给 L1 Controller , (可见没有 cache 的数据在一次搬移时可能会更快) f) L1 controller 把数据保存在自己的 Cache 中,然后回给 CPU。 SDMA 是 CPU 核外设备访问核内资源的接口。它的访问过程如下: a) 外设通过 EMC 的 SDMA 接口,访问 EMC b) EMC 会访问 L2 Controller,如果 L2 中有数据,则 L2 Controller 会通知 EMC 取数 据。 i. 如果 L2 没有,则 L2 controller 会访问 L1 Controller,通过 IDMA 获取数据。 c) EMC 会分配 SDMA 接口资源,把数据搬移到外面。

2.

3.

34


推荐相关:

DSP 汇编指令总结 一、寻址方式: 1、立即寻址: 短立即寻址(单指令字) D15 D14 D13 D12 D11 1 0 1 1 1 D10 0 D9 1 D8 1 D7 0 D6 1 D5 1 D4 ...


汇编指令总结 105页 1下载券 汇编 指令总结 暂无评价 12页 1下载券 DSP汇编指令总结 5页 2下载券 汇编跳转指令小结 暂无评价 4页 1下载券 汇编语言-跳转指令...


DSP汇编指令总结_学习总结_总结/汇报_实用文档。DSP 汇编指令总结 (2007-01-18 08:41:59) 转载▼ 1.定义段的伪指令 助记符和语法 .asect"section name...


DSP学习笔记_计算机软件及应用_IT/计算机_专业资料。一、如何开始 DSP 的学习 ...既能看到源文件中代码的执行情况,又能看到汇编指令的执行情况---"View","Mixed...


DSP 学习笔记引言:学习 DSP 的时间有两个多月了,收获很多新知识,我们要每天都...Go main。 既能看到源文件中代码的执行情况,又能看到汇编指令的执行情况 View?...


dsp汇编指令_IT/计算机_专业资料。dsp中的汇编伪指令伪指令分类伪指令及其表示格式具体描述段定义伪指令 .asect “段名” , 地址汇编到一以绝对地址为起始的段中...


DSP学习笔记心得_电子/电路_工程科技_专业资料。DSP 学习心得笔记 --- 白建成...既能看到源文件中代码的执行情况,又能看到汇编指令的执行情况 View?我们在调试...


6.1 汇编语言指令集概述在学习 C28x 系列 DSP 的寻址方式和汇编指令指令之前,先来对一些基础的知识进行讲 解一下先, 在汇编程序当中开发人员会常常使用到许多...


DSP 汇编语言 简单小程序 经典_信息与通信_工程科技_专业资料。对于刚入门的DSP...学习 DMA 的原理的使用方法 实验内容:用 DMA 方法接收 McBSP 接口语音芯片的...


一个完整的 dsp 工程包括头文件(.h),库文件(.lib),源文件(.c),以 及...如果想在一个窗口内同时看到 c 和汇编,则有操作 View?mixed source/asm 11、...

网站首页 | 网站地图
3986 3986.net
文档资料库内容来自网络,如有侵犯请联系客服。zhit325@qq.com