URL
https://opencores.org/ocsvn/wb_tk/wb_tk/trunk
Subversion Repositories wb_tk
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 3 to Rev 4
- ↔ Reverse comparison
Rev 3 → Rev 4
/trunk/TestBench/wb_arbiter_TB.vhd
File deleted
/trunk/TestBench/wb_async_master_TB.vhd
File deleted
/trunk/TestBench/wb_bus_upsize_TB.vhd
File deleted
/trunk/TestBench/wb_out_reg_TB.vhd
0,0 → 1,279
-- |
-- A test bench for 32-bit access |
-- |
|
library ieee,wb_tk; |
use ieee.std_logic_1164.all; |
use wb_tk.technology.all; |
use wb_tk.wb_test.all; |
|
entity wb_out_reg_tb_32 is |
-- Generic declarations of the tested unit |
generic( |
width : POSITIVE := 16; |
bus_width : POSITIVE := 32; |
offset : INTEGER := 4 ); |
end wb_out_reg_tb_32; |
|
architecture TB of wb_out_reg_tb_32 is |
-- Component declaration of the tested unit |
component wb_out_reg |
generic( |
width : POSITIVE := width; |
bus_width : POSITIVE := bus_width; |
offset : INTEGER := offset ); |
port ( |
clk_i: in std_logic; |
rst_i: in std_logic; |
rst_val: std_logic_vector(width-1 downto 0) := (others => '0'); |
|
cyc_i: in std_logic := '1'; |
stb_i: in std_logic; |
sel_i: in std_logic_vector ((bus_width/8)-1 downto 0) := (others => '1'); |
we_i: in std_logic; |
ack_o: out std_logic; |
ack_oi: in std_logic := '-'; |
adr_i: in std_logic_vector (size2bits((width+offset+bus_width-1)/bus_width)-1 downto 0) := (others => '0'); |
dat_i: in std_logic_vector (bus_width-1 downto 0); |
dat_oi: in std_logic_vector (bus_width-1 downto 0) := (others => '-'); |
dat_o: out std_logic_vector (bus_width-1 downto 0); |
q: out std_logic_vector (width-1 downto 0) |
); |
end component; |
|
-- Stimulus signals - signals mapped to the input and inout ports of tested entity |
signal adr_i : std_logic_vector (size2bits((width+offset+bus_width-1)/bus_width)-1 downto 0) := (others => '0'); |
signal clk_i : std_logic; |
signal rst_i : std_logic; |
signal rst_val : std_logic_vector((width-1) downto 0) := (others => '0'); |
signal cyc_i : std_logic; |
signal stb_i : std_logic; |
signal sel_i : std_logic_vector(((bus_width/8)-1) downto 0) := (others => '1'); |
signal we_i : std_logic; |
signal ack_oi : std_logic; |
signal dat_i : std_logic_vector((bus_width-1) downto 0); |
signal dat_oi : std_logic_vector((bus_width-1) downto 0); |
-- Observed signals - signals mapped to the output ports of tested entity |
signal ack_o : std_logic; |
signal dat_o : std_logic_vector((bus_width-1) downto 0); |
signal q : std_logic_vector((width-1) downto 0); |
|
-- Add your code here ... |
|
begin |
rst_val <= (others => '0'); |
ack_oi <= 'U'; |
dat_oi <= (others => 'U'); |
|
-- Unit Under Test port map |
UUT : wb_out_reg |
port map |
(clk_i => clk_i, |
rst_i => rst_i, |
rst_val => rst_val, |
cyc_i => cyc_i, |
stb_i => stb_i, |
sel_i => sel_i, |
we_i => we_i, |
ack_o => ack_o, |
ack_oi => ack_oi, |
adr_i => adr_i, |
dat_i => dat_i, |
dat_oi => dat_oi, |
dat_o => dat_o, |
q => q ); |
|
clk: process is |
begin |
clk_i <= '0'; |
wait for 25ns; |
clk_i <= '1'; |
wait for 25ns; |
end process; |
|
reset: process is |
begin |
rst_i <= '1'; |
wait for 150ns; |
rst_i <= '0'; |
wait; |
end process; |
|
master: process is |
begin |
we_i <= '0'; |
cyc_i <= '0'; |
stb_i <= '0'; |
adr_i <= (others => '0'); |
dat_i <= (others => '0'); |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
|
wr_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,"0","00000000000000000000000000000000"); |
rd_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,"0","00000000000000000000000000000000"); |
wr_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,"0","11111111111111111111111111111111"); |
rd_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,"0","11111111111111111111111111111111"); |
wr_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,"0","01110110010101000011001000010000"); |
rd_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,"0","01110110010101000011001000010000"); |
|
sel_i <= add_one(sel_i); |
-- if (sel_i = "1111") then wait; end if; |
end process; |
end TB; |
|
configuration TB_wb_out_reg_32 of wb_out_reg_tb_32 is |
for TB |
for UUT : wb_out_reg |
use entity work.wb_out_reg(wb_out_reg); |
end for; |
end for; |
end TB_wb_out_reg_32; |
|
|
|
-- |
-- A test bench for 16-bit access |
-- |
|
|
library ieee,wb_tk; |
use ieee.std_logic_1164.all; |
use wb_tk.technology.all; |
use wb_tk.wb_test.all; |
|
entity wb_out_reg_tb_16 is |
-- Generic declarations of the tested unit |
generic( |
width : POSITIVE := 16; |
bus_width : POSITIVE := 16; |
offset : INTEGER := 4 ); |
end wb_out_reg_tb_16; |
|
architecture TB of wb_out_reg_tb_16 is |
-- Component declaration of the tested unit |
component wb_out_reg |
generic( |
width : POSITIVE := width; |
bus_width : POSITIVE := bus_width; |
offset : INTEGER := offset ); |
port ( |
clk_i: in std_logic; |
rst_i: in std_logic; |
rst_val: std_logic_vector(width-1 downto 0) := (others => '0'); |
|
cyc_i: in std_logic := '1'; |
stb_i: in std_logic; |
sel_i: in std_logic_vector ((bus_width/8)-1 downto 0) := (others => '1'); |
we_i: in std_logic; |
ack_o: out std_logic; |
ack_oi: in std_logic := '-'; |
adr_i: in std_logic_vector (max(log2((width+offset+bus_width-1)/bus_width)-1,0) downto 0) := (others => '0'); |
dat_i: in std_logic_vector (bus_width-1 downto 0); |
dat_oi: in std_logic_vector (bus_width-1 downto 0) := (others => '-'); |
dat_o: out std_logic_vector (bus_width-1 downto 0); |
q: out std_logic_vector (width-1 downto 0) |
); |
end component; |
|
signal adr_i : std_logic_vector (max(log2((width+offset+bus_width-1)/bus_width)-1,0) downto 0) := (others => '0'); |
-- Stimulus signals - signals mapped to the input and inout ports of tested entity |
signal clk_i : std_logic; |
signal rst_i : std_logic; |
signal rst_val : std_logic_vector((width-1) downto 0) := (others => '0'); |
signal cyc_i : std_logic; |
signal stb_i : std_logic; |
signal sel_i : std_logic_vector(((bus_width/8)-1) downto 0) := (others => '1'); |
signal we_i : std_logic; |
signal ack_oi : std_logic; |
signal dat_i : std_logic_vector((bus_width-1) downto 0); |
signal dat_oi : std_logic_vector((bus_width-1) downto 0); |
-- Observed signals - signals mapped to the output ports of tested entity |
signal ack_o : std_logic; |
signal dat_o : std_logic_vector((bus_width-1) downto 0); |
signal q : std_logic_vector((width-1) downto 0); |
|
-- Add your code here ... |
|
begin |
rst_val <= (others => '0'); |
ack_oi <= 'U'; |
dat_oi <= (others => 'U'); |
|
-- Unit Under Test port map |
UUT : wb_out_reg |
port map |
(clk_i => clk_i, |
rst_i => rst_i, |
rst_val => rst_val, |
cyc_i => cyc_i, |
stb_i => stb_i, |
sel_i => sel_i, |
we_i => we_i, |
ack_o => ack_o, |
ack_oi => ack_oi, |
adr_i => adr_i, |
dat_i => dat_i, |
dat_oi => dat_oi, |
dat_o => dat_o, |
q => q ); |
|
clk: process is |
begin |
clk_i <= '0'; |
wait for 25ns; |
clk_i <= '1'; |
wait for 25ns; |
end process; |
|
reset: process is |
begin |
rst_i <= '1'; |
wait for 150ns; |
rst_i <= '0'; |
wait; |
end process; |
|
master: process is |
begin |
we_i <= '0'; |
cyc_i <= '0'; |
stb_i <= '0'; |
adr_i <= (others => '0'); |
dat_i <= (others => '0'); |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
|
wr_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,"1","0000000000000000"); |
wr_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,"0","0000000000000000"); |
rd_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,"1","0000000000000000"); |
rd_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,"0","0000000000000000"); |
wr_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,"1","1111111111111111"); |
wr_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,"0","1111111111111111"); |
rd_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,"1","1111111111111111"); |
rd_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,"0","1111111111111111"); |
wr_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,"1","0111011001010100"); |
wr_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,"0","0011001000010000"); |
rd_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,"1","0111011001010100"); |
rd_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,"0","0011001000010000"); |
|
sel_i <= add_one(sel_i); |
end process; |
end TB; |
|
configuration TB_wb_out_reg_16 of wb_out_reg_tb_16 is |
for TB |
for UUT : wb_out_reg |
use entity work.wb_out_reg(wb_out_reg); |
end for; |
end for; |
end TB_wb_out_reg_16; |
/trunk/TestBench/wb_bus_dnsize_TB.vhd
0,0 → 1,174
--************************************************************* |
--* This file is automatically generated test bench template * |
--* By ACTIVE-VHDL <TBgen v1.10>. Copyright (C) ALDEC Inc. * |
--* * |
--* This file was generated on: 15:34, 2001.04.22. * |
--* Tested entity name: wb_bus_dnsize * |
--* File name contains tested entity: $DSN\src\wb_bus_dnsize.vhd * |
--************************************************************* |
|
library ieee,wb_tk,synopsys; |
use ieee.std_logic_1164.all; |
use wb_tk.technology.all; |
use synopsys.std_logic_arith.all; |
use wb_tk.wb_test.all; |
|
entity wb_bus_dnsize_tb is |
generic( |
m_bus_width : POSITIVE := 64; |
m_addr_width : POSITIVE := 6; |
s_bus_width : POSITIVE := 16; |
s_addr_width : POSITIVE := 8; |
little_endien : BOOLEAN := true ); |
end wb_bus_dnsize_tb; |
|
architecture TB of wb_bus_dnsize_tb is |
component wb_bus_dnsize |
generic( |
m_bus_width : POSITIVE := m_bus_width; |
m_addr_width : POSITIVE := m_addr_width; |
s_bus_width : POSITIVE := s_bus_width; |
s_addr_width : POSITIVE := s_addr_width; |
little_endien : BOOLEAN := little_endien |
); |
port( |
m_adr_i : in std_logic_vector((m_addr_width-1) downto 0); |
m_sel_i : in std_logic_vector(((m_bus_width/8)-1) downto 0); |
m_dat_i : in std_logic_vector((m_bus_width-1) downto 0); |
m_dat_oi : in std_logic_vector((m_bus_width-1) downto 0); |
m_dat_o : out std_logic_vector((m_bus_width-1) downto 0); |
m_cyc_i : in std_logic; |
m_ack_o : out std_logic; |
m_ack_oi : in std_logic; |
m_err_o : out std_logic; |
m_err_oi : in std_logic; |
m_rty_o : out std_logic; |
m_rty_oi : in std_logic; |
m_we_i : in std_logic; |
m_stb_i : in std_logic; |
s_adr_o : out std_logic_vector((s_addr_width-1) downto 0); |
s_sel_o : out std_logic_vector(((s_bus_width/8)-1) downto 0); |
s_dat_i : in std_logic_vector((s_bus_width-1) downto 0); |
s_dat_o : out std_logic_vector((s_bus_width-1) downto 0); |
s_cyc_o : out std_logic; |
s_ack_i : in std_logic; |
s_err_i : in std_logic; |
s_rty_i : in std_logic; |
s_we_o : out std_logic; |
s_stb_o : out std_logic |
); |
end component; |
|
-- Stimulus signals - signals mapped to the input and inout ports of tested entity |
signal m_adr_i : std_logic_vector((m_addr_width-1) downto 0); |
signal m_sel_i : std_logic_vector(((m_bus_width/8)-1) downto 0) := (others => '0'); |
signal m_dat_i : std_logic_vector((m_bus_width-1) downto 0); |
signal m_dat_oi : std_logic_vector((m_bus_width-1) downto 0) := (others => 'U'); |
signal m_cyc_i : std_logic; |
signal m_ack_oi : std_logic := 'U'; |
signal m_err_oi : std_logic := 'U'; |
signal m_rty_oi : std_logic := 'U'; |
signal m_we_i : std_logic; |
signal m_stb_i : std_logic; |
signal s_dat_i : std_logic_vector((s_bus_width-1) downto 0); |
signal s_ack_i : std_logic; |
signal s_err_i : std_logic; |
signal s_rty_i : std_logic; |
-- Observed signals - signals mapped to the output ports of tested entity |
signal m_dat_o : std_logic_vector((m_bus_width-1) downto 0); |
signal m_ack_o : std_logic; |
signal m_err_o : std_logic; |
signal m_rty_o : std_logic; |
signal s_adr_o : std_logic_vector((s_addr_width-1) downto 0); |
signal s_sel_o : std_logic_vector(((s_bus_width/8)-1) downto 0); |
signal s_dat_o : std_logic_vector((s_bus_width-1) downto 0); |
signal s_cyc_o : std_logic; |
signal s_we_o : std_logic; |
signal s_stb_o : std_logic; |
|
signal clk_i: std_logic; |
signal rst_i: std_logic; |
begin |
|
-- Unit Under Test port map |
UUT : wb_bus_dnsize |
port map |
(m_adr_i => m_adr_i, |
m_sel_i => m_sel_i, |
m_dat_i => m_dat_i, |
m_dat_oi => m_dat_oi, |
m_dat_o => m_dat_o, |
m_cyc_i => m_cyc_i, |
m_ack_o => m_ack_o, |
m_ack_oi => m_ack_oi, |
m_err_o => m_err_o, |
m_err_oi => m_err_oi, |
m_rty_o => m_rty_o, |
m_rty_oi => m_rty_oi, |
m_we_i => m_we_i, |
m_stb_i => m_stb_i, |
s_adr_o => s_adr_o, |
s_sel_o => s_sel_o, |
s_dat_i => s_dat_i, |
s_dat_o => s_dat_o, |
s_cyc_o => s_cyc_o, |
s_ack_i => s_ack_i, |
s_err_i => s_err_i, |
s_rty_i => s_rty_i, |
s_we_o => s_we_o, |
s_stb_o => s_stb_o ); |
|
clk: process is |
begin |
clk_i <= '0'; |
wait for 25ns; |
clk_i <= '1'; |
wait for 25ns; |
end process; |
|
reset: process is |
begin |
rst_i <= '1'; |
wait for 150ns; |
rst_i <= '0'; |
wait; |
end process; |
|
master: process is |
begin |
m_we_i <= '0'; |
m_cyc_i <= '0'; |
m_stb_i <= '0'; |
m_adr_i <= (others => '0'); |
m_dat_i <= (others => '0'); |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
|
wr_val(clk_i, m_adr_i,m_dat_o,m_dat_i,m_we_i,m_cyc_i,m_stb_i,m_ack_o,"000101","1111111011011100101110101001100001110110010101000011001000010000"); |
rd_val(clk_i, m_adr_i,m_dat_o,m_dat_i,m_we_i,m_cyc_i,m_stb_i,m_ack_o,"000101","1111111011011100101110101001100001110110010101000011001000010000"); |
-- wr_val(clk_i, m_adr_i,m_dat_o,m_dat_i,m_we_i,m_cyc_i,m_stb_i,m_ack_o,"000101","01110110010101000011001000010000"); |
-- rd_val(clk_i, m_adr_i,m_dat_o,m_dat_i,m_we_i,m_cyc_i,m_stb_i,m_ack_o,"000101","01110110010101000011001000010000"); |
|
m_sel_i <= add_one(m_sel_i); |
-- if (sel_i = "1111") then wait; end if; |
end process; |
|
s_ack_i <= s_stb_o; |
s_dat_i <= (others => '1'); |
s_err_i <= '0'; |
s_rty_i <= '0'; |
end TB; |
|
configuration TB_wb_bus_dnsize of wb_bus_dnsize_tb is |
for TB |
for UUT : wb_bus_dnsize |
use entity work.wb_bus_dnsize(wb_bus_dnsize); |
end for; |
end for; |
end TB_wb_bus_dnsize; |
|
/trunk/wb_async_slave.vhd
0,0 → 1,184
-- |
-- Wishbone bus toolkit. |
-- |
-- (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/03/31 |
-- This code is distributed under the terms and conditions of the GNU General Public Lince. |
-- |
-- |
-- ELEMENTS: |
-- wb_async_slave: Wishbone bus to async (SRAM-like) bus slave bridge. |
|
------------------------------------------------------------------------------- |
-- |
-- wb_async_slave |
-- |
------------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
library wb_tk; |
use wb_tk.technology.all; |
|
entity wb_async_slave is |
generic ( |
width: positive := 16; |
addr_width: positive := 20 |
); |
port ( |
clk_i: in std_logic; |
rst_i: in std_logic := '0'; |
|
-- interface for wait-state generator state-machine |
wait_state: in std_logic_vector (3 downto 0); |
|
-- interface to wishbone master device |
adr_i: in std_logic_vector (addr_width-1 downto 0); |
sel_i: in std_logic_vector ((addr_width/8)-1 downto 0); |
dat_i: in std_logic_vector (width-1 downto 0); |
dat_o: out std_logic_vector (width-1 downto 0); |
dat_oi: in std_logic_vector (width-1 downto 0) := (others => '-'); |
we_i: in std_logic; |
stb_i: in std_logic; |
ack_o: out std_logic := '0'; |
ack_oi: in std_logic := '-'; |
|
-- interface to async slave |
a_data: inout std_logic_vector (width-1 downto 0) := (others => 'Z'); |
a_addr: out std_logic_vector (addr_width-1 downto 0) := (others => 'U'); |
a_rdn: out std_logic := '1'; |
a_wrn: out std_logic := '1'; |
a_cen: out std_logic := '1'; |
-- byte-enable signals |
a_byen: out std_logic_vector ((width/8)-1 downto 0) |
); |
end wb_async_slave; |
|
architecture wb_async_slave of wb_async_slave is |
-- multiplexed access signals to memory |
signal i_ack: std_logic; |
signal sm_ack: std_logic; |
|
type states is (sm_idle, sm_wait, sm_deact); |
signal state: states; |
signal cnt: std_logic_vector(3 downto 0); |
begin |
ack_o <= (stb_i and i_ack) or (not stb_i and ack_oi); |
dat_o_gen: for i in dat_o'RANGE generate |
dat_o(i) <= (stb_i and a_data(i)) or (not stb_i and dat_oi(i)); |
end generate; |
|
-- For 0WS operation i_ack is an async signal otherwise it's a sync one. |
i_ack_gen: process is |
begin |
wait on sm_ack, stb_i, wait_state, state; |
if (wait_state = "0000") then |
case (state) is |
when sm_deact => i_ack <= '0'; |
when others => i_ack <= stb_i; |
end case; |
else |
i_ack <= sm_ack; |
end if; |
end process; |
|
-- SRAM signal-handler process |
sram_signals: process is |
begin |
wait on state,we_i,a_data,adr_i,rst_i, stb_i, sel_i, dat_i; |
if (rst_i = '1') then |
a_wrn <= '1'; |
a_rdn <= '1'; |
a_cen <= '1'; |
a_addr <= (others => '-'); |
a_data <= (others => 'Z'); |
a_byen <= (others => '1'); |
else |
case (state) is |
when sm_deact => |
a_wrn <= '1'; |
a_rdn <= '1'; |
a_cen <= '1'; |
a_addr <= (others => '-'); |
a_data <= (others => 'Z'); |
a_byen <= (others => '1'); |
when others => |
a_addr <= adr_i; |
a_rdn <= not (not we_i and stb_i); |
a_wrn <= not (we_i and stb_i); |
a_cen <= not stb_i; |
a_byen <= not sel_i; |
if (we_i = '1') then |
a_data <= dat_i; |
else |
a_data <= (others => 'Z'); |
end if; |
end case; |
end if; |
end process; |
|
-- Aysnc access state-machine. |
async_sm: process is |
-- variable cnt: std_logic_vector(3 downto 0) := "0000"; |
-- variable state: states := init; |
begin |
wait until clk_i'EVENT and clk_i = '1'; |
if (rst_i = '1') then |
state <= sm_idle; |
cnt <= ((0) => '1', others => '0'); |
sm_ack <= '0'; |
else |
case (state) is |
when sm_idle => |
-- Check if anyone needs access to the memory. |
-- it's rdy signal will already be pulled low, so we only have to start the access |
if (stb_i = '1') then |
case wait_state is |
when "0000" => |
sm_ack <= '1'; |
state <= sm_deact; |
when "0001" => |
sm_ack <= '1'; |
cnt <= "0001"; |
state <= sm_wait; |
when others => |
sm_ack <= '0'; |
cnt <= "0001"; |
state <= sm_wait; |
end case; |
end if; |
when sm_wait => |
if (cnt = wait_state) then |
-- wait cycle completed. |
state <= sm_deact; |
sm_ack <= '0'; |
cnt <= "0000"; |
else |
if (add_one(cnt) = wait_state) then |
sm_ack <= '1'; |
else |
sm_ack <= '0'; |
end if; |
cnt <= add_one(cnt); |
end if; |
when sm_deact => |
if (stb_i = '1') then |
case wait_state is |
when "0000" => |
cnt <= "0000"; |
sm_ack <= '0'; |
state <= sm_wait; |
when others => |
sm_ack <= '0'; |
cnt <= "0000"; |
state <= sm_wait; |
end case; |
else |
sm_ack <= '0'; |
state <= sm_idle; |
end if; |
end case; |
end if; |
end process; |
end wb_async_slave; |
|
/trunk/wb_arbiter.vhd
0,0 → 1,245
-- |
-- Wishbone bus toolkit. |
-- |
-- (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/03/31 |
-- This code is distributed under the terms and conditions of the GNU General Public Lince. |
-- |
-- |
-- ELEMENTS: |
-- wb_arbiter: two-way bus arbiter. Asyncronous logic ensures 0-ws operation on shared bus |
|
------------------------------------------------------------------------------- |
-- |
-- wb_arbiter |
-- |
------------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
library wb_tk; |
use wb_tk.technology.all; |
|
entity wb_arbiter is |
port ( |
-- clk: in std_logic; |
rst_i: in std_logic := '0'; |
|
-- interface to master device a |
a_we_i: in std_logic; |
a_stb_i: in std_logic; |
a_cyc_i: in std_logic; |
a_ack_o: out std_logic; |
a_ack_oi: in std_logic := '-'; |
a_err_o: out std_logic; |
a_err_oi: in std_logic := '-'; |
a_rty_o: out std_logic; |
a_rty_oi: in std_logic := '-'; |
|
-- interface to master device b |
b_we_i: in std_logic; |
b_stb_i: in std_logic; |
b_cyc_i: in std_logic; |
b_ack_o: out std_logic; |
b_ack_oi: in std_logic := '-'; |
b_err_o: out std_logic; |
b_err_oi: in std_logic := '-'; |
b_rty_o: out std_logic; |
b_rty_oi: in std_logic := '-'; |
|
-- interface to shared devices |
s_we_o: out std_logic; |
s_stb_o: out std_logic; |
s_cyc_o: out std_logic; |
s_ack_i: in std_logic; |
s_err_i: in std_logic := '-'; |
s_rty_i: in std_logic := '-'; |
|
mux_signal: out std_logic; -- 0: select A signals, 1: select B signals |
|
-- misc control lines |
priority: in std_logic -- 0: A have priority over B, 1: B have priority over A |
); |
end wb_arbiter; |
|
-- This acthitecture is a clean asyncron state-machine. However it cannot be mapped to FPGA architecture |
architecture behaviour of wb_arbiter is |
type states is (idle,aa,ba); |
signal i_mux_signal: std_logic; |
|
signal e_state: states; |
begin |
mux_signal <= i_mux_signal; |
|
sm: process is |
variable state: states; |
begin |
wait on a_cyc_i, b_cyc_i, priority, rst_i; |
if (rst_i = '1') then |
state := idle; |
i_mux_signal <= priority; |
else |
case (state) is |
when idle => |
if (a_cyc_i = '1' and (priority = '0' or b_cyc_i = '0')) then |
state := aa; |
i_mux_signal <= '0'; |
elsif (b_cyc_i = '1' and (priority = '1' or a_cyc_i = '0')) then |
state := ba; |
i_mux_signal <= '1'; |
else |
i_mux_signal <= priority; |
end if; |
when aa => |
if (a_cyc_i = '0') then |
if (b_cyc_i = '1') then |
state := ba; |
i_mux_signal <= '1'; |
else |
state := idle; |
i_mux_signal <= priority; |
end if; |
else |
i_mux_signal <= '0'; |
end if; |
when ba => |
if (b_cyc_i = '0') then |
if (a_cyc_i = '1') then |
state := aa; |
i_mux_signal <= '0'; |
else |
state := idle; |
i_mux_signal <= priority; |
end if; |
else |
i_mux_signal <= '1'; |
end if; |
end case; |
end if; |
e_state <= state; |
end process; |
|
signal_mux: process is |
begin |
wait on a_we_i, a_stb_i, a_ack_oi, a_err_oi, a_rty_oi, a_cyc_i, |
b_we_i, b_stb_i, b_ack_oi, b_err_oi, b_rty_oi, b_cyc_i, |
s_ack_i, s_err_i, s_rty_i, i_mux_signal; |
if (i_mux_signal = '0') then |
s_we_o <= a_we_i; |
s_stb_o <= a_stb_i; |
s_cyc_o <= a_cyc_i; |
a_ack_o <= (a_stb_i and s_ack_i) or (not a_stb_i and a_ack_oi); |
a_err_o <= (a_stb_i and s_err_i) or (not a_stb_i and a_err_oi); |
a_rty_o <= (a_stb_i and s_rty_i) or (not a_stb_i and a_rty_oi); |
b_ack_o <= (b_stb_i and '0') or (not b_stb_i and b_ack_oi); |
b_err_o <= (b_stb_i and '0') or (not b_stb_i and b_err_oi); |
b_rty_o <= (b_stb_i and '0') or (not b_stb_i and b_rty_oi); |
else |
s_we_o <= b_we_i; |
s_stb_o <= b_stb_i; |
s_cyc_o <= b_cyc_i; |
b_ack_o <= (b_stb_i and s_ack_i) or (not b_stb_i and b_ack_oi); |
b_err_o <= (b_stb_i and s_err_i) or (not b_stb_i and b_err_oi); |
b_rty_o <= (b_stb_i and s_rty_i) or (not b_stb_i and b_rty_oi); |
a_ack_o <= (a_stb_i and '0') or (not a_stb_i and a_ack_oi); |
a_err_o <= (a_stb_i and '0') or (not a_stb_i and a_err_oi); |
a_rty_o <= (a_stb_i and '0') or (not a_stb_i and a_rty_oi); |
end if; |
end process; |
end behaviour; |
|
-- This acthitecture is a more-or-less structural implementation. Fits for FPGA realization. |
architecture FPGA of wb_arbiter is |
component d_ff |
port ( d : in STD_LOGIC; |
clk: in STD_LOGIC; |
ena: in STD_LOGIC := '1'; |
clr: in STD_LOGIC := '0'; |
pre: in STD_LOGIC := '0'; |
q : out STD_LOGIC |
); |
end component; |
|
signal i_mux_signal: std_logic; |
|
type states is (idle,aa,ba,XX); |
signal e_state: states; |
|
-- signals for a DFF in FPGA |
signal idle_s, aa_s, ba_s: std_logic; |
|
signal aa_clk, aa_ena, aa_clr, aa_pre: std_logic; |
signal ba_clk, ba_ena, ba_clr, ba_pre: std_logic; |
|
begin |
mux_signal <= i_mux_signal; |
|
idle_s <= not (a_cyc_i or b_cyc_i); |
|
aa_clr <= rst_i or not a_cyc_i; |
aa_clk <= a_cyc_i; |
aa_ena <= not b_cyc_i and priority; |
aa_pre <= (a_cyc_i and not priority and not ba_s) or (a_cyc_i and not b_cyc_i); |
aa_ff: d_ff port map ( |
d => '1', |
clk => aa_clk, |
ena => aa_ena, |
clr => aa_clr, |
pre => aa_pre, |
q => aa_s |
); |
|
ba_clr <= rst_i or not b_cyc_i; |
ba_clk <= b_cyc_i; |
ba_ena <= not a_cyc_i and not priority; |
ba_pre <= (b_cyc_i and priority and not aa_s) or (b_cyc_i and not a_cyc_i); |
ba_ff: d_ff port map ( |
d => '1', |
clk => ba_clk, |
ena => ba_ena, |
clr => ba_clr, |
pre => ba_pre, |
q => ba_s |
); |
|
i_mux_signal <= (priority and idle_s) or ba_s; |
|
signal_mux: process is |
begin |
wait on a_we_i, a_stb_i, a_ack_oi, a_err_oi, a_rty_oi, a_cyc_i, |
b_we_i, b_stb_i, b_ack_oi, b_err_oi, b_rty_oi, b_cyc_i, |
s_ack_i, s_err_i, s_rty_i, i_mux_signal; |
if (i_mux_signal = '0') then |
s_we_o <= a_we_i; |
s_stb_o <= a_stb_i; |
s_cyc_o <= a_cyc_i; |
a_ack_o <= (a_stb_i and s_ack_i) or (not a_stb_i and a_ack_oi); |
a_err_o <= (a_stb_i and s_err_i) or (not a_stb_i and a_err_oi); |
a_rty_o <= (a_stb_i and s_rty_i) or (not a_stb_i and a_rty_oi); |
b_ack_o <= (b_stb_i and '0') or (not b_stb_i and b_ack_oi); |
b_err_o <= (b_stb_i and '0') or (not b_stb_i and b_err_oi); |
b_rty_o <= (b_stb_i and '0') or (not b_stb_i and b_rty_oi); |
else |
s_we_o <= b_we_i; |
s_stb_o <= b_stb_i; |
s_cyc_o <= b_cyc_i; |
b_ack_o <= (b_stb_i and s_ack_i) or (not b_stb_i and b_ack_oi); |
b_err_o <= (b_stb_i and s_err_i) or (not b_stb_i and b_err_oi); |
b_rty_o <= (b_stb_i and s_rty_i) or (not b_stb_i and b_rty_oi); |
a_ack_o <= (a_stb_i and '0') or (not a_stb_i and a_ack_oi); |
a_err_o <= (a_stb_i and '0') or (not a_stb_i and a_err_oi); |
a_rty_o <= (a_stb_i and '0') or (not a_stb_i and a_rty_oi); |
end if; |
end process; |
|
gen_e_state: process is |
begin |
wait on idle_s,aa_s,ba_s; |
if (idle_s = '1' and ba_s = '0' and aa_s = '0') then e_state <= idle; |
elsif (idle_s = '0' and ba_s = '1' and aa_s = '0') then e_state <= aa; |
elsif (idle_s = '0' and ba_s = '0' and aa_s = '1') then e_state <= ba; |
else e_state <= XX; |
end if; |
end process; |
end FPGA; |
|
/trunk/wb_async_master.vhd
0,0 → 1,127
-- |
-- Wishbone bus toolkit. |
-- |
-- (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/03/31 |
-- This code is distributed under the terms and conditions of the GNU General Public Lince. |
-- |
-- |
-- ELEMENTS: |
-- wb_async_master: async bus master to Wishbone bus bridge. |
|
------------------------------------------------------------------------------- |
-- |
-- wb_async_master |
-- |
------------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
library wb_tk; |
use wb_tk.technology.all; |
|
entity wb_async_master is |
generic ( |
width: positive := 16; |
addr_width: positive := 20 |
); |
port ( |
clk_i: in std_logic; |
rst_i: in std_logic := '0'; |
|
-- interface to wb slave devices |
s_adr_o: out std_logic_vector (addr_width-1 downto 0); |
s_sel_o: out std_logic_vector ((width/8)-1 downto 0); |
s_dat_i: in std_logic_vector (width-1 downto 0); |
s_dat_o: out std_logic_vector (width-1 downto 0); |
s_cyc_o: out std_logic; |
s_ack_i: in std_logic; |
s_err_i: in std_logic := '-'; |
s_rty_i: in std_logic := '-'; |
s_we_o: out std_logic; |
s_stb_o: out std_logic; |
|
-- interface to asyncron master device |
a_data: inout std_logic_vector (width-1 downto 0) := (others => 'Z'); |
a_addr: in std_logic_vector (addr_width-1 downto 0) := (others => 'U'); |
a_rdn: in std_logic := '1'; |
a_wrn: in std_logic := '1'; |
a_cen: in std_logic := '1'; |
a_byen: in std_logic_vector ((width/8)-1 downto 0); |
a_waitn: out std_logic |
); |
end wb_async_master; |
|
architecture wb_async_master of wb_async_master is |
component d_ff |
port ( d : in STD_LOGIC; |
clk: in STD_LOGIC; |
ena: in STD_LOGIC := '1'; |
clr: in STD_LOGIC := '0'; |
pre: in STD_LOGIC := '0'; |
q : out STD_LOGIC |
); |
end component; |
signal wg_clk, wg_pre, wg_q: std_logic; |
signal i_cyc_o, i_stb_o, i_we_o: std_logic; |
signal i_waitn: std_logic; |
begin |
ctrl: process is |
begin |
wait until clk_i'EVENT and clk_i = '1'; |
if (rst_i = '1') then |
i_cyc_o <= '0'; |
i_stb_o <= '0'; |
i_we_o <= '0'; |
else |
if (a_cen = '0') then |
i_stb_o <= not (a_rdn and a_wrn); |
i_we_o <= not a_wrn; |
i_cyc_o <= '1'; |
else |
i_cyc_o <= '0'; |
i_stb_o <= '0'; |
i_we_o <= '0'; |
end if; |
end if; |
end process; |
s_cyc_o <= i_cyc_o and not i_waitn; |
s_stb_o <= i_stb_o and not i_waitn; |
s_we_o <= i_we_o and not i_waitn; |
|
w_ff1: d_ff port map ( |
d => s_ack_i, |
clk => clk_i, |
ena => '1', |
clr => rst_i, |
pre => '0', |
q => wg_q |
); |
|
wg_clk <= not a_cen; |
wg_pre <= wg_q or rst_i; |
w_ff2: d_ff port map ( |
d => '0', |
clk => wg_clk, |
ena => '1', |
clr => '0', |
pre => wg_pre, |
q => i_waitn |
); |
a_waitn <= i_waitn; |
|
s_adr_o <= a_addr; |
negate: for i in s_sel_o'RANGE generate s_sel_o(i) <= not a_byen(i); end generate; |
s_dat_o <= a_data; |
|
a_data_out: process is |
begin |
wait on s_dat_i, a_rdn, a_cen; |
if (a_rdn = '0' and a_cen = '0') then |
a_data <= s_dat_i; |
else |
a_data <= (others => 'Z'); |
end if; |
end process; |
end wb_async_master; |
|
/trunk/wb_bus_upsize.vhd
0,0 → 1,111
-- |
-- Wishbone bus toolkit. |
-- |
-- (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/03/31 |
-- This code is distributed under the terms and conditions of the GNU General Public Lince. |
-- |
-- |
-- ELEMENTS: |
-- wb_bus_upsize: bus upsizer. |
|
------------------------------------------------------------------------------- |
-- |
-- wb_bus_upsize |
-- |
------------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
library wb_tk; |
use wb_tk.technology.all; |
|
entity wb_bus_upsize is |
generic ( |
m_bus_width: positive := 8; -- master bus width |
m_addr_width: positive := 21; -- master bus width |
s_bus_width: positive := 16; -- slave bus width |
s_addr_width: positive := 20; -- master bus width |
little_endien: boolean := true -- if set to false, big endien |
); |
port ( |
-- clk_i: in std_logic; |
-- rst_i: in std_logic := '0'; |
|
-- Master bus interface |
m_adr_i: in std_logic_vector (m_addr_width-1 downto 0); |
m_sel_i: in std_logic_vector ((m_bus_width/8)-1 downto 0) := (others => '1'); |
m_dat_i: in std_logic_vector (m_bus_width-1 downto 0); |
m_dat_oi: in std_logic_vector (m_bus_width-1 downto 0) := (others => '-'); |
m_dat_o: out std_logic_vector (m_bus_width-1 downto 0); |
m_cyc_i: in std_logic; |
m_ack_o: out std_logic; |
m_ack_oi: in std_logic := '-'; |
m_err_o: out std_logic; |
m_err_oi: in std_logic := '-'; |
m_rty_o: out std_logic; |
m_rty_oi: in std_logic := '-'; |
m_we_i: in std_logic; |
m_stb_i: in std_logic; |
|
-- Slave bus interface |
s_adr_o: out std_logic_vector (s_addr_width-1 downto 0); |
s_sel_o: out std_logic_vector ((s_bus_width/8)-1 downto 0); |
s_dat_i: in std_logic_vector (s_bus_width-1 downto 0); |
s_dat_o: out std_logic_vector (s_bus_width-1 downto 0); |
s_cyc_o: out std_logic; |
s_ack_i: in std_logic; |
s_err_i: in std_logic := '-'; |
s_rty_i: in std_logic := '-'; |
s_we_o: out std_logic; |
s_stb_o: out std_logic |
); |
end wb_bus_upsize; |
|
architecture wb_bus_upsize of wb_bus_upsize is |
constant addr_diff: integer := log2(s_bus_width/m_bus_width); |
signal i_m_dat_o: std_logic_vector(m_bus_width-1 downto 0); |
begin |
assert (m_addr_width = s_addr_width+addr_diff) report "Address widths are not consistent" severity FAILURE; |
s_adr_o <= m_adr_i(m_addr_width-addr_diff downto addr_diff); |
s_we_o <= m_we_i; |
m_ack_o <= (m_stb_i and s_ack_i) or (not m_stb_i and m_ack_oi); |
m_err_o <= (m_stb_i and s_err_i) or (not m_stb_i and m_err_oi); |
m_rty_o <= (m_stb_i and s_rty_i) or (not m_stb_i and m_rty_oi); |
s_stb_o <= m_stb_i; |
s_cyc_o <= m_cyc_i; |
|
|
sel_dat_mux: process is |
begin |
wait on s_dat_i, m_adr_i; |
if (little_endien) then |
for i in s_sel_o'RANGE loop |
if (equ(m_adr_i(addr_diff-1 downto 0),i)) then |
s_sel_o(i) <= '1'; |
i_m_dat_o <= s_dat_i(8*i+7 downto 8*i+0); |
else |
s_sel_o(i) <= '0'; |
end if; |
end loop; |
else |
for i in s_sel_o'RANGE loop |
if (equ(m_adr_i(addr_diff-1 downto 0),i)) then |
s_sel_o(s_sel_o'HIGH-i) <= '1'; |
i_m_dat_o <= s_dat_i(s_dat_i'HIGH-8*i downto s_dat_i'HIGH-8*i-7); |
else |
s_sel_o(s_sel_o'HIGH-i) <= '0'; |
end if; |
end loop; |
end if; |
end process; |
|
d_i_for: for i in m_dat_o'RANGE generate |
m_dat_o(i) <= (m_stb_i and i_m_dat_o(i)) or (not m_stb_i and m_dat_oi(i)); |
end generate; |
|
d_o_for: for i in s_sel_o'RANGE generate |
s_dat_o(8*i+7 downto 8*i+0) <= m_dat_i; |
end generate; |
end wb_bus_upsize; |
|
/trunk/compile.sh
0,0 → 1,78
#!/bin/bash |
# |
# Script to compile sources to a library using Active HDL |
# (c) Copyright Andras Tantos <tantos@opencores.org> 2001/04/25 |
# This code is distributed under the terms and conditions of the GNU General Public Lince. |
# |
# USAGE: |
# |
# Set APATH to the installation directory of ActiveHDL and |
# LIB to whatever name your library has |
# RESULT_PATH to where generated files you wish to be put |
# Also make sure that you upadted the Library.cfg file to contain |
# the specified library name. |
# After the common part, list all files you wish to include in your library |
# with 'compile_file' preciding the file name. |
# |
# NOTES: |
# |
# This script depends on the following executables: |
# bash |
# cat |
# rm |
# mv |
# mkdir |
# echo |
# test |
# they are available under all UNIX-es and can be installed for windows |
# and DOS too. The windows version of these files can be obtained from |
# GNU Cygnus distribution (http://sources.redhat.com/cygwin) |
# The minimal package of these utilities are also available from |
# OpenCores web-site. |
|
APATH=C:/CAED/ActiveHDL.36/ |
LIB=wb_tk |
RESULT_PATH=ahdl |
|
# ___________Common part of the script____________ |
|
LIB_FILE=$RESULT_PATH/$LIB.lib |
CMP_FILE=$RESULT_PATH/0.mgf |
CMP=$APATH/bin/acombat.exe |
CMP_FLAGS="-avhdl $APATH -lib $LIB -93" |
|
compile_file() { |
LOG_FILE=$1 |
LOG_FILE=$RESULT_PATH/${LOG_FILE/.vhd/.rlt} |
ERR_FILE=${LOG_FILE/.rtl/.err} |
rm -f $LOG_FILE |
rm -f $ERR_FILE |
$CMP $CMP_FLAGS -log $LOG_FILE $1 || { |
mv $LOG_FILE $ERR_FILE |
cat $ERR_FILE |
exit 1 |
} |
cat $LOG_FILE |
} |
|
if test ! -d $RESULT_PATH; then |
mkdir $RESULT_PATH |
fi |
rm -f $RESULT_PATH/* |
if test ! -f $LIB_FILE; then |
echo > $LIB_FILE |
fi |
# ___________End of common part of the script____________ |
|
compile_file technology.vhd |
compile_file wb_arbiter.vhd |
compile_file wb_async_master.vhd |
compile_file wb_async_slave.vhd |
compile_file wb_bus_dnsize.vhd |
compile_file wb_bus_upsize.vhd |
compile_file wb_bus_resize.vhd |
compile_file wb_out_reg.vhd |
compile_file wb_ram.vhd |
compile_file wb_test.vhd |
compile_file wb_tk.vhd |
|
/trunk/wb_bus_resize.vhd
0,0 → 1,249
-- |
-- Wishbone bus toolkit. |
-- |
-- (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/03/31 |
-- This code is distributed under the terms and conditions of the GNU General Public Lince. |
-- |
-- |
-- ELEMENTS: |
-- wb_bus_resize: bus resizer. |
|
------------------------------------------------------------------------------- |
-- |
-- wb_bus_resize |
-- |
------------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
library wb_tk; |
use wb_tk.technology.all; |
use wb_tk.all; |
|
entity wb_bus_resize is |
generic ( |
m_bus_width: positive := 32; -- master bus width |
m_addr_width: positive := 19; -- master bus width |
s_bus_width: positive := 16; -- slave bus width |
s_addr_width: positive := 20; -- master bus width |
little_endien: boolean := true -- if set to false, big endien |
); |
port ( |
-- clk_i: in std_logic; |
-- rst_i: in std_logic := '0'; |
|
-- Master bus interface |
m_adr_i: in std_logic_vector (m_addr_width-1 downto 0); |
m_sel_i: in std_logic_vector ((m_bus_width/8)-1 downto 0) := (others => '1'); |
m_dat_i: in std_logic_vector (m_bus_width-1 downto 0); |
m_dat_oi: in std_logic_vector (m_bus_width-1 downto 0) := (others => '-'); |
m_dat_o: out std_logic_vector (m_bus_width-1 downto 0); |
m_cyc_i: in std_logic; |
m_ack_o: out std_logic; |
m_ack_oi: in std_logic := '-'; |
m_err_o: out std_logic; |
m_err_oi: in std_logic := '-'; |
m_rty_o: out std_logic; |
m_rty_oi: in std_logic := '-'; |
m_we_i: in std_logic; |
m_stb_i: in std_logic; |
|
-- Slave bus interface |
s_adr_o: out std_logic_vector (s_addr_width-1 downto 0); |
s_sel_o: out std_logic_vector ((s_bus_width/8)-1 downto 0); |
s_dat_i: in std_logic_vector (s_bus_width-1 downto 0); |
s_dat_o: out std_logic_vector (s_bus_width-1 downto 0); |
s_cyc_o: out std_logic; |
s_ack_i: in std_logic; |
s_err_i: in std_logic := '-'; |
s_rty_i: in std_logic := '-'; |
s_we_o: out std_logic; |
s_stb_o: out std_logic |
); |
end wb_bus_resize; |
|
architecture wb_bus_resize of wb_bus_resize is |
component wb_bus_upsize is |
generic ( |
m_bus_width: positive := 8; -- master bus width |
m_addr_width: positive := 21; -- master bus width |
s_bus_width: positive := 16; -- slave bus width |
s_addr_width: positive := 20; -- master bus width |
little_endien: boolean := true -- if set to false, big endien |
); |
port ( |
-- clk_i: in std_logic; |
-- rst_i: in std_logic := '0'; |
|
-- Master bus interface |
m_adr_i: in std_logic_vector (m_addr_width-1 downto 0); |
m_sel_i: in std_logic_vector ((m_bus_width/8)-1 downto 0) := (others => '1'); |
m_dat_i: in std_logic_vector (m_bus_width-1 downto 0); |
m_dat_oi: in std_logic_vector (m_bus_width-1 downto 0) := (others => '-'); |
m_dat_o: out std_logic_vector (m_bus_width-1 downto 0); |
m_cyc_i: in std_logic; |
m_ack_o: out std_logic; |
m_ack_oi: in std_logic := '-'; |
m_err_o: out std_logic; |
m_err_oi: in std_logic := '-'; |
m_rty_o: out std_logic; |
m_rty_oi: in std_logic := '-'; |
m_we_i: in std_logic; |
m_stb_i: in std_logic; |
|
-- Slave bus interface |
s_adr_o: out std_logic_vector (s_addr_width-1 downto 0); |
s_sel_o: out std_logic_vector ((s_bus_width/8)-1 downto 0); |
s_dat_i: in std_logic_vector (s_bus_width-1 downto 0); |
s_dat_o: out std_logic_vector (s_bus_width-1 downto 0); |
s_cyc_o: out std_logic; |
s_ack_i: in std_logic; |
s_err_i: in std_logic := '-'; |
s_rty_i: in std_logic := '-'; |
s_we_o: out std_logic; |
s_stb_o: out std_logic |
); |
end component; |
|
component wb_bus_dnsize is |
generic ( |
m_bus_width: positive := 32; -- master bus width |
m_addr_width: positive := 20; -- master bus width |
s_bus_width: positive := 16; -- slave bus width |
s_addr_width: positive := 21; -- master bus width |
little_endien: boolean := true -- if set to false, big endien |
); |
port ( |
-- clk_i: in std_logic; |
-- rst_i: in std_logic := '0'; |
|
-- Master bus interface |
m_adr_i: in std_logic_vector (m_addr_width-1 downto 0); |
m_sel_i: in std_logic_vector ((m_bus_width/8)-1 downto 0) := (others => '1'); |
m_dat_i: in std_logic_vector (m_bus_width-1 downto 0); |
m_dat_oi: in std_logic_vector (m_bus_width-1 downto 0) := (others => '-'); |
m_dat_o: out std_logic_vector (m_bus_width-1 downto 0); |
m_cyc_i: in std_logic; |
m_ack_o: out std_logic; |
m_ack_oi: in std_logic := '-'; |
m_err_o: out std_logic; |
m_err_oi: in std_logic := '-'; |
m_rty_o: out std_logic; |
m_rty_oi: in std_logic := '-'; |
m_we_i: in std_logic; |
m_stb_i: in std_logic; |
|
-- Slave bus interface |
s_adr_o: out std_logic_vector (s_addr_width-1 downto 0); |
s_sel_o: out std_logic_vector ((s_bus_width/8)-1 downto 0); |
s_dat_i: in std_logic_vector (s_bus_width-1 downto 0); |
s_dat_o: out std_logic_vector (s_bus_width-1 downto 0); |
s_cyc_o: out std_logic; |
s_ack_i: in std_logic; |
s_err_i: in std_logic := '-'; |
s_rty_i: in std_logic := '-'; |
s_we_o: out std_logic; |
s_stb_o: out std_logic |
); |
end component; |
begin |
dn_sel: if (m_bus_width > s_bus_width) generate |
dnsizer: wb_bus_dnsize |
generic map ( |
m_bus_width => m_bus_width, |
m_addr_width => m_addr_width, |
s_bus_width => s_bus_width, |
s_addr_width => s_addr_width, |
little_endien => little_endien |
) |
port map |
(m_adr_i => m_adr_i, |
m_sel_i => m_sel_i, |
m_dat_i => m_dat_i, |
m_dat_oi => m_dat_oi, |
m_dat_o => m_dat_o, |
m_cyc_i => m_cyc_i, |
m_ack_o => m_ack_o, |
m_ack_oi => m_ack_oi, |
m_err_o => m_err_o, |
m_err_oi => m_err_oi, |
m_rty_o => m_rty_o, |
m_rty_oi => m_rty_oi, |
m_we_i => m_we_i, |
m_stb_i => m_stb_i, |
s_adr_o => s_adr_o, |
s_sel_o => s_sel_o, |
s_dat_i => s_dat_i, |
s_dat_o => s_dat_o, |
s_cyc_o => s_cyc_o, |
s_ack_i => s_ack_i, |
s_err_i => s_err_i, |
s_rty_i => s_rty_i, |
s_we_o => s_we_o, |
s_stb_o => s_stb_o |
); |
end generate; |
up_sel: if (m_bus_width < s_bus_width) generate |
upsizer: wb_bus_upsize |
generic map ( |
m_bus_width => m_bus_width, |
m_addr_width => m_addr_width, |
s_bus_width => s_bus_width, |
s_addr_width => s_addr_width, |
little_endien => little_endien |
) |
port map |
(m_adr_i => m_adr_i, |
m_sel_i => m_sel_i, |
m_dat_i => m_dat_i, |
m_dat_oi => m_dat_oi, |
m_dat_o => m_dat_o, |
m_cyc_i => m_cyc_i, |
m_ack_o => m_ack_o, |
m_ack_oi => m_ack_oi, |
m_err_o => m_err_o, |
m_err_oi => m_err_oi, |
m_rty_o => m_rty_o, |
m_rty_oi => m_rty_oi, |
m_we_i => m_we_i, |
m_stb_i => m_stb_i, |
s_adr_o => s_adr_o, |
s_sel_o => s_sel_o, |
s_dat_i => s_dat_i, |
s_dat_o => s_dat_o, |
s_cyc_o => s_cyc_o, |
s_ack_i => s_ack_i, |
s_err_i => s_err_i, |
s_rty_i => s_rty_i, |
s_we_o => s_we_o, |
s_stb_o => s_stb_o |
); |
end generate; |
eq_sel: if (m_bus_width = s_bus_width) generate |
dat_o_for: for i in m_dat_o'RANGE generate |
dat_o_gen: m_dat_o(i) <= (s_dat_i(i) and m_stb_i and not m_we_i) or (m_dat_oi(i) and not (m_stb_i and not m_we_i)); |
end generate; |
m_ack_o <= (s_ack_i and m_stb_i and not m_we_i) or (m_ack_oi and not (m_stb_i and not m_we_i)); |
m_err_o <= (s_err_i and m_stb_i and not m_we_i) or (m_err_oi and not (m_stb_i and not m_we_i)); |
m_rty_o <= (s_rty_i and m_stb_i and not m_we_i) or (m_rty_oi and not (m_stb_i and not m_we_i)); |
s_adr_o <= m_adr_i; |
s_sel_o <= m_sel_i; |
s_dat_o <= m_dat_i; |
s_cyc_o <= m_cyc_i; |
s_we_o <= m_we_i; |
s_stb_o <= m_stb_i; |
end generate; |
end wb_bus_resize; |
|
--configuration c_wb_bus_resize of wb_bus_resize is |
-- for wb_bus_resize |
-- for dnsizer: wb_bus_dnsize |
-- use entity wb_bus_dnsize(wb_bus_dnsize); |
-- end for; |
-- for upsizer: wb_bus_upsize |
-- use entity wb_bus_upsize(wb_bus_upsize); |
-- end for; |
-- end for; |
--end c_wb_bus_resize; |
|
/trunk/wb_tk.vhd
10,9 → 10,12
-- wb_async_slave: Wishbone bus to async (SRAM-like) bus slave bridge. |
-- wb_arbiter: two-way bus arbiter. Asyncronous logic ensures 0-ws operation on shared bus |
-- wb_out_reg: Wishbone bus compatible output register. |
-- wb_bus_resize: Wishbone bus resizer. |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
library wb_tk; |
use wb_tk.technology.all; |
|
package wb_tk is |
component wb_bus_upsize is |
56,7 → 59,91
s_stb_o: out std_logic |
); |
end component; |
|
component wb_bus_dnsize is |
generic ( |
m_bus_width: positive := 32; -- master bus width |
m_addr_width: positive := 20; -- master bus width |
s_bus_width: positive := 16; -- slave bus width |
s_addr_width: positive := 21; -- master bus width |
little_endien: boolean := true -- if set to false, big endien |
); |
port ( |
-- clk_i: in std_logic; |
-- rst_i: in std_logic := '0'; |
|
-- Master bus interface |
m_adr_i: in std_logic_vector (m_addr_width-1 downto 0); |
m_sel_i: in std_logic_vector ((m_bus_width/8)-1 downto 0) := (others => '1'); |
m_dat_i: in std_logic_vector (m_bus_width-1 downto 0); |
m_dat_oi: in std_logic_vector (m_bus_width-1 downto 0) := (others => '-'); |
m_dat_o: out std_logic_vector (m_bus_width-1 downto 0); |
m_cyc_i: in std_logic; |
m_ack_o: out std_logic; |
m_ack_oi: in std_logic := '-'; |
m_err_o: out std_logic; |
m_err_oi: in std_logic := '-'; |
m_rty_o: out std_logic; |
m_rty_oi: in std_logic := '-'; |
m_we_i: in std_logic; |
m_stb_i: in std_logic; |
|
-- Slave bus interface |
s_adr_o: out std_logic_vector (s_addr_width-1 downto 0); |
s_sel_o: out std_logic_vector ((s_bus_width/8)-1 downto 0); |
s_dat_i: in std_logic_vector (s_bus_width-1 downto 0); |
s_dat_o: out std_logic_vector (s_bus_width-1 downto 0); |
s_cyc_o: out std_logic; |
s_ack_i: in std_logic; |
s_err_i: in std_logic := '-'; |
s_rty_i: in std_logic := '-'; |
s_we_o: out std_logic; |
s_stb_o: out std_logic |
); |
end component; |
|
component wb_bus_resize is |
generic ( |
m_bus_width: positive := 32; -- master bus width |
m_addr_width: positive := 20; -- master bus width |
s_bus_width: positive := 16; -- slave bus width |
s_addr_width: positive := 21; -- master bus width |
little_endien: boolean := true -- if set to false, big endien |
); |
port ( |
-- clk_i: in std_logic; |
-- rst_i: in std_logic := '0'; |
|
-- Master bus interface |
m_adr_i: in std_logic_vector (m_addr_width-1 downto 0); |
m_sel_i: in std_logic_vector ((m_bus_width/8)-1 downto 0) := (others => '1'); |
m_dat_i: in std_logic_vector (m_bus_width-1 downto 0); |
m_dat_oi: in std_logic_vector (m_bus_width-1 downto 0) := (others => '-'); |
m_dat_o: out std_logic_vector (m_bus_width-1 downto 0); |
m_cyc_i: in std_logic; |
m_ack_o: out std_logic; |
m_ack_oi: in std_logic := '-'; |
m_err_o: out std_logic; |
m_err_oi: in std_logic := '-'; |
m_rty_o: out std_logic; |
m_rty_oi: in std_logic := '-'; |
m_we_i: in std_logic; |
m_stb_i: in std_logic; |
|
-- Slave bus interface |
s_adr_o: out std_logic_vector (s_addr_width-1 downto 0); |
s_sel_o: out std_logic_vector ((s_bus_width/8)-1 downto 0); |
s_dat_i: in std_logic_vector (s_bus_width-1 downto 0); |
s_dat_o: out std_logic_vector (s_bus_width-1 downto 0); |
s_cyc_o: out std_logic; |
s_ack_i: in std_logic; |
s_err_i: in std_logic := '-'; |
s_rty_i: in std_logic := '-'; |
s_we_o: out std_logic; |
s_stb_o: out std_logic |
); |
end component; |
|
component wb_async_master is |
generic ( |
width: positive := 16; |
166,749 → 253,28
end component; |
|
component wb_out_reg is |
generic ( |
width : positive := 8; |
bus_width: positive := 8; |
offset: integer := 0 |
); |
port ( |
clk_i: in std_logic; |
rst_i: in std_logic; |
rst_val: std_logic_vector(width-1 downto 0) := (others => '0'); |
|
dat_i: in std_logic_vector (bus_width-1 downto 0); |
dat_oi: in std_logic_vector (bus_width-1 downto 0) := (others => '-'); |
dat_o: out std_logic_vector (bus_width-1 downto 0); |
q: out std_logic_vector (width-1 downto 0); |
we_i: in std_logic; |
stb_i: in std_logic; |
ack_o: out std_logic; |
ack_oi: in std_logic := '-' |
); |
generic ( |
width : positive := 8; |
bus_width: positive := 8; |
offset: integer := 0 |
); |
port ( |
clk_i: in std_logic; |
rst_i: in std_logic; |
rst_val: std_logic_vector(width-1 downto 0) := (others => '0'); |
|
cyc_i: in std_logic := '1'; |
stb_i: in std_logic; |
sel_i: in std_logic_vector ((bus_width/8)-1 downto 0) := (others => '1'); |
we_i: in std_logic; |
ack_o: out std_logic; |
ack_oi: in std_logic := '-'; |
adr_i: in std_logic_vector (size2bits((width+offset+bus_width-1)/bus_width)-1 downto 0) := (others => '0'); |
dat_i: in std_logic_vector (bus_width-1 downto 0); |
dat_oi: in std_logic_vector (bus_width-1 downto 0) := (others => '-'); |
dat_o: out std_logic_vector (bus_width-1 downto 0); |
q: out std_logic_vector (width-1 downto 0) |
); |
end component; |
end wb_tk; |
|
------------------------------------------------------------------------------- |
-- |
-- wb_bus_upsize |
-- |
------------------------------------------------------------------------------- |
|
library IEEE; |
library synopsys; |
use IEEE.std_logic_1164.all; |
use synopsys.std_logic_arith.all; |
|
library work; |
use work.technology.all; |
|
entity wb_bus_upsize is |
generic ( |
m_bus_width: positive := 8; -- master bus width |
m_addr_width: positive := 21; -- master bus width |
s_bus_width: positive := 16; -- slave bus width |
s_addr_width: positive := 20; -- master bus width |
little_endien: boolean := true -- if set to false, big endien |
); |
port ( |
-- clk_i: in std_logic; |
-- rst_i: in std_logic := '0'; |
|
-- Master bus interface |
m_adr_i: in std_logic_vector (m_addr_width-1 downto 0); |
m_sel_i: in std_logic_vector ((m_bus_width/8)-1 downto 0) := (others => '1'); |
m_dat_i: in std_logic_vector (m_bus_width-1 downto 0); |
m_dat_oi: in std_logic_vector (m_bus_width-1 downto 0) := (others => '-'); |
m_dat_o: out std_logic_vector (m_bus_width-1 downto 0); |
m_cyc_i: in std_logic; |
m_ack_o: out std_logic; |
m_ack_oi: in std_logic := '-'; |
m_err_o: out std_logic; |
m_err_oi: in std_logic := '-'; |
m_rty_o: out std_logic; |
m_rty_oi: in std_logic := '-'; |
m_we_i: in std_logic; |
m_stb_i: in std_logic; |
|
-- Slave bus interface |
s_adr_o: out std_logic_vector (s_addr_width-1 downto 0); |
s_sel_o: out std_logic_vector ((s_bus_width/8)-1 downto 0); |
s_dat_i: in std_logic_vector (s_bus_width-1 downto 0); |
s_dat_o: out std_logic_vector (s_bus_width-1 downto 0); |
s_cyc_o: out std_logic; |
s_ack_i: in std_logic; |
s_err_i: in std_logic := '-'; |
s_rty_i: in std_logic := '-'; |
s_we_o: out std_logic; |
s_stb_o: out std_logic |
); |
end wb_bus_upsize; |
|
architecture wb_bus_upsize of wb_bus_upsize is |
function log2(inp : integer) return integer is |
begin |
if (inp < 1) then return 0; end if; |
if (inp < 2) then return 0; end if; |
if (inp < 4) then return 1; end if; |
if (inp < 8) then return 2; end if; |
if (inp < 16) then return 3; end if; |
if (inp < 32) then return 4; end if; |
if (inp < 64) then return 5; end if; |
if (inp < 128) then return 6; end if; |
if (inp < 256) then return 7; end if; |
if (inp < 512) then return 8; end if; |
if (inp < 1024) then return 9; end if; |
if (inp < 2048) then return 10; end if; |
if (inp < 4096) then return 11; end if; |
if (inp < 8192) then return 12; end if; |
if (inp < 16384) then return 13; end if; |
if (inp < 32768) then return 14; end if; |
if (inp < 65538) then return 15; end if; |
return 16; |
end; |
function equ(a : std_logic_vector; b : integer) return boolean is |
variable b_s : std_logic_vector(a'RANGE); |
begin |
b_s := CONV_STD_LOGIC_VECTOR(b,a'HIGH+1); |
return (a = b_s); |
end; |
constant addr_diff: integer := log2(s_bus_width/m_bus_width); |
signal i_m_dat_o: std_logic_vector(m_bus_width-1 downto 0); |
begin |
assert (m_addr_width = s_addr_width+addr_diff) report "Address widths are not consistent" severity FAILURE; |
s_adr_o <= m_adr_i(m_addr_width-addr_diff downto addr_diff); |
s_we_o <= m_we_i; |
m_ack_o <= (m_stb_i and s_ack_i) or (not m_stb_i and m_ack_oi); |
m_err_o <= (m_stb_i and s_err_i) or (not m_stb_i and m_err_oi); |
m_rty_o <= (m_stb_i and s_rty_i) or (not m_stb_i and m_rty_oi); |
s_stb_o <= m_stb_i; |
s_cyc_o <= m_cyc_i; |
|
|
sel_dat_mux: process is |
begin |
wait on s_dat_i, m_adr_i; |
if (little_endien) then |
for i in s_sel_o'RANGE loop |
if (equ(m_adr_i(addr_diff-1 downto 0),i)) then |
s_sel_o(i) <= '1'; |
i_m_dat_o <= s_dat_i(8*i+7 downto 8*i+0); |
else |
s_sel_o(i) <= '0'; |
end if; |
end loop; |
else |
for i in s_sel_o'RANGE loop |
if (equ(m_adr_i(addr_diff-1 downto 0),i)) then |
s_sel_o(s_sel_o'HIGH-i) <= '1'; |
i_m_dat_o <= s_dat_i(s_dat_i'HIGH-8*i downto s_dat_i'HIGH-8*i-7); |
else |
s_sel_o(s_sel_o'HIGH-i) <= '0'; |
end if; |
end loop; |
end if; |
end process; |
|
d_i_for: for i in m_dat_o'RANGE generate |
m_dat_o(i) <= (m_stb_i and i_m_dat_o(i)) or (not m_stb_i and m_dat_oi(i)); |
end generate; |
|
d_o_for: for i in s_sel_o'RANGE generate |
s_dat_o(8*i+7 downto 8*i+0) <= m_dat_i; |
end generate; |
end wb_bus_upsize; |
|
------------------------------------------------------------------------------- |
-- |
-- wb_async_master |
-- |
------------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
library work; |
use work.technology.all; |
|
entity wb_async_master is |
generic ( |
width: positive := 16; |
addr_width: positive := 20 |
); |
port ( |
clk_i: in std_logic; |
rst_i: in std_logic := '0'; |
|
-- interface to wb slave devices |
s_adr_o: out std_logic_vector (addr_width-1 downto 0); |
s_sel_o: out std_logic_vector ((width/8)-1 downto 0); |
s_dat_i: in std_logic_vector (width-1 downto 0); |
s_dat_o: out std_logic_vector (width-1 downto 0); |
s_cyc_o: out std_logic; |
s_ack_i: in std_logic; |
s_err_i: in std_logic := '-'; |
s_rty_i: in std_logic := '-'; |
s_we_o: out std_logic; |
s_stb_o: out std_logic; |
|
-- interface to asyncron master device |
a_data: inout std_logic_vector (width-1 downto 0) := (others => 'Z'); |
a_addr: in std_logic_vector (addr_width-1 downto 0) := (others => 'U'); |
a_rdn: in std_logic := '1'; |
a_wrn: in std_logic := '1'; |
a_cen: in std_logic := '1'; |
a_byen: in std_logic_vector ((width/8)-1 downto 0); |
a_waitn: out std_logic |
); |
end wb_async_master; |
|
architecture wb_async_master of wb_async_master is |
component d_ff |
port ( d : in STD_LOGIC; |
clk: in STD_LOGIC; |
ena: in STD_LOGIC := '1'; |
clr: in STD_LOGIC := '0'; |
pre: in STD_LOGIC := '0'; |
q : out STD_LOGIC |
); |
end component; |
signal wg_clk, wg_pre, wg_q: std_logic; |
signal i_cyc_o, i_stb_o, i_we_o: std_logic; |
signal i_waitn: std_logic; |
begin |
ctrl: process is |
begin |
wait until clk_i'EVENT and clk_i = '1'; |
if (rst_i = '1') then |
i_cyc_o <= '0'; |
i_stb_o <= '0'; |
i_we_o <= '0'; |
else |
if (a_cen = '0') then |
i_stb_o <= not (a_rdn and a_wrn); |
i_we_o <= not a_wrn; |
i_cyc_o <= '1'; |
else |
i_cyc_o <= '0'; |
i_stb_o <= '0'; |
i_we_o <= '0'; |
end if; |
end if; |
end process; |
s_cyc_o <= i_cyc_o and not i_waitn; |
s_stb_o <= i_stb_o and not i_waitn; |
s_we_o <= i_we_o and not i_waitn; |
|
w_ff1: d_ff port map ( |
d => s_ack_i, |
clk => clk_i, |
ena => '1', |
clr => rst_i, |
pre => '0', |
q => wg_q |
); |
|
wg_clk <= not a_cen; |
wg_pre <= wg_q or rst_i; |
w_ff2: d_ff port map ( |
d => '0', |
clk => wg_clk, |
ena => '1', |
clr => '0', |
pre => wg_pre, |
q => i_waitn |
); |
a_waitn <= i_waitn; |
|
s_adr_o <= a_addr; |
negate: for i in s_sel_o'RANGE generate s_sel_o(i) <= not a_byen(i); end generate; |
s_dat_o <= a_data; |
|
a_data_out: process is |
begin |
wait on s_dat_i, a_rdn, a_cen; |
if (a_rdn = '0' and a_cen = '0') then |
a_data <= s_dat_i; |
else |
a_data <= (others => 'Z'); |
end if; |
end process; |
end wb_async_master; |
|
------------------------------------------------------------------------------- |
-- |
-- wb_async_slave |
-- |
------------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
library work; |
use work.technology.all; |
|
entity wb_async_slave is |
generic ( |
width: positive := 16; |
addr_width: positive := 20 |
); |
port ( |
clk_i: in std_logic; |
rst_i: in std_logic := '0'; |
|
-- interface for wait-state generator state-machine |
wait_state: in std_logic_vector (3 downto 0); |
|
-- interface to wishbone master device |
adr_i: in std_logic_vector (addr_width-1 downto 0); |
sel_i: in std_logic_vector ((addr_width/8)-1 downto 0); |
dat_i: in std_logic_vector (width-1 downto 0); |
dat_o: out std_logic_vector (width-1 downto 0); |
dat_oi: in std_logic_vector (width-1 downto 0) := (others => '-'); |
we_i: in std_logic; |
stb_i: in std_logic; |
ack_o: out std_logic := '0'; |
ack_oi: in std_logic := '-'; |
|
-- interface to async slave |
a_data: inout std_logic_vector (width-1 downto 0) := (others => 'Z'); |
a_addr: out std_logic_vector (addr_width-1 downto 0) := (others => 'U'); |
a_rdn: out std_logic := '1'; |
a_wrn: out std_logic := '1'; |
a_cen: out std_logic := '1'; |
-- byte-enable signals |
a_byen: out std_logic_vector ((width/8)-1 downto 0) |
); |
end wb_async_slave; |
|
architecture wb_async_slave of wb_async_slave is |
-- multiplexed access signals to memory |
signal i_ack: std_logic; |
signal sm_ack: std_logic; |
|
type states is (sm_idle, sm_wait, sm_deact); |
signal state: states; |
signal cnt: std_logic_vector(3 downto 0); |
begin |
ack_o <= (stb_i and i_ack) or (not stb_i and ack_oi); |
dat_o_gen: for i in dat_o'RANGE generate |
dat_o(i) <= (stb_i and a_data(i)) or (not stb_i and dat_oi(i)); |
end generate; |
|
-- For 0WS operation i_ack is an async signal otherwise it's a sync one. |
i_ack_gen: process is |
begin |
wait on sm_ack, stb_i, wait_state, state; |
if (wait_state = "0000") then |
case (state) is |
when sm_deact => i_ack <= '0'; |
when others => i_ack <= stb_i; |
end case; |
else |
i_ack <= sm_ack; |
end if; |
end process; |
|
-- SRAM signal-handler process |
sram_signals: process is |
begin |
wait on state,we_i,a_data,adr_i,rst_i, stb_i, sel_i, dat_i; |
if (rst_i = '1') then |
a_wrn <= '1'; |
a_rdn <= '1'; |
a_cen <= '1'; |
a_addr <= (others => '-'); |
a_data <= (others => 'Z'); |
a_byen <= (others => '1'); |
else |
case (state) is |
when sm_deact => |
a_wrn <= '1'; |
a_rdn <= '1'; |
a_cen <= '1'; |
a_addr <= (others => '-'); |
a_data <= (others => 'Z'); |
a_byen <= (others => '1'); |
when others => |
a_addr <= adr_i; |
a_rdn <= not (not we_i and stb_i); |
a_wrn <= not (we_i and stb_i); |
a_cen <= not stb_i; |
a_byen <= not sel_i; |
if (we_i = '1') then |
a_data <= dat_i; |
else |
a_data <= (others => 'Z'); |
end if; |
end case; |
end if; |
end process; |
|
-- Aysnc access state-machine. |
async_sm: process is |
-- variable cnt: std_logic_vector(3 downto 0) := "0000"; |
-- variable state: states := init; |
begin |
wait until clk_i'EVENT and clk_i = '1'; |
if (rst_i = '1') then |
state <= sm_idle; |
cnt <= ((0) => '1', others => '0'); |
sm_ack <= '0'; |
else |
case (state) is |
when sm_idle => |
-- Check if anyone needs access to the memory. |
-- it's rdy signal will already be pulled low, so we only have to start the access |
if (stb_i = '1') then |
case wait_state is |
when "0000" => |
sm_ack <= '1'; |
state <= sm_deact; |
when "0001" => |
sm_ack <= '1'; |
cnt <= "0001"; |
state <= sm_wait; |
when others => |
sm_ack <= '0'; |
cnt <= "0001"; |
state <= sm_wait; |
end case; |
end if; |
when sm_wait => |
if (cnt = wait_state) then |
-- wait cycle completed. |
state <= sm_deact; |
sm_ack <= '0'; |
cnt <= "0000"; |
else |
if (add_one(cnt) = wait_state) then |
sm_ack <= '1'; |
else |
sm_ack <= '0'; |
end if; |
cnt <= add_one(cnt); |
end if; |
when sm_deact => |
if (stb_i = '1') then |
case wait_state is |
when "0000" => |
cnt <= "0000"; |
sm_ack <= '0'; |
state <= sm_wait; |
when others => |
sm_ack <= '0'; |
cnt <= "0000"; |
state <= sm_wait; |
end case; |
else |
sm_ack <= '0'; |
state <= sm_idle; |
end if; |
end case; |
end if; |
end process; |
end wb_async_slave; |
|
------------------------------------------------------------------------------- |
-- |
-- wb_arbiter |
-- |
------------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
library work; |
use work.technology.all; |
|
entity wb_arbiter is |
port ( |
-- clk: in std_logic; |
rst_i: in std_logic := '0'; |
|
-- interface to master device a |
a_we_i: in std_logic; |
a_stb_i: in std_logic; |
a_cyc_i: in std_logic; |
a_ack_o: out std_logic; |
a_ack_oi: in std_logic := '-'; |
a_err_o: out std_logic; |
a_err_oi: in std_logic := '-'; |
a_rty_o: out std_logic; |
a_rty_oi: in std_logic := '-'; |
|
-- interface to master device b |
b_we_i: in std_logic; |
b_stb_i: in std_logic; |
b_cyc_i: in std_logic; |
b_ack_o: out std_logic; |
b_ack_oi: in std_logic := '-'; |
b_err_o: out std_logic; |
b_err_oi: in std_logic := '-'; |
b_rty_o: out std_logic; |
b_rty_oi: in std_logic := '-'; |
|
-- interface to shared devices |
s_we_o: out std_logic; |
s_stb_o: out std_logic; |
s_cyc_o: out std_logic; |
s_ack_i: in std_logic; |
s_err_i: in std_logic := '-'; |
s_rty_i: in std_logic := '-'; |
|
mux_signal: out std_logic; -- 0: select A signals, 1: select B signals |
|
-- misc control lines |
priority: in std_logic -- 0: A have priority over B, 1: B have priority over A |
); |
end wb_arbiter; |
|
-- This acthitecture is a clean asyncron state-machine. However it cannot be mapped to FPGA architecture |
architecture behaviour of wb_arbiter is |
type states is (idle,aa,ba); |
signal i_mux_signal: std_logic; |
|
signal e_state: states; |
begin |
mux_signal <= i_mux_signal; |
|
sm: process is |
variable state: states; |
begin |
wait on a_cyc_i, b_cyc_i, priority, rst_i; |
if (rst_i = '1') then |
state := idle; |
i_mux_signal <= priority; |
else |
case (state) is |
when idle => |
if (a_cyc_i = '1' and (priority = '0' or b_cyc_i = '0')) then |
state := aa; |
i_mux_signal <= '0'; |
elsif (b_cyc_i = '1' and (priority = '1' or a_cyc_i = '0')) then |
state := ba; |
i_mux_signal <= '1'; |
else |
i_mux_signal <= priority; |
end if; |
when aa => |
if (a_cyc_i = '0') then |
if (b_cyc_i = '1') then |
state := ba; |
i_mux_signal <= '1'; |
else |
state := idle; |
i_mux_signal <= priority; |
end if; |
else |
i_mux_signal <= '0'; |
end if; |
when ba => |
if (b_cyc_i = '0') then |
if (a_cyc_i = '1') then |
state := aa; |
i_mux_signal <= '0'; |
else |
state := idle; |
i_mux_signal <= priority; |
end if; |
else |
i_mux_signal <= '1'; |
end if; |
end case; |
end if; |
e_state <= state; |
end process; |
|
signal_mux: process is |
begin |
wait on a_we_i, a_stb_i, a_ack_oi, a_err_oi, a_rty_oi, a_cyc_i, |
b_we_i, b_stb_i, b_ack_oi, b_err_oi, b_rty_oi, b_cyc_i, |
s_ack_i, s_err_i, s_rty_i, i_mux_signal; |
if (i_mux_signal = '0') then |
s_we_o <= a_we_i; |
s_stb_o <= a_stb_i; |
s_cyc_o <= a_cyc_i; |
a_ack_o <= (a_stb_i and s_ack_i) or (not a_stb_i and a_ack_oi); |
a_err_o <= (a_stb_i and s_err_i) or (not a_stb_i and a_err_oi); |
a_rty_o <= (a_stb_i and s_rty_i) or (not a_stb_i and a_rty_oi); |
b_ack_o <= (b_stb_i and '0') or (not b_stb_i and b_ack_oi); |
b_err_o <= (b_stb_i and '0') or (not b_stb_i and b_err_oi); |
b_rty_o <= (b_stb_i and '0') or (not b_stb_i and b_rty_oi); |
else |
s_we_o <= b_we_i; |
s_stb_o <= b_stb_i; |
s_cyc_o <= b_cyc_i; |
b_ack_o <= (b_stb_i and s_ack_i) or (not b_stb_i and b_ack_oi); |
b_err_o <= (b_stb_i and s_err_i) or (not b_stb_i and b_err_oi); |
b_rty_o <= (b_stb_i and s_rty_i) or (not b_stb_i and b_rty_oi); |
a_ack_o <= (a_stb_i and '0') or (not a_stb_i and a_ack_oi); |
a_err_o <= (a_stb_i and '0') or (not a_stb_i and a_err_oi); |
a_rty_o <= (a_stb_i and '0') or (not a_stb_i and a_rty_oi); |
end if; |
end process; |
end behaviour; |
|
-- This acthitecture is a more-or-less structural implementation. Fits for FPGA realization. |
architecture FPGA of wb_arbiter is |
component d_ff |
port ( d : in STD_LOGIC; |
clk: in STD_LOGIC; |
ena: in STD_LOGIC := '1'; |
clr: in STD_LOGIC := '0'; |
pre: in STD_LOGIC := '0'; |
q : out STD_LOGIC |
); |
end component; |
|
signal i_mux_signal: std_logic; |
|
type states is (idle,aa,ba,XX); |
signal e_state: states; |
|
-- signals for a DFF in FPGA |
signal idle_s, aa_s, ba_s: std_logic; |
|
signal aa_clk, aa_ena, aa_clr, aa_pre: std_logic; |
signal ba_clk, ba_ena, ba_clr, ba_pre: std_logic; |
|
begin |
mux_signal <= i_mux_signal; |
|
idle_s <= not (a_cyc_i or b_cyc_i); |
|
aa_clr <= rst_i or not a_cyc_i; |
aa_clk <= a_cyc_i; |
aa_ena <= not b_cyc_i and priority; |
aa_pre <= (a_cyc_i and not priority and not ba_s) or (a_cyc_i and not b_cyc_i); |
aa_ff: d_ff port map ( |
d => '1', |
clk => aa_clk, |
ena => aa_ena, |
clr => aa_clr, |
pre => aa_pre, |
q => aa_s |
); |
|
ba_clr <= rst_i or not b_cyc_i; |
ba_clk <= b_cyc_i; |
ba_ena <= not a_cyc_i and not priority; |
ba_pre <= (b_cyc_i and priority and not aa_s) or (b_cyc_i and not a_cyc_i); |
ba_ff: d_ff port map ( |
d => '1', |
clk => ba_clk, |
ena => ba_ena, |
clr => ba_clr, |
pre => ba_pre, |
q => ba_s |
); |
|
i_mux_signal <= (priority and idle_s) or ba_s; |
|
signal_mux: process is |
begin |
wait on a_we_i, a_stb_i, a_ack_oi, a_err_oi, a_rty_oi, a_cyc_i, |
b_we_i, b_stb_i, b_ack_oi, b_err_oi, b_rty_oi, b_cyc_i, |
s_ack_i, s_err_i, s_rty_i, i_mux_signal; |
if (i_mux_signal = '0') then |
s_we_o <= a_we_i; |
s_stb_o <= a_stb_i; |
s_cyc_o <= a_cyc_i; |
a_ack_o <= (a_stb_i and s_ack_i) or (not a_stb_i and a_ack_oi); |
a_err_o <= (a_stb_i and s_err_i) or (not a_stb_i and a_err_oi); |
a_rty_o <= (a_stb_i and s_rty_i) or (not a_stb_i and a_rty_oi); |
b_ack_o <= (b_stb_i and '0') or (not b_stb_i and b_ack_oi); |
b_err_o <= (b_stb_i and '0') or (not b_stb_i and b_err_oi); |
b_rty_o <= (b_stb_i and '0') or (not b_stb_i and b_rty_oi); |
else |
s_we_o <= b_we_i; |
s_stb_o <= b_stb_i; |
s_cyc_o <= b_cyc_i; |
b_ack_o <= (b_stb_i and s_ack_i) or (not b_stb_i and b_ack_oi); |
b_err_o <= (b_stb_i and s_err_i) or (not b_stb_i and b_err_oi); |
b_rty_o <= (b_stb_i and s_rty_i) or (not b_stb_i and b_rty_oi); |
a_ack_o <= (a_stb_i and '0') or (not a_stb_i and a_ack_oi); |
a_err_o <= (a_stb_i and '0') or (not a_stb_i and a_err_oi); |
a_rty_o <= (a_stb_i and '0') or (not a_stb_i and a_rty_oi); |
end if; |
end process; |
|
gen_e_state: process is |
begin |
wait on idle_s,aa_s,ba_s; |
if (idle_s = '1' and ba_s = '0' and aa_s = '0') then e_state <= idle; |
elsif (idle_s = '0' and ba_s = '1' and aa_s = '0') then e_state <= aa; |
elsif (idle_s = '0' and ba_s = '0' and aa_s = '1') then e_state <= ba; |
else e_state <= XX; |
end if; |
end process; |
end FPGA; |
|
------------------------------------------------------------------------------- |
-- |
-- wb_out_reg |
-- |
------------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
library work; |
use work.technology.all; |
|
entity wb_out_reg is |
generic ( |
width : positive := 8; |
bus_width: positive := 8; |
offset: integer := 0 |
); |
port ( |
clk_i: in std_logic; |
rst_i: in std_logic; |
rst_val: std_logic_vector(width-1 downto 0) := (others => '0'); |
|
dat_i: in std_logic_vector (bus_width-1 downto 0); |
dat_oi: in std_logic_vector (bus_width-1 downto 0) := (others => '-'); |
dat_o: out std_logic_vector (bus_width-1 downto 0); |
q: out std_logic_vector (width-1 downto 0); |
we_i: in std_logic; |
stb_i: in std_logic; |
ack_o: out std_logic; |
ack_oi: in std_logic := '-' |
); |
end wb_out_reg; |
|
architecture wb_out_reg of wb_out_reg is |
signal content : std_logic_vector (width-1 downto 0); |
begin |
-- output bus handling with logic |
gen_dat_o: process is |
variable rd_sel: std_logic; |
begin |
wait on dat_oi, we_i, stb_i, content; |
rd_sel := stb_i and not we_i; |
for i in bus_width-1 downto 0 loop |
if (i >= offset and i < offset+width) then |
dat_o(i) <= (dat_oi(i) and not rd_sel) or (content(i-offset) and rd_sel); |
else |
dat_o(i) <= dat_oi(i); |
end if; |
end loop; |
end process; |
|
-- this item never generates any wait-states |
ack_o <= stb_i or ack_oi; |
|
reg: process is |
begin |
wait until clk_i'EVENT and clk_i='1'; |
if (rst_i = '1') then |
content <= rst_val; |
else |
if (stb_i = '1' and we_i = '1') then |
content <= dat_i(width+offset-1 downto offset); |
end if; |
end if; |
end process; |
q <= content; |
end wb_out_reg; |
/trunk/wb_ram.vhd
0,0 → 1,85
-- |
-- Wishbone bus toolkit. |
-- |
-- (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/03/31 |
-- This code is distributed under the terms and conditions of the GNU General Public Lince. |
-- |
-- |
-- ELEMENTS: |
-- wb_ram: ram element. |
|
------------------------------------------------------------------------------- |
-- |
-- wb_ram |
-- |
------------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
library wb_tk; |
use wb_tk.technology.all; |
|
entity wb_ram is |
generic ( |
data_width: positive := 8; |
addr_width: positive := 10 |
); |
port ( |
clk_i: in std_logic; |
-- rst_i: in std_logic := '0'; |
adr_i: in std_logic_vector (addr_width-1 downto 0); |
-- sel_i: in std_logic_vector ((bus_width/8)-1 downto 0) := (others => '1'); |
dat_i: in std_logic_vector (data_width-1 downto 0); |
dat_oi: in std_logic_vector (data_width-1 downto 0) := (others => '-'); |
dat_o: out std_logic_vector (data_width-1 downto 0); |
cyc_i: in std_logic; |
ack_o: out std_logic; |
ack_oi: in std_logic := '-'; |
-- err_o: out std_logic; |
-- err_oi: in std_logic := '-'; |
-- rty_o: out std_logic; |
-- rty_oi: in std_logic := '-'; |
we_i: in std_logic; |
stb_i: in std_logic |
); |
end wb_ram; |
|
architecture wb_ram of wb_ram is |
component ram |
generic ( |
data_width : positive; |
addr_width : positive |
); |
port ( |
clk : in std_logic; |
we : in std_logic; |
addr : in std_logic_vector(addr_width-1 downto 0); |
d_in : in std_logic_vector(data_width-1 downto 0); |
d_out : out std_logic_vector(data_width-1 downto 0) |
); |
end component; |
|
signal mem_we: std_logic; |
signal mem_dat_o: std_logic_vector(data_width-1 downto 0); |
begin |
mem_we <= we_i and stb_i and cyc_i; |
tech_ram: ram |
generic map ( |
data_width => data_width, |
addr_width => addr_width |
) |
port map ( |
clk => clk_i, |
we => mem_we, |
addr => adr_i, |
d_in => dat_i, |
d_out => mem_dat_o |
); |
|
dat_o_gen: for i in dat_o'RANGE generate |
dat_o(i) <= (mem_dat_o(i) and stb_i and cyc_i and not we_i) or (dat_oi(i) and not (stb_i and cyc_i and not we_i)); |
end generate; |
ack_o <= ('1' and stb_i and cyc_i) or (ack_oi and not (stb_i and cyc_i)); |
end wb_ram; |
|
/trunk/wb_test.vhd
0,0 → 1,222
-- |
-- Wishbone bus tester utilities. |
-- |
-- (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/04/17 |
-- This code is distributed under the terms and conditions of the GNU General Public Lince. |
-- |
-- |
-- ELEMENTS: |
-- procedure wr_chk_val: writes a value, reads it back an checks if it's the same |
-- procedure wr_val: writes a value |
-- procedure rd_val: reads a value |
-- procedure chk_val: checks (after read) a value |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
package wb_test is |
procedure wr_chk_val( |
signal clk_i: in STD_LOGIC; |
signal adr_i: out STD_LOGIC_VECTOR; |
signal dat_o: in STD_LOGIC_VECTOR; |
signal dat_i: out STD_LOGIC_VECTOR; |
signal we_i: out STD_LOGIC; |
signal cyc_i: out std_logic; |
signal stb_i: out STD_LOGIC; |
signal ack_o: in STD_LOGIC; |
constant addr: in STD_LOGIC_VECTOR; |
constant data: in STD_LOGIC_VECTOR |
); |
procedure wr_val( |
signal clk_i: in STD_LOGIC; |
signal adr_i: out STD_LOGIC_VECTOR; |
signal dat_o: in STD_LOGIC_VECTOR; |
signal dat_i: out STD_LOGIC_VECTOR; |
signal we_i: out STD_LOGIC; |
signal cyc_i: out std_logic; |
signal stb_i: out STD_LOGIC; |
signal ack_o: in STD_LOGIC; |
constant addr: in STD_LOGIC_VECTOR; |
constant data: in STD_LOGIC_VECTOR |
); |
procedure rd_val( |
signal clk_i: in STD_LOGIC; |
signal adr_i: out STD_LOGIC_VECTOR; |
signal dat_o: in STD_LOGIC_VECTOR; |
signal dat_i: out STD_LOGIC_VECTOR; |
signal we_i: out STD_LOGIC; |
signal cyc_i: out std_logic; |
signal stb_i: out STD_LOGIC; |
signal ack_o: in STD_LOGIC; |
constant addr: in STD_LOGIC_VECTOR; |
variable data: out STD_LOGIC_VECTOR |
); |
procedure chk_val( |
signal clk_i: in STD_LOGIC; |
signal adr_i: out STD_LOGIC_VECTOR; |
signal dat_o: in STD_LOGIC_VECTOR; |
signal dat_i: out STD_LOGIC_VECTOR; |
signal we_i: out STD_LOGIC; |
signal cyc_i: out std_logic; |
signal stb_i: out STD_LOGIC; |
signal ack_o: in STD_LOGIC; |
constant addr: in STD_LOGIC_VECTOR; |
constant data: in STD_LOGIC_VECTOR |
); |
end wb_test; |
|
|
package body wb_test is |
procedure wr_chk_val( |
signal clk_i: in STD_LOGIC; |
signal adr_i: out STD_LOGIC_VECTOR; |
signal dat_o: in STD_LOGIC_VECTOR; |
signal dat_i: out STD_LOGIC_VECTOR; |
signal we_i: out STD_LOGIC; |
signal cyc_i: out std_logic; |
signal stb_i: out STD_LOGIC; |
signal ack_o: in STD_LOGIC; |
constant addr: in STD_LOGIC_VECTOR; |
constant data: in STD_LOGIC_VECTOR |
) is |
variable adr_zero: STD_LOGIC_VECTOR(adr_i'RANGE) := (others => '0'); |
variable dat_undef: STD_LOGIC_VECTOR(dat_i'RANGE) := (others => 'U'); |
begin |
adr_i <= adr_zero; |
dat_i <= dat_undef; |
stb_i <= '0'; |
we_i <= '0'; |
cyc_i <= '0'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
adr_i <= addr; |
dat_i <= data; |
cyc_i <= '1'; |
stb_i <= '1'; |
we_i <= '1'; |
wait until clk_i'EVENT and clk_i = '1' and ack_o = '1'; |
adr_i <= adr_zero; |
dat_i <= dat_undef; |
cyc_i <= '0'; |
stb_i <= '0'; |
we_i <= '0'; |
wait until clk_i'EVENT and clk_i = '1'; |
adr_i <= addr; |
dat_i <= dat_undef; |
cyc_i <= '1'; |
stb_i <= '1'; |
we_i <= '0'; |
wait until clk_i'EVENT and clk_i = '1' and ack_o = '1'; |
assert dat_o = data report "Value does not match!" severity ERROR; |
adr_i <= adr_zero; |
stb_i <= '0'; |
cyc_i <= '0'; |
end procedure; |
|
procedure wr_val( |
signal clk_i: in STD_LOGIC; |
signal adr_i: out STD_LOGIC_VECTOR; |
signal dat_o: in STD_LOGIC_VECTOR; |
signal dat_i: out STD_LOGIC_VECTOR; |
signal we_i: out STD_LOGIC; |
signal cyc_i: out std_logic; |
signal stb_i: out STD_LOGIC; |
signal ack_o: in STD_LOGIC; |
constant addr: in STD_LOGIC_VECTOR; |
constant data: in STD_LOGIC_VECTOR |
) is |
variable adr_zero: STD_LOGIC_VECTOR(adr_i'RANGE) := (others => '0'); |
variable dat_undef: STD_LOGIC_VECTOR(dat_i'RANGE) := (others => 'U'); |
begin |
adr_i <= adr_zero; |
dat_i <= dat_undef; |
stb_i <= '0'; |
we_i <= '0'; |
cyc_i <= '0'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
adr_i <= addr; |
dat_i <= data; |
cyc_i <= '1'; |
stb_i <= '1'; |
we_i <= '1'; |
wait until clk_i'EVENT and clk_i = '1' and ack_o = '1'; |
adr_i <= adr_zero; |
dat_i <= dat_undef; |
cyc_i <= '0'; |
stb_i <= '0'; |
we_i <= '0'; |
end procedure; |
|
procedure rd_val( |
signal clk_i: in STD_LOGIC; |
signal adr_i: out STD_LOGIC_VECTOR; |
signal dat_o: in STD_LOGIC_VECTOR; |
signal dat_i: out STD_LOGIC_VECTOR; |
signal we_i: out STD_LOGIC; |
signal cyc_i: out std_logic; |
signal stb_i: out STD_LOGIC; |
signal ack_o: in STD_LOGIC; |
constant addr: in STD_LOGIC_VECTOR; |
variable data: out STD_LOGIC_VECTOR |
) is |
variable adr_zero: STD_LOGIC_VECTOR(adr_i'RANGE) := (others => '0'); |
variable dat_undef: STD_LOGIC_VECTOR(dat_i'RANGE) := (others => 'U'); |
begin |
adr_i <= adr_zero; |
dat_i <= dat_undef; |
cyc_i <= '0'; |
stb_i <= '0'; |
we_i <= '0'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
adr_i <= addr; |
dat_i <= dat_undef; |
cyc_i <= '1'; |
stb_i <= '1'; |
we_i <= '0'; |
wait until clk_i'EVENT and clk_i = '1' and ack_o = '1'; |
data := dat_o; |
adr_i <= adr_zero; |
stb_i <= '0'; |
cyc_i <= '0'; |
end procedure; |
|
procedure chk_val( |
signal clk_i: in STD_LOGIC; |
signal adr_i: out STD_LOGIC_VECTOR; |
signal dat_o: in STD_LOGIC_VECTOR; |
signal dat_i: out STD_LOGIC_VECTOR; |
signal we_i: out STD_LOGIC; |
signal cyc_i: out std_logic; |
signal stb_i: out STD_LOGIC; |
signal ack_o: in STD_LOGIC; |
constant addr: in STD_LOGIC_VECTOR; |
constant data: in STD_LOGIC_VECTOR |
) is |
variable adr_zero: STD_LOGIC_VECTOR(adr_i'RANGE) := (others => '0'); |
variable dat_undef: STD_LOGIC_VECTOR(dat_i'RANGE) := (others => 'U'); |
begin |
adr_i <= adr_zero; |
dat_i <= dat_undef; |
cyc_i <= '0'; |
stb_i <= '0'; |
we_i <= '0'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
adr_i <= addr; |
dat_i <= dat_undef; |
cyc_i <= '1'; |
stb_i <= '1'; |
we_i <= '0'; |
wait until clk_i'EVENT and clk_i = '1' and ack_o = '1'; |
assert dat_o = data report "Value does not match!" severity ERROR; |
adr_i <= adr_zero; |
stb_i <= '0'; |
cyc_i <= '0'; |
end procedure; |
end package body wb_test; |
/trunk/technology.vhd
16,6 → 16,11
function sl(l: std_logic_vector; r: integer) return std_logic_vector; |
-- procedure inc(data : inout std_logic_vector); |
function "+"(op_l, op_r: std_logic_vector) return std_logic_vector; |
function log2(inp : integer) return integer; |
function size2bits(inp : integer) return integer; |
function max(a : integer; b: integer) return integer; |
function min(a : integer; b: integer) return integer; |
function equ(a : std_logic_vector; b : integer) return boolean; |
|
component d_ff is |
port ( d : in STD_LOGIC; |
49,6 → 54,8
use IEEE.std_logic_1164.all; |
library exemplar; |
use exemplar.exemplar_1164.all; |
library synopsys; |
use synopsys.std_logic_arith.all; |
|
package body technology is |
function "+"(op_l, op_r: std_logic_vector) return std_logic_vector is |
77,6 → 84,69
-- begin |
-- data := addone(data); |
-- end; |
function max(a : integer; b: integer) return integer is |
begin |
if (a > b) then return a; end if; |
return b; |
end; |
|
function min(a : integer; b: integer) return integer is |
begin |
if (a < b) then return a; end if; |
return b; |
end; |
|
function log2(inp : integer) return integer is |
begin |
if (inp < 1) then return 0; end if; |
if (inp < 2) then return 0; end if; |
if (inp < 4) then return 1; end if; |
if (inp < 8) then return 2; end if; |
if (inp < 16) then return 3; end if; |
if (inp < 32) then return 4; end if; |
if (inp < 64) then return 5; end if; |
if (inp < 128) then return 6; end if; |
if (inp < 256) then return 7; end if; |
if (inp < 512) then return 8; end if; |
if (inp < 1024) then return 9; end if; |
if (inp < 2048) then return 10; end if; |
if (inp < 4096) then return 11; end if; |
if (inp < 8192) then return 12; end if; |
if (inp < 16384) then return 13; end if; |
if (inp < 32768) then return 14; end if; |
if (inp < 65538) then return 15; end if; |
return 16; |
end; |
|
function size2bits(inp : integer) return integer is |
begin |
if (inp < 1) then return 1; end if; |
if (inp < 2) then return 1; end if; |
if (inp < 4) then return 2; end if; |
if (inp < 8) then return 3; end if; |
if (inp < 16) then return 4; end if; |
if (inp < 32) then return 5; end if; |
if (inp < 64) then return 6; end if; |
if (inp < 128) then return 7; end if; |
if (inp < 256) then return 8; end if; |
if (inp < 512) then return 9; end if; |
if (inp < 1024) then return 10; end if; |
if (inp < 2048) then return 11; end if; |
if (inp < 4096) then return 12; end if; |
if (inp < 8192) then return 13; end if; |
if (inp < 16384) then return 14; end if; |
if (inp < 32768) then return 15; end if; |
if (inp < 65538) then return 16; end if; |
return 17; |
end; |
|
function equ(a : std_logic_vector; b : integer) return boolean is |
variable b_s : std_logic_vector(a'RANGE); |
begin |
b_s := CONV_STD_LOGIC_VECTOR(b,a'HIGH+1); |
return (a = b_s); |
end; |
|
end package body technology; |
|
|
150,10 → 220,169
); |
end altera; |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
library exemplar; |
use exemplar.exemplar_1164.all; |
|
library lpm; |
use lpm.all; |
|
entity ram is |
generic ( |
data_width : positive; |
addr_width : positive |
); |
port ( |
clk : in std_logic; |
we : in std_logic; |
addr : in std_logic_vector(addr_width-1 downto 0); |
d_in : in std_logic_vector(data_width-1 downto 0); |
d_out : out std_logic_vector(data_width-1 downto 0) |
); |
end ram; |
|
architecture altera of ram is |
component lpm_ram_dp |
generic ( |
lpm_width: positive; |
lpm_widthad: positive; |
lpm_numwords: natural := 0; |
lpm_type: string := "lpm_ram_dp"; |
lpm_indata: string := "REGISTERED"; |
lpm_outdata: string := "UNREGISTERED"; |
lpm_rdaddress_control: string := "REGISTERED"; |
lpm_wraddress_control: string := "REGISTERED"; |
lpm_file: string := "UNUSED"; |
lpm_hint: string := "UNUSED" |
); |
port ( |
rdaddress, wraddress: in std_logic_vector(lpm_widthad-1 downto 0); |
rdclock, wrclock: in std_logic := '0'; |
rden, rdclken, wrclken: in std_logic := '1'; |
wren: in std_logic; |
data: in std_logic_vector(lpm_width-1 downto 0); |
q: out std_logic_vector(lpm_width-1 downto 0) |
); |
end component; |
begin |
altera_ram: lpm_ram_dp |
generic map ( |
lpm_width => data_width, |
lpm_widthad => addr_width, |
lpm_numwords => 2 ** addr_width, |
lpm_type => "lpm_ram_dp", |
lpm_indata => "REGISTERED", |
lpm_wraddress_control => "REGISTERED", |
lpm_outdata => "UNREGISTERED", |
lpm_rdaddress_control => "UNREGISTERED", |
lpm_file => "UNUSED", |
lpm_hint => "UNUSED" |
) |
port map ( |
rdclock => clk, |
rdclken => '1', |
rdaddress => addr, |
q => d_out, |
rden => '1', |
|
wrclock => clk, |
wrclken => '1', |
wraddress => addr, |
data => d_in, |
wren => we |
); |
end altera; |
|
|
|
|
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
library exemplar; |
use exemplar.exemplar_1164.all; |
|
library lpm; |
use lpm.all; |
|
entity dpram is |
generic ( |
data_width : positive; |
addr_width : positive |
); |
port ( |
clk : in std_logic; |
|
r_d_out : out std_logic_vector(data_width-1 downto 0); |
r_rd : in std_logic; |
r_clk_en : in std_logic; |
r_addr : in std_logic_vector(addr_width-1 downto 0); |
|
w_d_in : in std_logic_vector(data_width-1 downto 0); |
w_wr : in std_logic; |
w_clk_en : in std_logic; |
w_addr : in std_logic_vector(addr_width-1 downto 0) |
); |
end dpram; |
|
architecture altera of dpram is |
component lpm_ram_dp |
generic ( |
lpm_width: positive; |
lpm_widthad: positive; |
lpm_numwords: natural := 0; |
lpm_type: string := "lpm_ram_dp"; |
lpm_indata: string := "REGISTERED"; |
lpm_outdata: string := "UNREGISTERED"; |
lpm_rdaddress_control: string := "REGISTERED"; |
lpm_wraddress_control: string := "REGISTERED"; |
lpm_file: string := "UNUSED"; |
lpm_hint: string := "UNUSED" |
); |
port ( |
rdaddress, wraddress: in std_logic_vector(lpm_widthad-1 downto 0); |
rdclock, wrclock: in std_logic := '0'; |
rden, rdclken, wrclken: in std_logic := '1'; |
wren: in std_logic; |
data: in std_logic_vector(lpm_width-1 downto 0); |
q: out std_logic_vector(lpm_width-1 downto 0) |
); |
end component; |
begin |
altera_ram: lpm_ram_dp |
generic map ( |
lpm_width => data_width, |
lpm_widthad => addr_width, |
lpm_numwords => 2 ** addr_width, |
lpm_type => "lpm_ram_dp", |
lpm_indata => "REGISTERED", |
lpm_wraddress_control => "REGISTERED", |
lpm_outdata => "UNREGISTERED", |
lpm_rdaddress_control => "UNREGISTERED", |
lpm_file => "UNUSED", |
lpm_hint => "UNUSED" |
) |
port map ( |
rdclock => clk, |
rdclken => r_clk_en, |
rdaddress => r_addr, |
q => r_d_out, |
rden => r_rd, |
|
wrclock => clk, |
wrclken => w_clk_en, |
wraddress => w_addr, |
data => w_d_in, |
wren => w_wr |
); |
end altera; |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
library altera_exemplar; |
use altera_exemplar.all; |
|
/trunk/wb_out_reg.vhd
0,0 → 1,94
-- |
-- Wishbone bus toolkit. |
-- |
-- (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/03/31 |
-- This code is distributed under the terms and conditions of the GNU General Public Lince. |
-- |
-- |
-- ELEMENTS: |
-- wb_out_reg: Wishbone bus compatible output register. |
|
------------------------------------------------------------------------------- |
-- |
-- wb_out_reg |
-- |
------------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
|
library wb_tk; |
use wb_tk.technology.all; |
|
entity wb_out_reg is |
generic ( |
width : positive := 8; |
bus_width: positive := 8; |
offset: integer := 0 |
); |
port ( |
clk_i: in std_logic; |
rst_i: in std_logic; |
rst_val: std_logic_vector(width-1 downto 0) := (others => '0'); |
|
cyc_i: in std_logic := '1'; |
stb_i: in std_logic; |
sel_i: in std_logic_vector ((bus_width/8)-1 downto 0) := (others => '1'); |
we_i: in std_logic; |
ack_o: out std_logic; |
ack_oi: in std_logic := '-'; |
adr_i: in std_logic_vector (size2bits((width+offset+bus_width-1)/bus_width)-1 downto 0) := (others => '0'); |
dat_i: in std_logic_vector (bus_width-1 downto 0); |
dat_oi: in std_logic_vector (bus_width-1 downto 0) := (others => '-'); |
dat_o: out std_logic_vector (bus_width-1 downto 0); |
q: out std_logic_vector (width-1 downto 0) |
); |
end wb_out_reg; |
|
architecture wb_out_reg of wb_out_reg is |
signal content : std_logic_vector (width-1 downto 0); |
begin |
-- output bus handling with logic |
gen_dat_o: process is |
variable rd_sel: std_logic; |
variable adr: integer; |
variable reg_i: integer; |
begin |
wait on dat_oi, we_i, stb_i, content, adr_i, cyc_i, sel_i; |
rd_sel := cyc_i and stb_i and not we_i; |
for i in dat_i'RANGE loop |
adr := CONV_INTEGER(adr_i); |
reg_i := i-offset+adr*bus_width; |
if ((reg_i >= 0) and (reg_i < width) and (sel_i(i/8) = '1')) then |
dat_o(i) <= (dat_oi(i) and not rd_sel) or (content(reg_i) and rd_sel); |
else |
dat_o(i) <= dat_oi(i); |
end if; |
end loop; |
end process; |
|
-- this item never generates any wait-states |
ack_o <= stb_i or ack_oi; |
|
reg: process is |
variable adr: integer; |
variable reg_i: integer; |
begin |
wait until clk_i'EVENT and clk_i='1'; |
if (rst_i = '1') then |
content <= rst_val; |
else |
if (stb_i = '1' and cyc_i = '1' and we_i = '1') then |
for i in dat_i'RANGE loop |
adr := CONV_INTEGER(adr_i); |
reg_i := i-offset+adr*bus_width; |
if ((reg_i >= 0) and (reg_i < width) and (sel_i(i/8) = '1')) then |
content(reg_i) <= dat_i(i); |
end if; |
end loop; |
end if; |
end if; |
end process; |
q <= content; |
end wb_out_reg; |
/trunk/Makefile
0,0 → 1,2
all: |
bash compile.sh |
/trunk/wb_bus_dnsize.vhd
0,0 → 1,138
-- |
-- Wishbone bus toolkit. |
-- |
-- (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/03/31 |
-- This code is distributed under the terms and conditions of the GNU General Public Lince. |
-- |
-- |
-- ELEMENTS: |
-- wb_bus_dnsize: bus downsizer. |
-- doesn't split access cycles so granularity on the input bus must not be greater than |
-- the width of the output bus. |
|
------------------------------------------------------------------------------- |
-- |
-- wb_bus_upsize |
-- |
------------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
|
library wb_tk; |
use wb_tk.technology.all; |
|
library synopsys; |
use synopsys.std_logic_arith.all; |
|
entity wb_bus_dnsize is |
generic ( |
m_bus_width: positive := 32; -- master bus width |
m_addr_width: positive := 20; -- master bus width |
s_bus_width: positive := 16; -- slave bus width |
s_addr_width: positive := 21; -- master bus width |
little_endien: boolean := true -- if set to false, big endien |
); |
port ( |
-- clk_i: in std_logic; |
-- rst_i: in std_logic := '0'; |
|
-- Master bus interface |
m_adr_i: in std_logic_vector (m_addr_width-1 downto 0); |
m_sel_i: in std_logic_vector ((m_bus_width/8)-1 downto 0) := (others => '1'); |
m_dat_i: in std_logic_vector (m_bus_width-1 downto 0); |
m_dat_oi: in std_logic_vector (m_bus_width-1 downto 0) := (others => '-'); |
m_dat_o: out std_logic_vector (m_bus_width-1 downto 0); |
m_cyc_i: in std_logic; |
m_ack_o: out std_logic; |
m_ack_oi: in std_logic := '-'; |
m_err_o: out std_logic; |
m_err_oi: in std_logic := '-'; |
m_rty_o: out std_logic; |
m_rty_oi: in std_logic := '-'; |
m_we_i: in std_logic; |
m_stb_i: in std_logic; |
|
-- Slave bus interface |
s_adr_o: out std_logic_vector (s_addr_width-1 downto 0); |
s_sel_o: out std_logic_vector ((s_bus_width/8)-1 downto 0); |
s_dat_i: in std_logic_vector (s_bus_width-1 downto 0); |
s_dat_o: out std_logic_vector (s_bus_width-1 downto 0); |
s_cyc_o: out std_logic; |
s_ack_i: in std_logic; |
s_err_i: in std_logic := '-'; |
s_rty_i: in std_logic := '-'; |
s_we_o: out std_logic; |
s_stb_o: out std_logic |
); |
end wb_bus_dnsize; |
|
architecture wb_bus_dnsize of wb_bus_dnsize is |
constant addr_diff: integer := log2(m_bus_width/s_bus_width); |
constant mux_mask: integer := ((m_bus_width / 8)-1) - ((s_bus_width/8)-1); |
signal i_m_dat_o: std_logic_vector(m_bus_width-1 downto 0); |
signal mux_sel: std_logic_vector(log2(m_sel_i'HIGH+1)-1 downto 0); |
signal i_mux_sel: integer := 0; |
|
function prior_decode(inp: std_logic_vector) return integer is |
begin |
-- variable ret: std_logic_vector(log2(inp'HIGH)-1 downto 0) := (others = '1'); |
for i in inp'HIGH downto 0 loop |
if (inp(i) = '1') then |
return i; |
end if; |
end loop; |
return inp'HIGH; |
end; |
begin |
assert (s_addr_width = m_addr_width+addr_diff) report "Address widths are not consistent" severity FAILURE; |
|
-- Reconstructing address bits (mux_sel) |
compute_mux_sel: process is |
variable i: integer; |
begin |
wait on m_sel_i; |
i := prior_decode(m_sel_i); |
mux_sel <= CONV_STD_LOGIC_VECTOR(i,log2(m_sel_i'HIGH+1)) and CONV_STD_LOGIC_VECTOR(mux_mask,log2(m_sel_i'HIGH+1)); |
end process; |
i_mux_sel <= CONV_INTEGER(mux_sel); |
|
|
-- create slave address bus |
s_adr_o(s_addr_width-1 downto addr_diff) <= m_adr_i; |
s_adr_o_gen: process is |
variable all_ones: std_logic_vector(addr_diff-1 downto 0) := (others => '1'); |
begin |
wait on mux_sel(mux_sel'HIGH downto mux_sel'HIGH-addr_diff+1); |
if (little_endien) then |
s_adr_o(addr_diff-1 downto 0) <= mux_sel(mux_sel'HIGH downto mux_sel'HIGH-addr_diff+1); |
else |
s_adr_o(addr_diff-1 downto 0) <= all_ones-mux_sel(mux_sel'HIGH downto mux_sel'HIGH-addr_diff+1); |
end if; |
end process; |
|
-- create output byte select signals |
s_sel_o <= m_sel_i(i_mux_sel+(s_bus_width/8)-1 downto i_mux_sel); |
|
|
s_we_o <= m_we_i; |
m_ack_o <= (m_stb_i and s_ack_i) or (not m_stb_i and m_ack_oi); |
m_err_o <= (m_stb_i and s_err_i) or (not m_stb_i and m_err_oi); |
m_rty_o <= (m_stb_i and s_rty_i) or (not m_stb_i and m_rty_oi); |
s_stb_o <= m_stb_i; |
s_cyc_o <= m_cyc_i; |
|
-- Multiplex data-bus down to the slave width |
s_dat_o <= m_dat_i((i_mux_sel)*8-1+s_bus_width downto (i_mux_sel)*8); |
|
m_dat_o_mux: process is |
begin |
wait on m_dat_oi, s_dat_i, i_mux_sel, m_stb_i, m_we_i; |
m_dat_o <= m_dat_oi; |
if (m_stb_i = '1' and m_we_i = '0') then |
m_dat_o((i_mux_sel)*8-1+s_bus_width downto (i_mux_sel)*8) <= s_dat_i; |
end if; |
end process; |
end wb_bus_dnsize; |
|