OPB To Wishbone Bridge

Apr 16, 2007 5 Replies

Hi all, I am looking for an OPB to wishbone bridge to let OPB talk to my IP via wishbone in EDK. I have read some posts on OPB-> wishbone wrapper (available at opencores.org). Had a look at the wrapper, which raises a couple of questions in my mind. Where is the OPB bus translation to wishbone bus taking place in this wrapper? How to use it in an environment where the IP is connected to the wishbone slave and the wishbone slave has to be read and written by the OPB from the microblaze side? To start with, lets take the example that the wishbone slave is connected to SRAM at the other end and the microblaze writes and reads the SRAM via opb-> wishbone interface. In this scenario, how would this opb->wishbone wrapper help.



will be waiting for a reply................



Farhan



Hi Farhan,

My experience with this wrapper was not a good one.

It won't bridge a memory controller for you, because it has an (undocumented) limit of only working in the address range

0x80000000-0x800000ff. It won't signal SI_ToutSup either, resulting in another hard-to-meet timing requirement on your memory controller.

I tried to use the bridge to interface with a wishbone ATA host (also from opencores). It sort-of worked, but it was far from satisfying. Reading the OPB IPIF specs I realized that most signals map one-to-one with WB. It was a piece of cake to connect the wishbone peripherial directly to the OPB IPIF, without bridge. Faster, cheaper, better.

Regards, Marc

Hi Marc, Did you get my reply to your answer? I replied to your answer on the group but I dont see my reply appearing here. I sent my reply to you directly by using the 'Reply to Author' option. I hope you received it.

waiting for some more help from you.

Regards Farhan

-------------------------------------------------------------------------------------------------------------------------- Since my last reply appeared on the group, let me post my 'lost' reply once again.

------------------------------------------------------------------------------------------------------------------------- "Marc, what you are saying is, I should throw away the OPB-> wishbone wrapper and directly connect the OPB IPIF signals to wishbone (slave, in my case) signals. Could you kindly give me more details on which IPIF signal to connect with wishbone slave signals. Following is a list of the wishbone slave signals that have to talk to OPB via IPIF.

=================================== input CLK_I; input RST_I; input [31:0] ADR_I; input CYC_I; input [31:0] DAT_I; input [3:0] SEL_I; input STB_I; input WE_I; input [2:0] CTI_I; input [1:0] BTE_I;

output [31:0] DAT_O; output ACK_O; output ERR_O; output RTY_O; ===================================

I hope I am making some sense here while asking for more details :)

Regards Farhan

Hi Farhan,

Here's how I wired the wishbone ATA controller to the OPB IPIF. I hope it helps.

--- OPB2IPIF

signal sig_o2i_Clk_o : std_logic; -- opb2ipif_0 signal sig_o2i_Reset_o : std_logic; signal sig_o2i_Freeze_o : std_logic; signal sig_o2i_AddrValid_o : std_logic; signal sig_o2i_Burst_o : std_logic; signal sig_o2i_RNW_o : std_logic; signal sig_o2i_CS_o : std_logic_vector(0 to 0); signal sig_o2i_CE_o : std_logic_vector(0 to 0); signal sig_o2i_RdCE_o : std_logic_vector(0 to 0); signal sig_o2i_WrCE_o : std_logic_vector(0 to 0); signal sig_o2i_Ack_i : std_logic; signal sig_o2i_Retry_i : std_logic; signal sig_o2i_Error_i : std_logic; signal sig_o2i_ToutSup_i : std_logic; signal sig_o2i_PostedWrInh_i : std_logic; signal sig_o2i_AddrAck_i : std_logic;

signal sig_o2i_Addr_o_xil : std_logic_vector(0 to 31); signal sig_o2i_Data_o_xil : std_logic_vector(0 to 31); signal sig_o2i_BE_o_xil : std_logic_vector(0 to 3); signal sig_o2i_Data_i_xil : std_logic_vector(0 to 31);

signal sig_o2i_Addr_o : std_logic_vector(31 downto 0); signal sig_o2i_Data_o : std_logic_vector(31 downto 0); signal sig_o2i_BE_o : std_logic_vector( 3 downto 0); signal sig_o2i_Data_i : std_logic_vector(31 downto 0);

--- WISHBONE bus

signal sig_wb_data_o : std_logic_vector (31 downto 0); signal sig_wb_data_i : std_logic_vector (31 downto 0); -- signal sig_wb_addr_o : std_logic_vector (31 downto 0); signal sig_wb_cyc_o : std_logic; signal sig_wb_stb_o : std_logic; signal sig_wb_sel_o : std_logic_vector ( 3 downto 0); signal sig_wb_we_o : std_logic; signal sig_wb_ack_i : std_logic; signal sig_wb_err_i : std_logic; signal sig_wb_rty_i : std_logic;

--- Components

component edk port (

...

o2i_Clk_o_pin : out std_logic; -- opb2ipif_0 (for ATAHOST) o2i_Reset_o_pin : out std_logic; o2i_Freeze_o_pin : out std_logic; o2i_Addr_o_pin : out std_logic_vector(0 to 31); o2i_AddrValid_o_pin : out std_logic; o2i_Data_o_pin : out std_logic_vector(0 to 31); o2i_BE_o_pin : out std_logic_vector(0 to 3); o2i_Burst_o_pin : out std_logic; o2i_RNW_o_pin : out std_logic; o2i_CS_o_pin : out std_logic_vector(0 to 0); o2i_CE_o_pin : out std_logic_vector(0 to 0); o2i_RdCE_o_pin : out std_logic_vector(0 to 0); o2i_WrCE_o_pin : out std_logic_vector(0 to 0); o2i_Data_i_pin : in std_logic_vector(0 to 31); o2i_Ack_i_pin : in std_logic; o2i_Retry_i_pin : in std_logic; o2i_Error_i_pin : in std_logic; o2i_ToutSup_i_pin : in std_logic; o2i_PostedWrInh_i_pin : in std_logic; o2i_AddrAck_i_pin : in std_logic;

...

); end component;

------------------------------------------------------------------- --- DISK --- -------------------------------------------------------------------

--- signals

signal sig_disk_irq : std_logic; -- disk module requests INTERRUPT signal sig_disk_dma_req : std_logic; -- disk module requests DMA signal sig_disk_dma_ack : std_logic;

--- external pin glue

signal sig_disk_reset_n : std_logic; signal sig_disk_dd_i : std_logic_vector (15 downto 0); signal sig_disk_dd_o : std_logic_vector (15 downto 0); signal sig_disk_dd_t : std_logic; signal sig_disk_dd_oe : std_logic; signal sig_disk_da : std_logic_vector ( 2 downto 0); signal sig_disk_cs0_n : std_logic; signal sig_disk_cs1_n : std_logic; signal sig_disk_dior_n : std_logic; signal sig_disk_diow_n : std_logic; signal sig_disk_iordy : std_logic; signal sig_disk_intrq : std_logic; signal sig_disk_dmarq : std_logic; signal sig_disk_dmack_n : std_logic;

signal sig_disk_dasp_n : std_logic; -- not used signal sig_disk_pdiag_n : std_logic; -- not used

--- core glue

signal sig_disk_da_u : unsigned(2 downto 0);

signal sig_wb_addr_disk_u : unsigned(6 downto 2); signal sig_wb_cs_disk : std_logic;

--- OCIDEC3 core

component atahost_top

generic ( ARST_LVL : std_logic := '0'; -- asynchronous reset level

TWIDTH : natural := 8; -- counter width

-- PIO mode 0 settings (@100MHz clock) PIO_mode0_T1 : natural := 6; -- 70ns PIO_mode0_T2 : natural := 28; -- 290ns PIO_mode0_T4 : natural := 2; -- 30ns PIO_mode0_Teoc : natural := 23; -- 240ns ==> T0 - T1 - T2 =

600 - 70 - 290 = 240

-- Multiword DMA mode 0 settings (@100MHz clock) DMA_mode0_Tm : natural := 4; -- 50ns DMA_mode0_Td : natural := 21; -- 215ns DMA_mode0_Teoc : natural := 21 -- 215ns ==> T0 - Td - Tm =

480 - 50 - 215 = 215 );

port(

-- WISHBONE SYSCON signals

wb_clk_i : in std_logic; -- master clock in arst_i : in std_logic := '1'; -- asynchronous active low reset wb_rst_i : in std_logic := '0'; -- synchronous active high reset

-- WISHBONE SLAVE signals

wb_cyc_i : in std_logic; -- valid bus cycle input wb_stb_i : in std_logic; -- strobe/core select input wb_ack_o : out std_logic; -- strobe acknowledge output wb_rty_o : out std_logic; -- retry output wb_err_o : out std_logic; -- error output wb_adr_i : in unsigned(6 downto 2); -- A6 = '1' ATA devices selected -- A5 = '1' CS1- asserted, '0' CS0- asserted -- A4..A2 ATA address lines -- A6 = '0' ATA controller selected wb_dat_i : in std_logic_vector(31 downto 0); -- Databus in wb_dat_o : out std_logic_vector(31 downto 0); -- Databus out wb_sel_i : in std_logic_vector(3 downto 0); -- Byte select signals wb_we_i : in std_logic; -- Write enable input wb_inta_o : out std_logic; -- interrupt request signal IDE0

-- DMA engine signals

DMA_req : out std_logic; -- DMA request DMA_Ack : in std_logic; -- DMA acknowledge

-- ATA signals

resetn_pad_o : out std_logic; dd_pad_i : in std_logic_vector(15 downto 0); dd_pad_o : out std_logic_vector(15 downto 0); dd_padoe_o : out std_logic; da_pad_o : out unsigned(2 downto 0); cs0n_pad_o : out std_logic; cs1n_pad_o : out std_logic;

diorn_pad_o : out std_logic; diown_pad_o : out std_logic; iordy_pad_i : in std_logic; intrq_pad_i : in std_logic;

dmarq_pad_i : in std_logic; dmackn_pad_o : out std_logic;

debug_pio_sample_indata : out std_logic ); end component;

signal sig_pio_sample : std_logic;

--------------------------------------------------------------------------------------------------- --- --- --- EDK - Embedded Submodule --- --- --- ---------------------------------------------------------------------------------------------------

edk_inst : edk

port map (

...

--- OPB2IPIF

o2i_Clk_o_pin => sig_o2i_Clk_o, o2i_Reset_o_pin => sig_o2i_Reset_o, o2i_Freeze_o_pin => sig_o2i_Freeze_o, o2i_Addr_o_pin => sig_o2i_Addr_o_xil, o2i_AddrValid_o_pin => sig_o2i_AddrValid_o, o2i_Data_o_pin => sig_o2i_Data_o_xil, o2i_BE_o_pin => sig_o2i_BE_o_xil, o2i_Burst_o_pin => sig_o2i_Burst_o, o2i_RNW_o_pin => sig_o2i_RNW_o, o2i_CS_o_pin => sig_o2i_CS_o, o2i_CE_o_pin => sig_o2i_CE_o, o2i_RdCE_o_pin => sig_o2i_RdCE_o, o2i_WrCE_o_pin => sig_o2i_WrCE_o, o2i_Data_i_pin => sig_o2i_Data_i_xil, o2i_Ack_i_pin => sig_o2i_Ack_i, o2i_Retry_i_pin => sig_o2i_Retry_i, o2i_Error_i_pin => sig_o2i_Error_i, o2i_ToutSup_i_pin => sig_o2i_ToutSup_i, o2i_PostedWrInh_i_pin => sig_o2i_PostedWrInh_i, o2i_AddrAck_i_pin => sig_o2i_AddrAck_i,

...

);

--------------------------------------------------------------------------------------------------- --- --- --- --- --- OPB IPIF to WB --- --- --- --- --- ---------------------------------------------------------------------------------------------------

--- Reverse stupid xilinx "big endian" addressing

o2i_xil1 : for i in 0 to 31 generate sig_o2i_Data_i_xil (31-i)

ic; -- opb2ipif_0

ic;

ic;

ic;

ic;

ic;

ic_vector(0 to 0);

ic_vector(0 to 0);

ic_vector(0 to 0);

ic_vector(0 to 0);

ic;

ic;

ic;

ic;

ic;

ic;

ic_vector(0 to 31);

ic_vector(0 to 31);

ic_vector(0 to 3);

ic_vector(0 to 31);

ic_vector(31 downto 0);

ic_vector(31 downto 0);

ic_vector( 3 downto 0);

ic_vector(31 downto 0);

ic_vector (31 downto 0);

ic_vector (31 downto 0);

ic_vector (31 downto 0);

ic;

ic;

ic_vector ( 3 downto 0);

ic;

ic;

ic;

ic;

out std_logic; -- opb2ipif_0 (for ATAHOST)

out std_logic;

out std_logic;

out std_logic_vector(0 to 31);

out std_logic;

out std_logic_vector(0 to 31);

out std_logic_vector(0 to 3);

out std_logic;

out std_logic;

out std_logic_vector(0 to 0);

out std_logic_vector(0 to 0);

out std_logic_vector(0 to 0);

out std_logic_vector(0 to 0);

in std_logic_vector(0 to 31);

in std_logic;

in std_logic;

in std_logic;

in std_logic;

in std_logic;

in std_logic;

----------

---

----------

ic; -- disk module requests

ic; -- disk module requests

ic;

ic;

ic_vector (15 downto 0);

ic_vector (15 downto 0);

ic;

ic;

ic_vector ( 2 downto 0);

ic;

ic;

ic;

ic;

ic;

ic;

ic;

ic;

ic; -- not used

ic; -- not used

d(2 downto 0);

d(6 downto 2);

ic;

ic :=3D '0'; -- asynchronous reset level

:=3D 8; -- counter width

:=3D 6; -- 70ns

:=3D 28; -- 290ns

:=3D 2; -- 30ns

:=3D 23; -- 240ns =3D=3D> T0 - T1 - T2 =3D

clock)

:=3D 4; -- 50ns

:=3D 21; -- 215ns

:=3D 21 -- 215ns =3D=3D> T0 - Td - Tm =3D

td_logic; -- master clock in

td_logic :=3D '1'; -- asynchronous active low reset

td_logic :=3D '0'; -- synchronous active high

td_logic; -- valid bus cycle input

td_logic; -- strobe/core select input

td_logic; -- strobe acknowledge output

td_logic; -- retry output

td_logic; -- error output

nsigned(6 downto 2); -- A6 =3D '1' ATA devices

-- A5 =3D

-- A4..A2

-- A6 =3D '0' ATA

td_logic_vector(31 downto 0); -- Databus in

td_logic_vector(31 downto 0); -- Databus out

td_logic_vector(3 downto 0); -- Byte select

td_logic; -- Write enable input

td_logic; -- interrupt request signal IDE0

td_logic; -- DMA request

td_logic; -- DMA acknowledge

td_logic;

td_logic_vector(15 downto 0);

td_logic_vector(15 downto 0);

td_logic;

nsigned(2 downto 0);

td_logic;

td_logic;

td_logic;

td_logic;

td_logic;

td_logic;

td_logic;

td_logic;

td_logic

ic;

----------=AD------------------------

---

---

---

----------=AD------------------------

=3D> sig_o2i_Clk_o,

=3D> sig_o2i_Reset_o,

=3D> sig_o2i_Freeze_o,

=3D> sig_o2i_Addr_o_xil,

=3D> sig_o2i_AddrValid_o,

=3D> sig_o2i_Data_o_xil,

=3D> sig_o2i_BE_o_xil,

=3D> sig_o2i_Burst_o,

=3D> sig_o2i_RNW_o,

=3D> sig_o2i_CS_o,

=3D> sig_o2i_CE_o,

=3D> sig_o2i_RdCE_o,

=3D> sig_o2i_WrCE_o,

=3D> sig_o2i_Data_i_xil,

=3D> sig_o2i_Ack_i,

=3D> sig_o2i_Retry_i,

=3D> sig_o2i_Error_i,

=3D> sig_o2i_ToutSup_i,

=3D> sig_o2i_PostedWrInh_i,

=3D> sig_o2i_AddrAck_i,

----------=AD------------------------

---

---

---

---

---

----------=AD------------------------

sig_o2i_Data_o (i) = sig_o2i_Addr_o (i) = end generate;

end generate;

----------=AD------------------------

---

---

penCores ---

---

---

----------=AD------------------------

-- A5 =3D '1' CS1- asserted, '0' CS0- = asserted

-- A4..A2 ATA address lines

-- A6 =3D '0' ATA controller selected

-- Byte select signals

-- we're going to invert reset

-- counter width

lock)

-- 70ns

-- 290ns

-- 30ns

-- 240ns =3D=3D> T0 - T1 - T2 =3D 600= - 70 -

(@100MHz clock)

-- 50ns

-- 215ns

-- 215ns =3D=3D> T0 - Td - Tm =3D 480= - 50 -

OPB, -- master clock in

RST), -- asynchronous active low reset

-- synchronous active high reset

wb_cyc_o, -- valid bus cycle input

wb_stb_o, -- strobe/core select input

wb_ack_i, -- strobe acknowledge output

wb_rty_i, -- retry output

wb_err_i, -- error output

wb_addr_disk_u, -- A6 =3D '1' ATA devices

-- A5 =3D '1' CS1- asserted, '0' CS0- = asserted

-- A4..A2 ATA address lines

-- A6 =3D '0' ATA controller selected

wb_data_o, -- Databus in

wb_data_i, -- Databus out

wb_sel_o, -- Byte select signals

wb_we_o, -- Write enable input

disk_irq, -- interrupt request signal IDE0

disk_dma_req, -- DMA request

disk_dma_ack, -- DMA acknowledge

disk_reset_n,

disk_dd_i,

disk_dd_o,

disk_dd_oe,

disk_da_u,

disk_cs0_n,

disk_cs1_n,

disk_dior_n,

disk_diow_n,

disk_iordy,

disk_intrq,

disk_dmarq,

disk_dmack_n,

pio_sample

AULT",

T"

disk_reset_n,

_DD_RESET_N

AULT",

T"

disk_cs0_n,

_CS0_N

AULT",

T"

disk_cs1_n,

_CS1_N

AULT",

T"

disk_da (0),

_DA0

AULT",

T"

disk_da (1),

_DA1

AULT",

T"

disk_da (2),

_DA2

MAL",

AULT",

T"

disk_dd_o (i),

disk_dd_i (i),

disk_dd_t,

_DD_DD (i)

AULT",

T"

disk_dior_n,

_DIOR_HDMARDY_HSTB

AULT",

T"

disk_diow_n,

_DIOW_STOP

AULT",

T"

disk_dmack_n,

_DMACK_N

MAL",

AULT",

W"

disk_dmarq,

_DMARQ

MAL",

AULT",

W"

disk_intrq,

_INTRQ

MAL",

AULT",

W"

disk_iordy,

_IORDY_DDMARDY_DSTB

AULT",

W"

_CSEL

",

AULT"

_DASP_N,

disk_dasp_n

",

AULT"

_PDIAG_N,

disk_pdiag_n

AULT",

W"

P1

_DD_DD (7) -- ATA7 pg.38: 10k pulldown on DD7 to

_DMARQ -- ATA7 pg.38: 5k6 pulldown

_IORDY_DDMARDY_DSTB -- ATA7 pg.38: 4k7 pullup

_INTRQ -- ATA7 pg.38: 6k2 pulldown -> selects

Thanks Marc, Well, I am a Verilog guy, will take some time to decipher VHDL code into Verilog. Will let you know in case I need more details.

Best Wishes, Farhan

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required