MCX N PLU 设置和使用
主板: FRDM-MCXN947
?类别:?低功耗
工具链: MCUXpresso IDE
SDK: 2.14.0
外设: PLU
目录
介绍
MCX N 具有可编程逻辑单元 (PLU),能够创建独立于内核运行的组合逻辑电路和时序逻辑电路。PLU 通过预编程查找表或 LUT 来实现这一点,这些查找表或 LUT 决定了 PLU 所有输入的指定输出行为。MCX N PLU 模块的功能包括:
- 由 26 个可互连的 5 输入查找表 (LUT) 元素组成的阵列。
- 4双人字拖。
- 六个主要输入引脚。
- 八个主要输出引脚。
- 如果实现了顺序网络,则需要外部时钟来驱动四个触发器。
- 能够从睡眠和深度睡眠模式生成中断和唤醒请求。
功能描述
本应用笔记将首先解释 PLU 模块的组成元件,以及如何集成它们以实现简单的逻辑网络。最后,本应用笔记将通过三个示例代码演示该模块的设置和使用:一个 1 位 1 至 4 解复用器、一个 4 位移位器以及一个低功耗的 1 至 4 解复用器实现,以演示其唤醒功能。
模块架构
PLU 由三个主要元素组成:查找表 (LUT)、多路复用器和触发器。查找表用于创建 PLU 网络的实际逻辑,而多路复用器则负责将这些逻辑信号路由到其他 LUT 以及 PLU 的输入和输出引脚。触发器提供了一种将逻辑信号从 LUT 元素门控到共享时钟输入的方法,从而为逻辑网络添加了同步和延迟机制。
查找表 (LUT)
PLU 模块拥有 26 个可互连的查找表 (LUT),可同时实现最多 5 个输入的任意组合功能。LUT 的工作原理是为每种输入组合存储一个预编程的输出。这使得查找表能够在输入发生变化时立即生成特定的逻辑 0 或 1 输出,无需任何处理。通过将 LUT 元素互连,可以实现更复杂的可编程网络,同时提供多个逻辑门的功能。
多路复用器
PLU模块包含各种多路复用器,用于选择每个查找表(LUT)元素的输入和输出。每个LUT元素有5个输入多路复用器,将信号路由到其5个输入中的每一个。每个LUT的可用输入信号包括:
- PLU 输入板。
- 其他 LUT 元素输出。
- 状态触发器输出。
PLU 还为每个 PLU 输出垫(总共八个)配备了一个输出多路复用器,用于选择哪个查找表或触发器状态将驱动每个输出垫。
人字拖
最后的 PLU 元素是 D 型触发器,可以保留数据,为顺序逻辑电路和简单状态机提供手段。
PLU模块有4个触发器,它们连接到LUT[3:0]的输出以及用于触发器之间定时和同步的外部PLUCLKIN信号。为了使用触发器元件,必须通过PLUCLKIN引脚提供时钟信号。注意,由于触发器直接连接到前4个LUT元素的输出,因此必须设置相应的LUT元素才能使用每个触发器元素。
PLU设置
为了在PLU模块上实现逻辑网络,必须完成以下步骤:
- 使用 SYSCONSYSAHBCLKCTRLx 寄存器启用 PLU 的时钟,然后从 SYSCONPRESETCTRLx 寄存器切换 PLU 复位位。
- 使用 PORTx_PCRn 寄存器分配引脚。
- 使用以下步骤 创建逻辑网络:
- 将要使用的每个 LUT 元素的逻辑行为写入真值表寄存器中。
- 对输入多路复用器寄存器进行编程,以选择每个 LUT 的最多五个输入源。
- 对输出多路复用器寄存器进行编程,以从 PLU 模块中选择最多八个主要输出。
- (可选) 通过使用 WAKEINT_CTRL 寄存器选择用作唤醒源的输出以及设置去毛刺方法来设置唤醒行为。
创建逻辑网络
基本逻辑门
只需在单个 LUT 元素上配置两个输入和一个输出,即可实现所有基本逻辑门。例如,将 PLUIN0 和 PLUIN1 引脚配置为 LUT0 的输入,将 PLU_OUT0 引脚配置为 LUT0 的输出即可实现。
创建任何逻辑网络的第一步都是了解所需逻辑电路的真值表。对于使用上述配置的单个与门,真值表应等于以下内容:
| # | | PLUIN1 | PLUIN0 | PLU_OUT0 |
| ------- | -- | :-------: | :-------: | :-----------: |
| 0 | | 0 | 0 | 0 |
| 1 | | 0 | 1 | 0 |
| 2 | | 1 | 0 | 0 |
| 3 | | 1 | 1 | 1 |
查找表 (LUT) 必须设置为仅当 PLUIN1 和 PLUIN0 同时为高电平时输出才为高电平,这恰好是上一个真值表中查找表输入的第三种组合。因此,我们需要对查找表进行编程,使其在组合 #3 时输出高电平。我们可以通过在查找表真值表寄存器的第 3 位写入“1”来编程该逻辑门。这样,当 LUT0 的两个输入都为高电平时,查找表元素将“查找并找到”一个“1”,因此输出高电平。另一方面,对于其他所有组合,它将找到一个“0”,并输出低电平。
| 组合编号(输入) | 真值表寄存器(输出) |
| :-----------------------------: | :-------------------------: |
| ?0 *?(0b00)* | *0 |
| ?1 *?(0b01) | *0 |
| ?2 *?(0b10) | *0 |
| ?3 *?(0b11) | **1 |
考虑到这一点,很容易看出,LUT 元素所做的就是在预定义表中“查找”每个输入组合,以确定输出逻辑。该表通过每个 LUT 元素的 32 位 LUTa_TRUTH 寄存器进行编程。因此,上一个逻辑门所需的 32 位值(以十六进制表示)如下:
| 与门 | | | | | | |
| ---------------------- | :-----------: | :-----------: | :-----------: | :-----------: | :--: | :--------------: |
| LUT输入[1:0] | 11 | 10 | 01 | 00 | | |
| LUT0_TRUTH | 1 | 0 | 0 | 0 | → | 0x08 |
对于其余的基本逻辑门:
| 或门 | | | | | | |
| ---------------------- | :-----------: | :-----------: | :-----------: | :-----------: | :--: | :--------------: |
| LUT输入[1:0] | 11 | 10 | 01 | 00 | | |
| LUT0_TRUTH | 1 | 1 | 1 | 0 | → | 0x0E |
| 异或门 | | | | | | |
| ---------------------- | :-----------: | :-----------: | :-----------: | :-----------: | :--: | :--------------: |
| LUT输入[1:0] | 11 | 10 | 01 | 00 | | |
| LUT0_TRUTH | 0 | 1 | 1 | 0 | → | 0x06 |
| 与非门 | | | | | | |
| ---------------------- | :-----------: | :-----------: | :-----------: | :-----------: | :--: | :--------------: |
| LUT输入[1:0] | 11 | 10 | 01 | 00 | | |
| LUT0_TRUTH | 0 | 1 | 1 | 1 | → | 0x07 |
| 或非门 | | | | | | |
| ---------------------- | :-----------: | :-----------: | :-----------: | :-----------: | :--: | :--------------: |
| LUT输入[1:0] | 11 | 10 | 01 | 00 | | |
| LUT0_TRUTH | 0 | 0 | 0 | 1 | → | 0x01 |
| 同或门 | | | | | | |
| ---------------------- | :-----------: | :-----------: | :-----------: | :-----------: | :--: | :--------------: |
| LUT输入[1:0] | 11 | 10 | 01 | 00 | | |
| LUT0_TRUTH | 1 | 0 | 0 | 1 | → | 0x09 |
| 非门 | | | | |
| ---------------------- | :-----------: | :-----------: | :--: | :--------------: |
| LUT输入[1:0] | 1 | 0 | | |
| LUT0_TRUTH | 0 | 1 | → | 0x01 |
| 缓冲门 | | | | |
| ---------------------- | :-----------: | :-----------: | :--: | :--------------: |
| LUT输入[1:0] | 1 | 0 | | |
| LUT0_TRUTH | 1 | 0 | → | 0x02 |
请注意,在这种情况下,或非门和非门的真值表值相同,因为它们都要求第一个输入组合的输出为“1”,其余输入组合的输出为“0”。这表明 PLU 实际上并没有创建一个逻辑门阵列,而是简单地从包含所有可能输入组合的表中输出预先定义的值。
前面的表格显示了使用先前设置的 LUT0 实现所有基本逻辑门所需的寄存器值。但是,为了使用输入引脚 PLUIN0 和 PLUIN1 以及输出引脚 PLU_OUT0 实现此配置,必须按以下方式设置多路复用器:
为了实现此目的,引脚 PLUIN0 必须路由为 LUT0 的输入[0],PLUIN1 必须??路由为 LUT0 的输入[1]。此外,LUT0 的输出将路由至 PLU_OUT0 引脚。此配置用于设置两个输入源、路由输出源并写入真值表寄存器以产生与门,可以使用以下代码实现:
```c
/* Select input pin PLUIN0 as LUT Input 0 (Input MUX0) for LUT0 on module PLU0 */
PLUSetLutInputSource(PLU0, kPLULUT0, kPLULUTIN0, kPLULUTINSRCPLUIN_0);
/* Select input pin PLUIN1 as LUT Input 1 (Input MUX1) for LUT0 on module PLU0 */
PLUSetLutInputSource(PLU0, kPLULUT0, kPLULUTIN1, kPLULUTINSRCPLUIN_1);
/* Set Truth Table 0x08 for LUT element 0 on module PLU0 */
PLUSetLutTruthTable(PLU0, kPLULUT_0, 0x08); // This will result in an AND gate
/* Select LUT0 output as driver for PLUOUT0 pin on module PLU0 */
PLUSetOutputSource(PLU0, kPLUOUTPUT0, kPLUOUTSRCLUT0);
```
组合逻辑示例
设置
组合逻辑电路的一个简单但实??用的例子是解复用器。该电路将单个输入数据一次性输出到多个可选输出之一。该电路的一个具体示例的真值表如下表所示:
| 梳子 # | | D | S1 | S0 | | Y3 | Y2 | Y1 | Y0 |
| :-------: | :-: | :-: | :--: | :--: | :-: | :--: | :--: | :--: | :--: |
| 0 → 3 | | 0 | x | x | | 0 | 0 | 0 | 0 |
| 4 | | 1 | 0 | 0 | | 0 | 0 | 0 | 1 |
| 5 | | 1 | 0 | 1 | | 0 | 0 | 1 | 0 |
| 6 | | 1 | 1 | 0 | | 0 | 1 | 0 | 0 |
| 7 | | 1 | 1 | 1 | | 1 | 0 | 0 | 0 |
请注意,当 D =“0”时,S1 和 S2 被标记为“不关心”,这意味着前 4 个组合数字(从 0 到 3)都导致所有 LOW 输出的相同输出。
定义真值表后,可以按如下方式分配引脚:
- PLU_IN2对应数据线(D)。
- PLU_IN1 对应选择线 1 (S1)。
- PLU_IN0 对应选择线 0 (S0)。
该真值表有4个输出,这也意味着PLU需要4个LUT,因为每个LUT只能生成一个输出。因此,每个LUT寄存器的真值表值定义如下(括号之间的值对应于数据线上的逻辑值):
| | | PLU输入[2:0] | (1)11 | (1)10 | (1)01 | (1)00 | (0)11 | (0)10 | (0)01 | (0)00 | | |
| :----------: | :--: | :-------------: | :---------------: | :---------------: | :---------------: | :---------------: | :-------------: | :-------------: | :-------------: | :-------------: | :--: | :--------------: |
| LUT0TRUTH | → | PLUOUT0 | 0 | 0 | 0 | (1) | 0 | 0 | 0 | (0) | → | 0x10 |
| LUT1TRUTH | → | PLU输出1 | 0 | 0 | (1) | 0 | 0 | 0 | (0) | 0 | → | 0x20 |
| LUT2TRUTH | → | PLU输出2 | 0 | (1) | 0 | 0 | 0 | (0) | 0 | 0 | → | 0x40 |
| LUT3TRUTH | → | PLU_输出3 | (1) | 0 | 0 | 0 | (0) | 0 | 0 | 0 | → | 0x80 |
请注意,由于 PLU_IN2 或“数据”在前 4 个组合(即 000、001、010 和 011)中保持为 FALSE,因此所有输出均为逻辑“0”。这对应于真值表中选择线为“无关”的前 4 个组合,如前所述。
该组合电路的设置,包括每个 PLUOUTx 信号的 LUT 值,可以在所附的“frdmmcxn947plu4to1demux”示例代码中找到。
本示例基于FRDM-MCXN947开发板。输入输出接口如下:
- 输入:
- 选择 0 → P110 (PLUIN0)。(注意:如果使用 Rev. B,SJ16 需要更改为位置 2-3)
- 选择 1 → P111 (PLUIN1)。(注意:如果使用 Rev. B,SJ26 需要更改为位置 2-3)
- 数据→P114(PLUIN2)。
- 输出:
- Y0→P18(PLUOUT0)。
- Y1→P19(PLUOUT1)。
- Y2→P112(PLUOUT2)。
- Y3→P113(PLUOUT3)。
当将输入连接到 VDD 或 GND 时,输出将根据之前的真值表发生变化,这可以在示波器或逻辑分析仪上看到。下图显示了三个输入所有排列的输出结果。
如上图所示,PLUIN2(DATA) 的值每次仅被路由或解复用到一个输出。当数据为“1”时,该值将传输到由 PLUIN0 (SEL0) 和 PLU_IN1 (SEL1) 的值选定的输出;当数据为“0”时,所有输出结果均为“0”。
调整
但是,如果为了改变输入信号的路由而必须进行调整,该怎么办呢?例如,PLUIN0 现在应该作为数据线,而 PLUIN2 和 PLU_IN1 应该分别作为选择 1 和选择 0。有三种方法可以解决这个问题:
- 根据新的要求将外部输入信号重新连接到焊盘:
- 数据→P110(PLUIN0)。
- 选择 0 → P111 (PLUIN1)。
- 选择 1 → P114 (PLUIN2)。
- 通过在设置 PLU_SetLutInputSource() 函数时选择以下输入源来更改所有 4 个 LUT 的输入多路复用器:
- 将 LUTx 输入 IN0 (S0) 从 PLUIN0 更改为 PLUIN1。
- 将 LUTx 输入 IN1 (S1) 从 PLUIN1 更改为 PLUIN2。
- 将 LUTx 输入 IN2 (D) 从 PLUIN2 更改为 PLUIN0。
- 只需根据新要求调整 LUT 组合即可更改真值表寄存器的值(其中括号中的值对应于数据线上的新逻辑值):
| | | PLU输入[2:0] | 11(1) | 11(0) | 10(1) | 10(0) | 01(1) | 01(0) | 00(1) | 00(0) | | |
| :----------: | :--: | :-------------: | :---------------: | :-------------: | :---------------: | :-------------: | :---------------: | :-------------: | :---------------: | :-------------: | :--: | :--------------: |
| LUT0TRUTH | → | PLUOUT0 | 0 | 0 | 0 | 0 | 0 | 0 | (1) | (0) | → | 0x02 |
| LUT1TRUTH | → | PLU输出1 | 0 | 0 | 0 | 0 | (1) | (0) | 0 | 0 | → | 0x08 |
| LUT2TRUTH | → | PLU输出2 | 0 | 0 | (1) | (0) | 0 | 0 | 0 | 0 | → | 0x20 |
| LUT3TRUTH | → | PLU_输出3 | (1) | (0) | 0 | 0 | 0 | 0 | 0 | 0 | → | 0x80 |
通过此示例,我们很容易看出 PLU 模块通过 LUT 元素提供的灵活性。虽然可以通过重新路由(外部或使用多路复用器进行内部路由)输入来适应不同的输入要求,但只需更改 LUT 寄存器中的值,就可以重新排列整个逻辑网络。
可以通过将“frdmmcxn947plu4to1demux”示例代码上的“DEMOPLULUTxTRUTHTABLE”宏更改为上表中显示的值来测试前面的想法。
唤醒中断示例
PLU 还具有触发中断的功能,在某些情况下,还可以用于将 MCU 从低功耗模式唤醒。具体来说,它可以用来将 MCX 从睡眠和深度睡眠模式唤醒。
PLU 的中断功能基于其输出设置为“1”或逻辑“高”,并使用寄存器 WAKEINT_CTRL 进行配置。此寄存器的位 0 至 7 设置 8 个输出中每一个的掩码。此掩码决定其各自的输出是否会对中断请求做出贡献。例如,如果“MASK”= 0b10010011,则输出 7、4、1 和 0 将有助于中断,因为它们的位设置为“1”,而输出 6、5、3 和 2 将被阻止生成中断,因为它们各自的掩码位为“0”。请注意,由于 PLU 只有一个 ISR,因此所有输出都经过“或”运算。在前面的示例中,只要 4 个被屏蔽的输出中的任何一个生成“1”或“高”输出,就会触发中断。只要所有 4 个屏蔽输出都生成“0”或逻辑“低”,PLU 就不会中断。
然而,PLU 产生的输出信号容易出现故障,进而可能产生错误的中断或唤醒请求。PLU 有两种方法可以防止这些故障。
首先,它可以使用内部时钟来滤除毛刺。此滤波功能通过使用 WAKEINTCTRL 寄存器的位字段“FILTERMODE”[9:8] 来启用。这些位决定了用于滤除可能的输出毛刺脉冲的时间帧。它可以设置为所选时钟源的 1 个时钟周期到最多 3 个时钟周期,以用作滤波器。此时钟源由同一寄存器的位字段“FILTERCLKSEL”[11:10] 决定,它选择 1MHz 低功耗振荡器或 12MHz FRO 作为滤波器的参考时钟。举例来说,如果“FILTERMODE”= 11b 和“FILTER_CLKSEL”= 01b,则 PLU 将滤除短于 12MHz FRO 的 3 个时钟周期(或大约 0.25 μs)的脉冲。
防止误中断或唤醒事件的第二种机制是锁存中断。位域“LATCHENABLE”为中断请求设置此锁存机制,该机制使用已注册或已锁存的中断请求版本,而不是来自 PLU 输出的直接或滤波版本。此选项使用通过 PLUCLKIN 引脚提供给模块的外部时钟源,在 PLUCLKIN 信号的上升沿注册或锁存中断请求。一旦注册,中断即可触发,并且必须随后通过在 WAKEINTCTRL 寄存器的“INTRCLEAR”位上写入“1”来由软件清除。此选项为设置采样时间提供了更大的灵活性,因为它不受 1MHz 或 12MHz 时钟的限制,并且它阻止使用内部时钟以降低 MCX 的功耗。但是,它确实需要使用外部时钟信号和额外的 PLUCLKIN 引脚。
请注意,一次只能使用一种防止中断故障的方法。
附带中断功能的组合电路设置,包括用于将 MCU 从深度睡眠模式唤醒的 WAKEINTCTRL 寄存器的值,可在附件的“frdmmcxn947plu4to1demux_isr”示例代码中找到。该代码使用锁存方法进行去毛刺处理。
本示例基于FRDM-MCXN947开发板。输入输出接口如下:
- 输入:
- 选择 0 → P110 (PLUIN0)。(注意:如果使用 Rev. B,SJ16 需要更改为位置 2-3)
- 选择 1 → P111 (PLUIN1)。(注意:如果使用 Rev. B,SJ26 需要更改为位置 2-3)
- 数据→P114(PLUIN2)。
- CLK→P16(PLUCLKIN)。
- 输出:
- Y0→P18(PLUOUT0)。
- Y1→P19(PLUOUT1)。
- Y2→P112(PLUOUT2)。
- Y3→P113(PLUOUT3)。
- 蓝色 LED → P3_3(睡眠信号)。
与前面的组合示例一样,当将输入连接到 VDD 或 GND 时,输出将根据配置的解复用器真值表进行更改。但是,现在 PLUOUT0 和 PLUOUT3 也会产生中断。在此示例代码中,按下 SW3 将导致 MCU 进入深度睡眠模式,而 PLU 中断将使电源模式循环回到活动模式。
蓝色 LED 用于直观地显示 MCU 的电源状态。当 MCU 处于活动模式时,LED 亮起;当 MCU 处于深度睡眠模式时,LED 熄灭。
以下是该代码的预期行为的捕获:
如图所示,按下 SW3 按钮将使 MCU 进入深度睡眠模式,以绿线表示。该信号实际上是 P33 的输出,P33 是连接到蓝色 LED 的焊盘。当为低电平时,蓝色 LED 亮起,表示 MCU 处于活动模式。当为高电平时,蓝色 LED 熄灭,表示 MCU 处于深度睡眠模式。但是,只要设置了 PLUOUT2,就不会有导致中断的 PLU 输出,因为只有 PLUOUT0 和 PLUOUT3 设置为导致中断。因此,MCU 将保持深度睡眠模式,直到设置 PLUOUT0 或 PLU_OUT3。一旦这些输出中的任何一个设置为“1”或“高”,就会发生中断并再次将 MCU 循环到活动模式。
在此示例中,导致中断的输出设置为 PLUOUT0 和 PLUOUT3,但可以通过调整“plu4to1demux_isr.c”中的以下定义轻松更改:
```c
define ENAINTPLUOUT0 1 /* Enable PLUOUT0 interruption */
define ENAINTPLUOUT1 0 /* Block PLUOUT1 interruption */
define ENAINTPLUOUT2 0 /* Block PLUOUT2 interruption */
define ENAINTPLUOUT3 1 /* Enable PLUOUT3 interruption */
```
为了确保 MCU 确实通过按钮和 PLU ISR 在活动模式和深度睡眠模式之间循环,我们利用FRDM-MCXN947上的 MCU-Link Pro 功率测量功能进行了电流消耗测量。为此,将跳线 J24(也标记为 IDD_MCU)和电路板上的 GND 信号连接到 MCU-Link Pro 的 J9,如下所示:
测量结果如下:
在按下 SW3 按钮之前,MCX 显示电流消耗约为 9.32mA。按下 SW3 按钮后,电流消耗降至 7.96mA,表明 MCX 进入了深度睡眠模式。最终,当 PLU 输出发生变化并触发 PLU 中断后,电流消耗恢复到 9.32mA,因此该中断将电源模式切换回活动模式。
值得一提的是,本次测试启用了蓝色LED,以便直观地确认不同电源模式之间的转换。您可以通过在“plu4to1demux_isr.c”文件中将以下宏设置为“0”来禁用此LED:
```c
/* Enable or disable LED usage for corroborating Sleep behavior or adjusting current measurements */
define APPENABLELED 1
```
顺序逻辑示例
时序逻辑电路的一个简单示例是移位寄存器。该电路使用级联的触发器,每个触发器的输出连接到下一个触发器的输入。这样,输入信号将在每个时钟周期内从一个触发器传输到下一个触发器。如果没有时钟信号,每个触发器元件上的数据将保持其状态。考虑到该电路具有与时间和输入相关的输出(而不是像组合逻辑电路那样仅具有与输入相关的输出),它可以表示为一个根据输入在状态之间转换的状态机。
小端4位移位寄存器的状态图如下:
每个状态都用椭圆表示,4 个触发器的输出就是每个状态的值。每次转换时,都会根据每个时钟周期的输入,向 LSB 添加“1”(蓝色转换)或“0”(红色转换)。如果没有时钟周期,则不会发生转换,状态将保持不变。
如前所述,在“触发器”一章中,为了在PLU上创建顺序逻辑电路,需要使用状态触发器和PLU_CLKIN输入信号。考虑到四个触发器的输入连接到前四个LUT元素,如下图所示,为了使用触发器,还必须设置这四个LUT元素。因此,为了实现移位电路,4状态触发器需要按如下方式连接:
由于每个状态触发器都连接到相应的查找表 (LUT) 元素,因此必须使用每个查找表元素来连接触发器的输入。因此,使用每个查找表元素的输入多路复用器,可以将 PLU_IN0 连接到触发器 0,并将每个触发器的输出连接到每个后续状态触发器的输入。连接完成后,所有查找表元素都可以设置为一个简单的缓冲门,其输出将与输入相同。这可以通过将“0x2”写入查找表的真值表寄存器来实现。然而,很容易看出,通过使用这种查找表和触发器元素的组合,通过将更复杂的组合电路连接到每个时序电路,可以实现更复杂的状态机。
该顺序电路的设置,包括每个状态触发器元素的 LUT 缓冲区的这些值,可以在所附的“frdmmcxn947plu4bit_shifter”示例代码中找到。
本示例基于FRDM-MCXN947开发板。输入和输出引脚如下:
- 输入:
- P34(GPIO)→P17(PLU_CLKIN)。
- VDD 或 GND → P110(PLUIN0)。(注意:如果使用 Rev. B,SJ16 需要更换至位置 2-3)
- 输出:
- P18(PLUOUT0)。
- P19(PLUOUT1)。
- P112(PLUOUT2)。
- P113(PLUOUT3)。
P34 每秒切换一次,产生 1Hz 时钟信号,并作为触发器的 PLUCLK。在时钟信号的每个上升沿,PLUIN0 上的值将通过每个触发器传播到前四个 PLUOUT 引脚。下图显示了单个高电平脉冲通过所有输出的传播过程,从而导致以下转换(0000 → 0001 → 0010 → 0100 → 1000 → 0000):
如果时钟信号停止产生上升沿,触发器将不会更新其值。相反,当前值将被存储,直到时钟信号的下一个上升沿,如下图所示:
在这种情况下,转换过程为 0000 → 0001 → 0011 → 0110 → 1100 → 1000 → 0000,因为输入保持高电平持续了两个时钟周期。然而,从 0011 → 0110 的转换暂停,直到下一个时钟周期的上升沿。在暂停期间,值“0011”在触发器中存储了大约 10 秒,然后才恢复移位过程。
ConfigTools 支持
设置
PLU 与 ConfigTools 完全集成,允许使用基于数字原理图的界面,甚至 Verilog 文件,以更友好的方式设置 PLU 的元件。要使用此功能,首先在 Config Tools 概览窗口中打开相应的拨动开关以启用“外设”工具,然后点击“外设”图标打开该工具:
然后,在左侧的外围设备面板上,搜索“plu”并通过单击复选框来启用它:
PLU外围设备配置现在可以使用了。默认情况下,常规配置将包括上述所有元素的配置:
从上到下依次显示:
- 配置模式,允许使用不同的方法配置 PLU 的元素。
- 资源,允许配置输入、输出和 LUT(使用“显示所有资源设置(高级)”选项时可以在此处配置 LUT)。
- 触发器外部时钟配置。
- 中断配置,包括锁存器和毛刺滤波器。
本文档已解释了 PLU 的元素,包括输入、输出、LUT、触发器和 Interrut,因此本章的其余部分将重点介绍 ConfigTools 上 PLU 的配置模式。
使用“原理图 - 逻辑门”模式
默认配置模式为“原理图 - 逻辑门”,这是设置 PLU 的最简单方法,因为它允许使用一组预定义的逻辑门对模块进行原理图配置。
单击“打开原理图视图”按钮,将出现一个空白画布,其中有每个基本逻辑门的按钮:
此画布允许基于基本逻辑门轻松创建数字电路原理图。此模式可以更轻松地重现本文档“5.1 基本逻辑门”部分中所示的所有基本逻辑门,并且现在具有直观的拖放原理图界面。我们只需添加两个输入、一个输出和一个逻辑门,然后点击每个输入的端子即可进行相应的连接:
与门:
或门:
异或门:
与非门:
或非门:
NXOR门:
非门:
缓冲门:
多路复用器。(虽然从技术上讲它不是基本的逻辑门,但此模式也具有多路复用器的预设):
连接所有输入、输出和门后,只需单击“优化和应用”按钮,该工具就会自动将绘制的原理图转换为 PLU 要使用的寄存器定义。
然后将电路转换为适当的 MUX 和 LUT 值,并在“寄存器”窗口中进行确认,该窗口将以黄色突出显示新的更改。对于之前的与门电路,结果如下:
注意:“优化并应用”功能还会自动保存并锁定当前原理图。如果之后需要进一步修改,第一步需要使用“解锁按钮”解锁原理图。
另外,点击顶部菜单栏的时序信息按钮,所有与 PLU 相关的信号的时序都会显示出来,供用户参考。这些是与门的时序:
使用“原理图-直接查找表”模式
“原理图 - 直接查找表”模式与前一种模式类似,因为它也基于逻辑网络的原理图。然而,它不像前一种模式那样提供预定义的逻辑门,而是显示了“3. 模块架构”部分中描述的实际 PLU 元素,即:输入、输出、查找表和触发器。由于可以在原理图布局本身上手动设置自定义查找表,因此配置模式更直接地对应于 PLU 的实际配置,因此可用于创建更复杂或自定义的逻辑元素。例如,此模式可用于创建本文“5.2 组合逻辑示例”部分中详细阐述的 1 至 4 解复用器。结果如下:
在此模式下,LUT 表的连接以大写字母标记,其中连接 A 对应输入 0,连接 B 对应输入 1,连接 C 对应输入 2,依此类推。每个元素的实际表格都会显示该 LUT 元素所有可能的组合。然后,用户可以通过对表格的输出列进行计时,将每个组合的输出设置为“1”或“0”。对于解复用器的情况,真值表的设置如下(输入 A 为 SEL0,输入 B 为 SEL1,输入 C 为 DATA):
LUT0真值表:
LUT1真值表:
LUT2真值表:
LUT3真值表:
还值得注意的是,设置自定义查找表并不是设置每个 LUT 元素的唯一方法。通过使用画布右侧的“类型”下拉菜单,用户可以在自定义 LUT、一组预定义的基本逻辑门、一个逻辑表达式和一个逻辑的 CSV 文件描述之间进行选择。“自定义”类型是默认方法,允许通过在“1”或“0”之间切换来单独修改每个输出。预定义的逻辑门与“原理图 - 逻辑门”模式下的逻辑门类似,但其优势在于能够将每个逻辑门的输入数量增加最多 5 个。对于 MUX,有 3 个输入;对于缓冲区和非门,只有 1 个输入:
当选择“逻辑表达式”类型时,将出现一个对话框,用户可以以文本的方式输入所需的逻辑描述,例如:
对于这种情况,最终的 LUT 分配如下:
最后,最后一种 LUT 设置方法是使用“导入 CSV”方法,该方法允许使用逗号分隔值文件配置 LUT。此文件需要特定的格式,如下所示:
请注意,必须在文件开头定义输入数量,然后再描述真值表的其余部分。另外值得注意的是,此文件中输入的顺序是 LSB 优先,而在 IDE 中则是 MSB 优先。ConfigTools 中生成的查找表如下所示:
还值得注意的是,并非所有输出都必须明确写下来,只有导致“1”输出的输出才需要写出来。换句话说,上表也可以简化为以下 csv 文件:
| | | | |
| --- | --- | --- | --- |
| 0 | | | |
| 3 | | | |
| 0 | 0 | 1 | 1 |
使用“Verilog 文件和 Verilog 文本”模式
最后两种模式允许使用 Verilog 语法生成逻辑网络。这两种模式彼此非常相似,唯一的区别在于 Verilog 代码是作为文件导入还是手动输入到 ConfigTools。参照前面 1 至 4 解复用器的示例,可以使用以下 Verilog 代码实现相同的逻辑网络:
单击“应用 Verilog 配置”按钮后,将出现一个提示,要求您为每个使用的输入和输出选择路由选项:
一旦映射,ConfigTools 就会将 Verilog 代码转换为 PLU 模块所需的寄存器定义,以实现相同的行为。
结论
MCX N 的 PLU 模块内部组件复杂度适中,仅由一系列查找表、多路复用器和触发器组成。尽管如此,这些基本元件可以实现更复杂、更强大的逻辑网络,为许多重要的数字电路提供片上解决方案,并避免这些数字应用需要外部组件。不仅如此,其中断和唤醒功能也使 PLU 成为许多低功耗应用的简单而有效的补充。PLU 的灵活性和内置功能使其成为 MCX N 系列 MCU 的一个非常有效的补充,不容忽视。
来源:恩智浦appcodehub