【发布时间】:2018-03-19 16:03:24
【问题描述】:
我正在尝试了解 STM8 流水线,以便能够预测我的代码需要多少周期。
我有这个例子,我在每个 GPIO 引脚上切换 4 个周期。
如果loop 在 4 字节边界 + 3 处对齐,则该引脚保持活动 5 个周期(即比它应该多一个)。我想知道为什么?
// Switches port D2, 5 cycles high, 4 cycles low
void main(void)
{
__asm
bset 0x5011, #2 ; output mode
bset 0x5012, #2 ; push-pull
bset 0x5013, #2 ; fast switching
jra _loop
.bndry 4
nop
nop
nop
_loop:
nop
bset 0x500f, #2
nop
nop
nop
bres 0x500f, #2
jra _loop
__endasm;
}
更多上下文:
-
bset/bres是 4 字节指令,nop1 字节。 -
nop/bset/bres指令每个需要 1 个周期。 -
jra指令需要两个周期。我认为在第一个周期中,指令缓存被下一个 32 位值填充,即在这种情况下,只有nop指令。而第二个周期实际上只是 CPU 在解码下一条指令时停止。
所以在循环中:
-
bres清除密码 -
jra,管道刷新,nopfetch -
nop解码,bset获取 -
nop执行,bset解码,下一个nop获取 -
bset执行设置引脚 -
nop,bres获取 nop-
nop,bres解码 -
bres执行清除引脚
据此,该引脚应在 4 个周期内保持低电平,在 4 个周期内保持高电平,但在 5 个周期内保持高电平。
在任何其他对齐情况下,引脚为 LOW/HIGH 4 个周期,如预期的那样。
我认为,如果 PIN 在一个额外的周期内保持高电平,那一定意味着执行管道在 bset 指令之后停止(此后 nops 提供了足够的时间来确保稍后的 bres 准备好立即执行)。但据我了解nop(对于 6.)已经在 4.中获取。
知道如何解释这种行为吗?我在manual 中找不到任何提示。
【问题讨论】:
标签: opcode instruction-set benchmarking cpu-cycles stm8