引言
mikroBus是Mikroe公司推出的扩展板标准。该标准最常见于Mikroe的"Click"扩展板,通过紧凑的硬件接口,开发者可将多种组件接入开发板。开发板通常配备1至3个mikroBus接口。对于仅有一个接口的小型开发板,连接多个外部模块可能较为麻烦。当插入一块Click扩展板后,可能没有剩余I/O接口来连接其他必要设备。mikroBus I/O扩展器(昵称mikroBridge)展示了如何利用FPGA在多个mikroBus接口间建立桥接的方案。
mikroBus标准要求保留I2C、SPI、UART通信引脚及5个GPIO引脚。GPIO引脚的标准定义为:模拟信号、复位、SPI片选、中断和PWM。但这些引脚通常会根据扩展板组件重新定义功能。通信引脚(如SCL、TX、SCK、MOSI等)在未使用时保持悬空且不会重新定义。因此桥接系统必须考虑这种可变性,以兼容尽可能多的扩展板。
更多关于mikroBus标准的信息请访问Mikroe官网:mikroBus标准规范
最终系统采用Microchip IGLOO2 FPGA实现。下方提供源文件包,包含Libero工程、VHDL代码、测试平台及附带Gerber文件的KiCad工程。
下文将解析mikroBridge系统架构,概述各功能模块。
功能概述
mikroBridge具备双重功能。需要同时实现多路复用器和I/O扩展器功能。核心需求简明:
- 任何信号或通信总线必须能直接路由至任意/所有扩展接口的对应引脚。(多路复用)
- 扩展插座上用作输出的引脚在未被多路选择器选中时,运行时必须可写入。*(I/O扩展)
- 非通信引脚的方向必须在运行时可编程。
预期高频变化信号(如PWM)将直接布线,而低频变化信号(如RST)将通过I/O扩展功能间接控制。
*上述规则的一个例外是模拟引脚AN。本文描述的实现方案采用外部模拟开关,该开关无法驱动未选中的引脚。但可通过额外外部元件开发此类电路。
简化框图
mikroBridge 架构
本节简要概述用于构建上述功能的各个组件。多数实现标准行为(多路复用器、串行通信等)。特殊功能将在必要时注明。
双向 I/O 原语
相关 mikroBus 信号: SCL、SDA、CS、RST、INT、PWM
在I/O引脚层面,双向缓冲器至关重要。由于5个GPIO引脚可灵活用于任何功能,mikroBridge必须同时支持输入和输出模式。I2C通信总线也需要双向信号。这是设计中唯一依赖芯片制造商的组件,因各工具链对双向缓冲器的实例化处理方式不同。
上图为Microchip Libero设计工具中的BIBUF元件。Y表示I/O焊盘上的逻辑电平。D是当E为高电平时将被驱动到焊盘的电平。若E为低电平,Y可作为输入读取。对于I2C引脚SCL和SDA,双向缓冲器的D输入端接地,因I2C线路仅被拉低而从不驱动为高电平。
多路复用器 / 解复用器
相关 mikroBus 信号: MISO、RX、TX
对于无法重新分配的通信信号,使用多路复用器和解复用器在主机与输出端之间路由信号。它们有两个用于配置宽度的通用参数:N和SEL_WIDTH。N分别设置多路复用器或解复用器的 i 端口或 q 端口的宽度。SEL_WIDTH设置 sel 端口的宽度。SEL_WIDTH的设定必须确保可用地址数量大于或等于N。例如,若N为4,则SEL_WIDTH必须大于或等于2。超出N范围的地址将导致端口输出默认值:多路复用器为’0’,解复用器为预设默认值。
解复用器额外提供2个端口以增强灵活性。第一个特殊参数是 defaults 端口。该端口定义q侧输出在未被选中时的默认或空闲值。这使得线路可保持高电平空闲而非低电平。第二个特殊参数是demux_pass_all 。若设为’1’,当 sel ="11"时会创建特殊状态,将 i 端输入传递至所有 q 端输出。此功能最常见的用途是同时向多个设备发送复位信号。
双向 I/O 多路复用器
相关 mikroBus 信号: SCL、SDA、CS、RST、INT、PWM
每个可自由分配的GPIO引脚都需要独立双向多路复用器/解复用器,以控制其方向(输入或输出)及如何路由至主机mikroBus接口。上图中,i前缀信号代表主机侧,q前缀信号代表桥接侧。方向选择通常使桥接侧方向与主机侧相反。方向值’1’表示输出,'0’表示输入。根据配置情况,该模块可作为标准多路复用器或解复用器运行,并包含上述两个特殊解复用参数。
示例: 若CS是主机输出信号,设置 i_dir 为’0’(输入), q_dir 为"11"(输出)。CS信号将根据 sel 值从 i 端传递至某个 q 端输出。SPI片选线为低电平有效且需保持高电平空闲,因此设置demux_defaults =“11”。
I2C 透传
相关 mikroBus 信号: SCL、SDA
I2C本身具有寻址功能,因此不需要像SPI和UART那样进行多路复用,但仍需将信号路由至每个扩展插座。本硬件设计中,FPGA作为总线中介充当中继器,将来自I2C主设备的信号复制给每个从设备。虽然I2C总线本可直接物理连接每个插座以跳过此步骤,但通过FPGA透传能带来更大的长期灵活性。
要实现I2C信号的透传效果,模块必须识别当前是主设备还是从设备在驱动信号。当从设备驱动线路时,BIBUF的Y输出为’0’且输出使能(E)也为’0’,表明该线路正被外部拉低。此时主设备侧对应输出使能设为’1’,将该线路拉低。其他所有情况下,主设备输入Y经反相后连接至从设备侧BIBUF的输出使能,将主设备线路电平复制到从设备线路。
需特别注意I2C上拉电阻。系统初期测试时,在缺少专用外部上拉电阻的情况下使用了FPGA内部上拉。约10k欧姆的弱内部上拉电阻导致I2C线路上升时间约1微秒。相对于系统其他部分这非常缓慢,需进行补偿以避免错误。为此在输出使能信号上添加2位移位寄存器以产生延迟。选择1MHz时钟频率可使总延迟与1微秒上升时间匹配,确保采样时信号稳定。必须等待移位寄存器两位均为’0’,才能判定线路稳定且正被外部拉低。
此外,当内部I2C接口的输出使能信号从控制系统的高频时钟域进入透传模块的1MHz时钟域时,易引发亚稳态问题。与前述输出延迟缓冲类似,在 int_slave_scl_e 和 int_slave_sda_e 信号上采用2位同步链确保稳定性。
若缺少输入同步和上升时间补偿,内部I2C控制器会进入无效状态,SDA线路可能保持低电平直至复位。
配置 RAM
采用改进的RAM块存储系统所有设置,包括GPIO方向、多路选择器设置、解复用默认值等。此处设计并无特别之处,仅将各信号在模块顶层引出以连接至多路选择器。
虽然存储器按单字节字划分以匹配串行通信,但大多数设置仅需几位,从字节最低位按需截取。这使得主机可读取通过串行接口写入内存的完整字节,便于调试。该设计也便于在需要时扩展支持两个以上的mikroBus插座。
内存映射如下所示:
默认值根据mikroBus默认分配选择,并假设复位信号为低电平有效。可在源文件中根据需要轻松调整这些值。
下方包含每个“寄存器”设置的详细说明。
SEL
该寄存器设置多路复用器/解复用器的位置。除 AN_SEL 外,每个 _SEL 寄存器均遵循此格式。
对于AN_SEL 设置,
DEMUX_DEFAULTS
该寄存器设置未选中时解复用输出的电平。所有 _DEMUX_DEFAULTS 寄存器均遵循此格式。
DEMUX_PASS_ALL
该寄存器决定哪些解复用器使用特殊的“全通”SEL值0xFF。解复用器值为‘1’时启用全通功能。
DIR
这些寄存器设置双向GPIO引脚的方向。它直接连接到BIBUF的输出使能端。所有 _DIR 寄存器均遵循此格式。
‘1’表示该信号为FPGA输出 。
‘0’表示该信号为FPGA输入 。
I2C 从机
相关 mikroBus 信号: SCL、SDA
I2C是与mikroBridge交互的主要方式,因其天然具备可寻址特性,始终可用。不像SPI和UART那样需要复用至内部控制器。
该模块实现基本的I2C通信,支持7位地址且无时钟拉伸。模块的从机地址可通过泛型参数配置。默认从机地址为0x25。
发送数据时,当 tx_load 为高电平时,tx_data 会在时钟上升沿被载入发送缓冲区。当接收到字节(包括从机地址字节)时, rx_ready 会发出脉冲信号,表示 rx_data 端口上的数据有效。
内部I2C从机未使用双向端口,而是明确配置为使用BIBUF信号。这种方法为实现上述直通效果提供了更清晰的实现层级。
SPI 从机
相关 mikroBus 信号: CS、SCK、MOSI、MISO
SPI是与mikroBridge交互的可选方式。需将 spi_sel 设置为"10"以连接内部SPI控制器。默认情况下内部SPI从机工作在模式0,但可通过泛型参数修改。
SPI从机的运作方式与I2C从机几乎相同。当 tx_load 为高电平时,数据在时钟上升沿载入发送缓冲区;每接收一个字节后, rx_ready 会发出脉冲。
UART
相关 mikroBus 信号: TX、RX
UART是另一种与mikroBridge交互的可选方式。需将 uart_sel 设置为"10"以连接内部UART控制器。波特率等参数可通过泛型参数配置。请确保设置正确的系统时钟频率以获得准确波特率。默认配置为25MHz系统时钟下19,200波特率。
UART的VHDL代码引自另一个eeWiki页面。具体操作细节详见:浅谈 UART (VHDL)
串行转 RAM 接口
相关 mikroBus 信号: SCL、SDA、CS、SCK、MOSI、MISO、TX、RX
每种串行协议都有独特的封装层用于与配置RAM通信。该封装层使得与RAM的交互几乎完全相同,无论选择何种串行协议。每当底层串行接口接收到一个字节时,封装层会通过简单状态机将其路由到RAM的正确端口。命令结构如下所述。
mikroBus主机可通过包含地址和数据的2字节命令对RAM进行读写操作。地址字节为7位地址,最高位是读/写控制位。数据字节仅为普通单字节。超出配置RAM实际可寻址空间的地址位可视为"无关项",将被截取以匹配RAM地址端口的宽度。
命令字节格式

写操作时R/W=‘0’,读操作时R/W=‘1’。详见以下示例。
写入示例
读取示例
接口控制器
相关 mikroBus 信号: SCL、SDA、CS、SCK、MOSI、MISO、TX、RX
接口控制器在层级结构中位于串行转RAM接口的上层。该封装层将上述三个串行模块整合为统一的RAM接口。允许mikroBus主机使用任一接口,并在检测到活动时自动切换至正确的接口。请注意,在与RAM通信前,必须将SPI和UART复用至内部控制器(sel=“10”)。
若发生罕见冲突,仲裁流程将按以下优先级分配RAM总线控制权(从高到低):I2C > SPI > UART。
仿真
在物理实现前,mikroBridge系统已通过Modelsim进行仿真。完整Libero项目包含顶层mikroBridge系统的主测试平台及各子模块的测试平台。
测试平台虽未完全穷尽,但覆盖了主要使用场景。每个串行接口都经过测试,确保可对配置RAM进行读写。路由多路复用器所有可能位置均经过验证。包含一个TCL .do脚本,用于自动格式化波形视图,为每个模块划分独立区域以便于观察。
实现方案
在KiCad中开发了一块采用Microchip IGLOO2 FPGA实现的1:2 mikroBridge设计PCB。
该PCB设计不符合mikroBus标准规范,因为无法在任何标准尺寸上容纳两个完整插座。但由于该设计主要面向单插座开发板使用,这种偏差是可接受的。
测试时将mikroBridge PCB与配备单个mikroBus插座的AVR-IoT开发板配合使用。开发了Atmel Studio项目来镜像仿真测试平台,验证最终实现的行为。与主仿真测试平台类似,AVR版本会遍历所有可能的路由场景,验证每个接口能否读写配置存储器。项目中包含定义RAM内存映射的头部文件。
开发板上SW0用于切换测试用例,SW1用于重置初始状态。LED灯用于指示存储器读写是否成功。信号路由验证需要使用示波器。
注:扩展插座上的I2C上拉电阻(R13-R16)在PCB初始版本中未安装,系后期添加。测试时使用了IGLOO2内部上拉电阻,但性能有所下降。
源码下载
含VHDL源文件、测试平台等的Libero项目: mikrobridge_wiki.zip (4.4 MB)
KiCad原理图、布局源文件、物料清单及板卡Gerber文件下载:mikrobridge_3.3.20.zip (734.2 KB)
AVR测试平台源码:ClickBridgeTest.zip (283.5 KB)
结语
mikroBridge是扩展I/O受限开发板的实用开发工具。它展示了FPGA作为灵活I/O扩展器的应用。这个基础架构为适应更广泛应用的定制化改造留出了空间。
开发过程中获得了诸多有益经验,特别是关于I2C信号通过FPGA的路由设计。考虑时序和信号稳定性对实现正常I2C通信至关重要。
虽然上述IGLOO2实现对于演示和学习很有效,但远非成本最优方案。还存在其他可降低最终产品成本和尺寸的选项。当前设计下,大多数Click扩展板都能兼容,但在模拟信号引脚方面仍有提升灵活性的空间。




















