上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人
3.11 WISHBONE共享总线连接示例
WISHBONE共享总线连接与点到点连接同样重要。在本例中,两个主设备和两个从设备通过SYSCON实现了共享总线连接,如图3-23所示。在后续章节中,将使用该例子对OR1200进行基本RTL验证。系统复位后,一个或多个主设备通过置高CYC_O请求使用总线,仲裁器(后文将讨论)选择其中一个主设备#X(X在0和N之间),只将该主设备对应的GNTX信号置高,而将其他GNT信号置低以通知INTERCON哪一个主设备可以使用总线。
图3-23 基于选择器的WISHBONE共享总线连接示例
一旦主设备选定,其输出信号将通过选择器送到共享总线进而送到各个从设备。例如,如果主设备#0被中可以使用总线,则器ADR()、DAT_O()、SEL_O()、WE_O和STB_O信号将被送到各个从设备。与此同时请求使用总线的其他设备,将永远接收不到总线周期结束信号ACK_I/ERR_I/RTY_I。
从设备是如何被选择的呢?若系统中有M个从设备,则地址线被地址译码器分为M个部分,别代表每一个从设备的地址空间。从设备#Y对应的译码输出信号与共享总线上的STB_I信号相与,如果STB_I信号和从设备#Y对应的译码输出信号同时为高,从设备#Y才发起对主设备操作的响应。
各个从设备输出的总线周期结束ACK_O/ERR_O/RTY_O被通过或门送到各个主设备的ACK_I/ERR_I/RTY_I;而从设备的DAT_O()输出则通过选择器送到各个主设备的输入端,这个选择器的输入为共享地址总线。
INTERCON模块的源代码如下:
module intercon2M2S(clk_i, rst_i, wb0s_data_i, wb0s_data_o, wb0_addr_i, wb0_sel_i, wb0_we_i, wb0_cyc_i, wb0_stb_i, wb0_ack_o, wb0_err_o, wb0_rty_o, wb0m_data_i, wb0m_data_o, wb0_addr_o, wb0_sel_o, wb0_we_o, wb0_cyc_o, wb0_stb_o, wb0_ack_i, wb0_err_i, wb0_rty_i, wb1s_data_i, wb1s_data_o, wb1_addr_i, wb1_sel_i, wb1_we_i, wb1_cyc_i, wb1_stb_i, wb1_ack_o, wb1_err_o, wb1_rty_o, wb1m_data_i, wb1m_data_o, wb1_addr_o, wb1_sel_o, wb1_we_o, wb1_cyc_o, wb1_stb_o, wb1_ack_i, wb1_err_i, wb1_rty_i ); ……//这里忽略了端口定义 //仲裁器,两个主设备,两个从设备 wire GNT0,GNT1,CYC; arbiter2M2S arbiter2M2S(.CLK(clk_i),.RST(rst_i),.CYC0(wb0_cyc_i),.CYC1(wb1_cyc_i), .GNT0(GNT0),.GNT1(GNT1),.CYC(CYC)); //地址译码器 wire ACMP0,ACMP1; wire [31:0] shared_address; address_decoder2S address_decoder2S(.addr_i(shared_address),.ACMP0(ACMP0),.ACMP1(ACMP1)); //共享总线周期有效信号CYC,从各主设备到各从设备 assign wb0_cyc_o=CYC; assign wb1_cyc_o=CYC; //共享地址信号 assign shared_address=GNT1?wb1_addr_i:wb0_addr_i; assign wb0_addr_o=shared_address; assign wb1_addr_o=shared_address; //从各主设备到各从设备的共享数据总线 wire [31:0] shared_data_m2s=GNT1?wb1m_data_i:wb0m_data_i; assign wb0s_data_o=shared_data_m2s; assign wb1s_data_o=shared_data_m2s; //从各从设备到各主设备的共享数据总线 wire [31:0] shared_data_s2m=ACMP1?wb1s_data_i:wb0s_data_i; assign wb0m_data_o=shared_data_s2m; assign wb1m_data_o=shared_data_s2m; //从各主设备到各从设备的共享选择信号 wire [3:0] shared_sel=GNT1?wb1_sel_i:wb0_sel_i; assign wb0_sel_o=shared_sel; assign wb1_sel_o=shared_sel; //从各主设备到各从设备的共享写使能信号 wire shared_we=GNT1?wb1_we_i:wb0_we_i; assign wb0_we_o=shared_we; assign wb1_we_o=shared_we; //从各主设备到各从设备的共享选通信号 wire shared_stb=GNT1?wb1_stb_i:wb0_stb_i; assign wb0_stb_o=ACMP0?shared_stb:1'b0; assign wb1_stb_o=ACMP1?shared_stb:1'b1; //从各从设备到各主设备的应答信号 wire shared_ack=ACMP0?wb0_ack_i:wb1_ack_i; assign wb0_ack_o=shared_ack; assign wb1_ack_o=shared_ack; wire shared_err=ACMP0?wb0_err_i:wb1_err_i; assign wb0_err_o=shared_err; assign wb1_err_o=shared_err; wire shared_rty=ACMP0?wb0_rty_i:wb1_rty_i; assign wb0_rty_o=shared_rty; assign wb1_rty_o=shared_rty;