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设计》 徐敏、孙恺等 北京航空航天出版社
