了解STM8流水线

时间:2017-10-08 09:33:53

标签: opcode instruction-set benchmarking cpu-cycles stm8

我正在尝试了解STM8流水线技术,以便能够预测我的代码需要多少周期。

我有这个例子,我在那里切换GPIO引脚各4个周期。 Iff 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字节指令,nop 1字节。
  • nop / bset / bres说明每个都需要1个周期。
  • jra指令需要两个周期。我认为在第一个周期中,指令高速缓存用下一个32位值填充,即在这种情况下只有nop指令。而第二个周期实际上只是在解码下一条指令时CPU被停止。

所以周期:

  1. bres清除图钉
  2. jra,管道清除,nop提取
  3. nop解码,bset抓取
  4. nop执行,bset解码,下一个nop抓取
  5. bset执行设置引脚
  6. nopbres fetch
  7. nop
  8. nopbres解码
  9. bres执行清除引脚
  10. 据此,引脚应保持低电平4个周期,高电平保持4个周期,但保持高电平5个周期。

    在任何其他对准情况下,引脚按预期的方式为低电平/高电平4个周期。

    我认为,如果PIN在一个额外周期内保持高电平,这必然意味着执行管道在bset指令后停止(此后nop s提供足够的时间来确保{bres 1}}以后准备立即执行)。但根据我的理解nop(对于6)已经在4中获取。

    知道如何解释这种行为吗?我在manual找不到任何提示。

1 个答案:

答案 0 :(得分:0)

在5.4节中进行了解释,该节基本上说在整个programming manual中,将使用“简化的约定,提供与现实的良好匹配”。根据我的经验,对于较长的序列来说,这种简化的约定确实是一个很好的近似值,但是即使在装配级和控件对齐上工作,也不能用于精确的每条指令时序。以“ SLA addr”为例。记录使用1个周期。依次放置其中三个以实现C等效的“ *(addr)<< 3”,您将需要增加5-6个周期。

用于解码和执行的实际周期未记录。除了明显的原因外,没有关于导致管道停顿的原因的全面文档。通过使用预分频器/ 1配置TIM2并在使用ST-LINK / V2逐步浏览代码的同时重新加载值0xFFFF,我能够对此有所了解。然后,您可以监视TIM2_CNTRL以查看消耗的周期(==执行前一条指令并解码当前指令的总值)。

需要注意的显然是跨越32位边界的指令。在某些情况下,从下一个32位字加载指令会导致一系列NOP出现意外的额外周期,这表明任何获取(即使对于当前指令或下一条指令而言并非必需)都花费1个周期吗?我已经看到调用目标对齐到32位边界需要4-7个周期,这表明CPU仍在忙于执行上一条指令或由于未知原因而暂停调用。在某些情况下,修改SP(push / pop或直接add / sub)似乎会导致停顿。

任何其他见解表示赞赏!