OpenRISC—OR1200总线标准Wishbone
上一篇《OpenRISC—OR1200各子模块总览》对OR1200各子模块进行了介绍。针对5大子模块,不免产生一个疑问,这些模块之间通过怎样的接口进行连接和数据传输呢?这就要介绍Wishbone总线标准了。
1. 各端口信号定义
标准OR1200的IO端口可以分为5类:系统、指令wishbone总线接口、数据wishbone总线接口、调试接口和电源管理接口。
1.1 系统IO端口信号
OR1200系统IO端口信号 | ||||
序号 | 信号 | 宽度 | 方向 | 功能 |
1 | clk_i | 1 | 输入 | CPU主时钟 |
2 | rst_i | 1 | 输入 | 复位 |
3 | pic_ints_i | 20 | 输入 | 中断 |
4 | clmode_i | 2 | 输入 | CPU时钟与wish-bone时钟比例 |
1.2 指令wishbone总线接口IO端口信号
OR1200指令wishbone总线接口IO端口信号 | ||||
序号 | 信号 | 宽度 | 方向 | 功能 |
1 | iwb_clk_i | 1 | 输入 | 时钟 |
2 | iwb_rst_i | 1 | 输入 | 复位 |
3 | iwb_ack_i | 1 | 输入 | 响应 |
4 | iwb_err_i | 1 | 输入 | 错误 |
5 | iwb_rty_i | 1 | 输入 | 重试 |
6 | iwb_dat_i | 32 | 输入 | 数据输入 |
7 | iwb_cyc_o | 1 | 输出 | 循环 |
8 | iwb_adr_o | 32 | 输出 | 地址 |
9 | iwb_stb_o | 1 | 输出 | 选通 |
10 | iwb_we_o | 1 | 输出 | 写使能 |
11 | iwb_sel_o | 4 | 输出 | 字节选择 |
12 | iwb_dat_o | 32 | 输出 | 数据输出 |
13 | iwb_cab_o | 1 | 输出 | 突发 |
14 | iwb_cti_o | 3 | 输出 | 循环类型 |
15 | iwb_bte_o | 2 | 输出 | 突发类型扩展 |
1.3 数据wishbone总线接口IO端口信号
OR1200数据wishbone总线接口IO端口信号 | ||||
序号 | 信号 | 宽度 | 方向 | 功能 |
1 | dwb_clk_i | 1 | 输入 | 时钟 |
2 | dwb_rst_i | 1 | 输入 | 复位 |
3 | dwb_ack_i | 1 | 输入 | 响应 |
4 | dwb_err_i | 1 | 输入 | 错误 |
5 | dwb_rty_i | 1 | 输入 | 重试 |
6 | dwb_dat_i | 32 | 输入 | 数据输入 |
7 | dwb_cyc_o | 1 | 输出 | 循环 |
8 | dwb_adr_o | 32 | 输出 | 地址 |
9 | dwb_stb_o | 1 | 输出 | 选通 |
10 | dwb_we_o | 1 | 输出 | 写使能 |
11 | dwb_sel_o | 4 | 输出 | 字节选择 |
12 | dwb_dat_o | 32 | 输出 | 数据输出 |
13 | dwb_cab_o | 1 | 输出 | 突发 |
14 | dwb_cti_o | 3 | 输出 | 循环类型 |
15 | dwb_bte_o | 2 | 输出 | 突发类型扩展 |
1.4 调试IO端口信号
OR1200调试IO端口信号 | ||||
序号 | 信号 | 宽度 | 方向 | 功能 |
1 | dbg_stall_i | 1 | 输入 | 停止CPU |
2 | dbg_dat_i | 32 | 输入 | 数据输入 |
3 | dbg_adr_i | 32 | 输入 | 地址输入 |
4 | dbg_op_i | 3 | 输入 | 操作选择 |
5 | dbg_ewt_i | 1 | 输入 | 观察点触发 |
6 | dbg_lss_o | 4 | 输出 | Load/Store单元状态 |
7 | dbg_is_o | 2 | 输出 | 指令预取状态 |
8 | dbg_wp_o | 11 | 输出 | 观察点 |
9 | dbg_bp_o | 1 | 输出 | 断点 |
10 | dbg_dat_o | 32 | 输出 | 数据输出 |
1.5 电源管理IO端口信号
OR1200电源管理IO端口信号 | ||||
序号 | 信号 | 宽度 | 方向 | 功能 |
1 | pm_cpustall_i | 1 | 输入 | 停止CPU |
2 | pm_clksd_o | 4 | 输出 | 时钟停止因数 |
3 | pm_dc_gate_o | 1 | 输出 | 门控数据缓存时钟 |
4 | pm_ic_gate_o | 1 | 输出 | 门控指令缓存时钟 |
5 | pm_dmmu_gate_o | 1 | 输出 | 门控数据MMU时钟 |
6 | pm_immu_gate_o | 1 | 输出 | 门控指令MMU时钟 |
7 | pm_tt_gate_o | 1 | 输出 | 门控滴答定时器时钟 |
8 | pm_cpu_gate_o | 1 | 输出 | 门控CPU主时钟 |
9 | pm_wakeup_o | 1 | 输出 | 唤醒 |
10 | pm_lvolt_o | 1 | 输出 | 低压状态 |
2. Wishbone总线
总线规范是一种片上系统IP核互连体系结构。它定义了一种IP 核之间公共的逻辑接口,减轻了系统组件集成的难度,提高了系统组件的可重用性、可靠性和可移植性,加快产品市场化的速度。目前常见的片上总线规范有ARM公司的AMBA、IBM公司的CoreConnect、Altera公司的Avalon、以及Wishbone。
Wishbone是Silicore公司提出来的,现已被移交给OpenCores组织维护。由于其开放性,已有不少的用户群体,特别是一些免费的IP核,大多采用Wishbone标准。Wishbone总线规范用于软核、固核和硬核,对开发工具和目标硬件没有特殊要求,并且兼容绝大多数已有的综合工具,可以用多种硬件描述语言来实现。
为满足不同系统的需要,Wishbone总线提供了四种不同的IP核互连方式:
点到点(Point to Point):用于两IP核直接互连;
数据流(Data Flow):用于多个串行IP之间的数据并发传输;
共享总线(Shared Bus):多个IP核共享一条总线;
交叉开关(Crossbar Switch):同时连接多个主从部件,提高系统吞吐量。
wishbone总线主要特征如下:
所有应用适用于同一种总线体系结构;
是一种简单、紧凑的逻辑IP核硬件接口,只需很少的逻辑单元即可实现;
时序非常简单
主/从结构的总线,支持多个总线主设备
8~64位数据总线(可扩充)
单周期读/写
支持所有常用的总线数据传输协议,如单字节读/写周期、块传输周期、控制操作及其他的总线事务等;
支持多种IP核互连网络,如单向总线、双向总线、基于多路互用的互连网络、基于三态的互连网络等;
支持总线周期的正常结束、重试结束和错误结束;
使用用户自定义标记(TAG),确定数据传输类型、中断向量等;
仲裁机制由用户自定义;
独立于硬件技术(FPGA、ASIC、bipolar、MOS等),IP核类型(软核、固核、硬核),综合工具,布局和布线技术等。
2.1 Wishbone总线信号
Wishbone总线信号分为四类:系统控制信号、主从共有信号、主设备信号和从设备信号。
2.1.1 系统控制信号
序号 | 信号 | 功能 | 描述 |
1 | CLK_O | 系统时钟输出 | 系统时钟输出。由SYSCON模块产生,它同步Wishbone互连的所有内部信号有效。INTERCON(主/从设备连接)模块连接CLK_O和主从设备的CLK_I信号。 |
2 | RST_O | 复位输出 | 由SYSCON模块产生,它强制所有的Wishbone接口重新启动。所有的内部自启动状态将被强制处于初始状态。INTERCON模块(主/从设备连接模块)连接RST_O和主设备的RST_I信号。 |
2.1.2 主从共有信号
序号 | 信号 | 功能 | 描述 |
1 | CLK_I | 时钟输入 | 同步Wishbone互连的所有内部信号有效。所有的Wishbone输出信号在CLK_I的上升沿寄存,在CLK_I的上升沿前处于稳定状态。 |
2 | RST_I | 复位输入 | 强制Wishbone接口重新启动。此外,所有的内部自启动状态机将被强制处于初始状态。这个信号只复位Wishbone接口,不需复位IP Core的其他部分。 |
3 | DAT_I | 数据输入总线 | 用来传递二进制数据。总线的边界由端口大小决定,端口的最大值为64位(如DAT_I[0:63]) |
4 | DAT_O | 数据输出总线 | 用于传递二进制数据。总线的边界由端口大小决定,端口的最大值64位(如DAT_O[0:63]) |
5 | TGD_I | 数据标记类型 | 用于主设备和从设备的接口上。它包含与数据输入总线DAT_I有关的信息,并且由STB_I信号决定有效性。比如,奇偶保护、错误修正和时序标记信号可以附加在数据总线上。由于新信号的时序已经预先定义,这些标记简化了新信号的定义工作。在接口的数据手册中必须定义数据标记的名称和操作。 |
6 | TGD_O | 数据标记类型 | 用于主设备和从设备的接口上。它包含与数据输出总线DAT_O有关的信息,并且由STB_I信号决定有效性。由于新信号的时序已经预先定义,这些标记位简化了新信号的定义工作。在接口的数据手册中必须定义数据标记的名称和操作。 |
2.1.3 主设备信号
序号 | 信号 | 功能 | 描述 |
1 | ADR_O | 地址输出总线 | 用于传递二进制地址。总线的高端边界由IP Core的地址总线的宽度决定,总线的低端边界由数据端口的宽度和粒度决定。比如,一个32位的数据端口的字节粒度是ADR_O[2:n]。对于有些情况(比如FIFO接口),在接口中没有这个总线。 |
2 | WE_O | 写使能输出 | 指示当前的本地总线循环是READ循环还是WRITE循环。 1代表写,0代表读。 |
3 | SEL_O | 选择输出总线 | 指示在READ循环时有效数据在DAT_I总线中的位置,以及在WRITE循环时有效数据在DAT_O总线中的位置。选择输出总线的边界由端口的粒度决定。比如,如果在一个64位的端口中使用8位的粒度,那么选择输出总线将有8个信号,边界是SEL_O[0:7]。每个单独的选择信号确定64位数据总线的8个有效字节中的一个。 |
4 | STB_O | 选通输出 | 指示一个有效的数据传输循环。它用于确定像SEL_O这样的接口上的其他信号的有效性。对于每个STB_O信号的声明,从设备需要声明ACK_I、ERR_I或RTY_I信号。 |
5 | ACK_I | 应答输入 | 当它有效时,表明一个总线循环的正常结束。 |
ERR_I | 错误输入 | 提示一次错误的总线循环的结束。错误源和主设备的反应由IP Core的提供方定义。 | |
RTY_I | 重试输入 | 指示接口没有准备好接收或者发送数据,并且循环应当重试。何时以及如何进行重试由IP Core的提供方定义。 | |
6 | CYC_O | 循环输出 | 当它有效时,表明正在进行一个正确的总线循环。这个信号在所有总线循环持续过程中保持有效。比如,在一个块传送过程中有很多次数据传动。CYC_O在多端口接口(如双口存储器的接口)中很有用。在这种情况下,CYC_O信号需要使用仲裁器提供的共有总线。 |
7 | LOCK_O | 锁定输出 | 当它有效时,表明当前的总线循环不能被打断。锁定信号用于声明需要获取对总线完全拥有权。一旦传送开始,INTERCON模块不会将总线控制权交给其他主设备,直到当前主设备放弃LOCK_O或CYC_O。 |
8 | TGA_O | 地址标记类型 | 包含与地址线ADR_O有关信息,并且由STB_O信号确定有效性。比如,地址尺寸(24位、32位)和存储器管理(保护与非保护)信号可以附加在某一个地址上。由于新信号的时序已经预先定义,这些标记位简化了新信号的定义工作。在接口的数据手册中必须定义数据标记的名称和操作。 |
9 | TGC_O | 循环标记类型 | 包含与总线循环有关的信息,并且由CYC_O信号决定有效性。比如,数据传输、中断响应和缓存控制循环由循环标记来唯一确定。它们也可以用来区别SINGLE、BLOCK和RMW循环。由于新信号的时序已经预先定义,这些标记位简化了新信号的定义工作。在接口的数据手册中必须定义数据标记的名称和操作。 |
2.1.4 从设备信号
序号 | 信号 | 功能 | 描述 |
1 | ADR_I | 地址输入总线 | 用于传递二进制地址。总线的高端边界由IP Core的地址总线的宽度决定,总线的低端边界由数据端口的宽度和粒度决定。比如,一个32位的数据端口的字节粒度是ADR_O[2:n]。对于有些情况(比如FIFO接口),在接口中没有这个总线。 |
2 | WE_I | 写使能输入 | 指示当前的本地总线循环是READ循环还是WRITE循环。 1代表写,0代表读。 |
3 | SEL_I | 选择输入总线 | 指示在WRITE循环时有效数据在DAT_I总线中的位置,和在READ循环时有效数据在DAT_O总线中的位置。选择输出总线的边界由端口的粒度决定。比如,如果在一个64位的端口中使用8位的粒度,那么选择输出总线将有8个信号,边界是SEL_I[0:7]。每个单独的选择信号确定64位数据总线的8个有效字节中的一个。 |
4 | STB_I | 选通输入 | 当它有效时,指示这个从设备被选中。当STB_I有效时,一个从设备应当只对其他的Wishbone信号作出反应。对于每个STB_I信号的声明,从设备需要声明ACK_O、ERR_O或RTY_O。 |
5 | ACK_O | 应答输出 | 当它有效时,表明一个总线循环的正常结束。 |
ERR_O | 错误输出 | 指示一次错误的总线循环的结束。错误源和主设备的反应由IP Core的提供定义。 | |
RTY_O | 重试输出 | 指示接口没有准备好接收或发送数据,并且循环应该重试。何时以及如何进行重试由IP Core的提供定义。 | |
6 | CYC_I | 循环输入 | 当它有效时,表明正在进行一个正确的总线循环。这个信号在所有总线循环的持续过程中保持有效。比如,在一个块传送过程中会有多次输出传送。CYC_I信号在第一次数据传输时有效,并且一直保持到最后一个数据传输。 |
7 | LOCK_I | 锁定输入 | 当它有效时,表明当前的总线循环不能被打断。一个收到LOCK_I信号的从设备只能被一个主设备访问,直到LOCK_I或CYC_I无效。 |
8 | TGA_I | 地址标记类型 | 包含与地址线ADR_I有关的信息,并且由STB_O信号确定有效性。比如,地址尺寸(24位、32位)和存储器管理(保护与非保护)信息可以附加在某一个地址上。由于新信号的时序已经预先定义,这些标记位简化了新信号的定义工作。在接口的数据手册中必须定义数据标记的名称和操作。 |
9 | TGC_I | 循环标记类型 | 包含与总线循环有关信息,并且由CYC_I信号决定有效性。比如,数据传输、中断响应和缓存控制循环,由循环标记来唯一确定。他们也可以用来区别SINGLE、BLOCK和RMW循环。由于新信号的时序已经预先定义,这些标记位简化了新信号的定义工作。在接口的数据手册中必须定义数据标记的名称和操作。 |
2.2 Wishbone总线时序
一个总线周期由多个不同的时钟周期构成,完成单次读/写操作、块读/写操作、读改写操作, 总线周期也相应地分为单次读/写周期、块读/写周期、读改写周期。
具体时序,请参考对应书籍。
参考来源:
[1] 《步步惊芯—软核处理器内部设计分析》 雷思磊 电子工业出版社
[2] 《开源软核处理器OpenRisc的SOPC设计》 徐敏、孙恺等 北京航空航天出版社