OpenCores
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 5 to Rev 6
    Reverse comparison

Rev 5 → Rev 6

/trunk/wb_tk.vhd File deleted
/trunk/Makefile File deleted \ No newline at end of file
/trunk/compile.sh File deleted
/trunk/TestBench/wb_async_master_TB.vhd
0,0 → 1,420
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
library WB_TK;
use WB_TK.components.ALL;
 
entity wb_async_master_TB is
generic (
dat_width: positive := 8;
adr_width: positive := 8;
ab_rd_delay: positive := 2
);
end wb_async_master_TB;
 
architecture xilinx of wb_async_master_TB is
component wb_async_master_2
generic (
dat_width: positive := dat_width;
adr_width: positive := adr_width;
ab_rd_delay: positive := ab_rd_delay
);
port (
wb_clk_i: in std_logic;
wb_rst_i: in std_logic := '0';
-- interface to wb slave devices
wb_adr_o: out std_logic_vector (adr_width-1 downto 0);
wb_sel_o: out std_logic_vector ((dat_width/8)-1 downto 0);
wb_dat_i: in std_logic_vector (dat_width-1 downto 0);
wb_dat_o: out std_logic_vector (dat_width-1 downto 0);
wb_cyc_o: out std_logic;
wb_ack_i: in std_logic;
wb_err_i: in std_logic := '-';
wb_rty_i: in std_logic := '-';
wb_we_o: out std_logic;
wb_stb_o: out std_logic;
-- interface to the asyncronous master device
ab_dat: inout std_logic_vector (dat_width-1 downto 0) := (others => 'Z');
ab_adr: in std_logic_vector (adr_width-1 downto 0) := (others => 'U');
ab_rd_n: in std_logic := '1';
ab_wr_n: in std_logic := '1';
ab_ce_n: in std_logic := '1';
ab_byteen_n: in std_logic_vector ((dat_width/8)-1 downto 0);
ab_wait_n: out std_logic; -- wait-state request 'open-drain' output
ab_waiths: out std_logic -- handshake-type totem-pole output
);
end component;
 
signal wb_clk_i: std_logic;
signal wb_rst_i: std_logic := '0';
 
-- interface to wb slave devices
signal wb_adr_o: std_logic_vector (adr_width-1 downto 0);
signal wb_sel_o: std_logic_vector ((dat_width/8)-1 downto 0);
signal wb_dat_i: std_logic_vector (dat_width-1 downto 0);
signal wb_dat_o: std_logic_vector (dat_width-1 downto 0);
signal wb_cyc_o: std_logic;
signal wb_ack_i: std_logic;
signal wb_err_i: std_logic := '-';
signal wb_rty_i: std_logic := '-';
signal wb_we_o: std_logic;
signal wb_stb_o: std_logic;
 
-- interface to asyncron master device
signal ab_dat: std_logic_vector (dat_width-1 downto 0) := (others => 'Z');
signal ab_adr: std_logic_vector (adr_width-1 downto 0) := (others => 'U');
signal ab_rd_n: std_logic := '1';
signal ab_wr_n: std_logic := '1';
signal ab_ce_n: std_logic := '1';
signal ab_byteen_n: std_logic_vector ((dat_width/8)-1 downto 0);
signal ab_wait_n: std_logic;
signal ab_waiths: std_logic;
signal wait_mode: integer := 0;
signal ab_wait: std_logic;
procedure wait_for_cycle_end(
signal ab_wait: in std_logic;
wait_mode: in integer
) is begin
if wait_mode = 0 then
if ab_wait = '0' then
wait until ab_wait /= '0';
end if;
elsif wait_mode = 1 then
if ab_wait = '0' then
wait until ab_wait = '1';
end if;
else
end if;
end wait_for_cycle_end;
 
procedure wait_for_idle(
signal ab_wait: in std_logic;
wait_mode: in integer
) is begin
if wait_mode = 0 then
-- nothing to do in this case
else
if ab_wait = '1' then
wait until ab_wait = '0';
end if;
end if;
end wait_for_idle;
 
procedure do_write(
signal as_dat: inout std_logic_vector (dat_width-1 downto 0);
signal as_adr: out std_logic_vector (adr_width-1 downto 0);
signal as_rd_n: out std_logic;
signal as_wr_n: out std_logic;
signal as_ce_n: out std_logic;
signal as_byteen_n: out std_logic_vector ((dat_width/8)-1 downto 0);
signal as_wait: in std_logic;
a_dat: in std_logic_vector(dat_width-1 downto 0);
a_adr: in std_logic_vector(adr_width-1 downto 0);
a_cycle_length: in time;
a_setup_time: in time;
a_wait_mode: in integer
) is begin
wait_for_idle(as_wait,a_wait_mode);
as_dat <= (others => 'X');
as_adr <= (others => 'X');
as_byteen_n <= (others => 'X');
as_rd_n <= '1';
as_wr_n <= '0';
as_ce_n <= '0';
wait for a_setup_time;
as_dat <= a_dat;
as_adr <= a_adr;
as_byteen_n <= (others => '0');
wait for a_cycle_length-a_setup_time;
wait_for_cycle_end(as_wait,a_wait_mode);
as_dat <= (others => 'Z');
as_adr <= (others => 'U');
as_byteen_n <= (others => 'U');
as_rd_n <= '1';
as_wr_n <= '1';
as_ce_n <= '1';
end do_write;
 
procedure do_read(
signal as_dat: inout std_logic_vector (dat_width-1 downto 0);
signal as_adr: out std_logic_vector (adr_width-1 downto 0);
signal as_rd_n: out std_logic;
signal as_wr_n: out std_logic;
signal as_ce_n: out std_logic;
signal as_byteen_n: out std_logic_vector ((dat_width/8)-1 downto 0);
signal as_wait: in std_logic;
a_expected_dat: in std_logic_vector(dat_width-1 downto 0);
a_adr: in std_logic_vector(adr_width-1 downto 0);
a_cycle_length: in time;
a_setup_time: in time;
a_wait_mode: in integer
) is begin
wait_for_idle(as_wait,a_wait_mode);
as_dat <= "ZZZZZZZZ";
as_adr <= (others => 'X');
as_byteen_n <= (others => 'X');
as_rd_n <= '0';
as_wr_n <= '1';
as_ce_n <= '0';
wait for a_setup_time;
as_adr <= a_adr;
as_byteen_n <= (others => '0');
wait for a_cycle_length-a_setup_time;
wait_for_cycle_end(as_wait,a_wait_mode);
for i in ab_dat'RANGE loop
ASSERT (as_dat(i) = a_expected_dat(i)) report "Cannot read back data from bus!" severity error;
end loop;
wait for 12 ns;
as_dat <= (others => 'Z');
as_adr <= (others => 'U');
as_byteen_n <= (others => 'U');
as_rd_n <= '1';
as_wr_n <= '1';
as_ce_n <= '1';
end do_read;
begin
ab_wait <= ab_wait_n when wait_mode = 0 else ab_waiths;
clk_gen: process
begin
wb_clk_i <= '1';
wait for 25 ns;
wb_clk_i <= '0';
wait for 25 ns;
end process;
 
reset_gen: process
begin
wb_rst_i <= '1';
wait for 100 ns;
wb_rst_i <= '0';
wait;
end process;
 
ss_slave: process
begin
if wb_rst_i = '1' then
wb_err_i <= '0';
wb_rty_i <= '0';
wb_ack_i <= '0';
wb_dat_i <= (others => 'U');
end if;
wait until wb_clk_i'EVENT and wb_clk_i = '1';
if wb_cyc_o = '1' then
if wb_we_o = '1' then
-- write cycle
-- simulate 2 WS
wb_ack_i <= '0';
wb_dat_i <= (others => 'U');
wait until wb_clk_i'EVENT and wb_clk_i = '1';
wait until wb_clk_i'EVENT and wb_clk_i = '1';
wb_ack_i <= '1';
wait until wb_clk_i'EVENT and wb_clk_i = '1';
wb_ack_i <= '0';
else
-- read cycle
-- simulate 3 WS
wb_dat_i <= (others => 'U');
wb_ack_i <= '0';
wait until wb_clk_i'EVENT and wb_clk_i = '1';
wait until wb_clk_i'EVENT and wb_clk_i = '1';
wait until wb_clk_i'EVENT and wb_clk_i = '1';
wb_ack_i <= '1';
wb_dat_i <= wb_adr_o(wb_dat_i'RANGE);
wait until wb_clk_i'EVENT and wb_clk_i = '1';
wb_dat_i <= (others => 'U');
wb_ack_i <= '0';
end if;
end if;
end process;
 
as_master: process
begin
if (wb_rst_i = '1') then
ab_adr <= (others => '0');
ab_dat <= (others => 'Z');
ab_rd_n <= '1';
ab_wr_n <= '1';
ab_ce_n <= '1';
wait until wb_rst_i = '0';
end if;
wait for 210 ns;
 
-- test1: normal write
do_write(
ab_dat,ab_adr,ab_rd_n,ab_wr_n,ab_ce_n,ab_byteen_n,ab_wait,
"10000001",
"01000001",
202 ns,
55 ns,
wait_mode
);
 
wait for 300 ns;
 
-- test2: normal read
do_read(
ab_dat,ab_adr,ab_rd_n,ab_wr_n,ab_ce_n,ab_byteen_n,ab_wait,
"00000010",
"00000010",
202 ns,
55 ns,
wait_mode
);
 
wait for 55 ns;
 
-- test3: normal write
do_write(
ab_dat,ab_adr,ab_rd_n,ab_wr_n,ab_ce_n,ab_byteen_n,ab_wait,
"10010001",
"01010001",
402 ns,
55 ns,
wait_mode
);
 
wait for 300 ns;
 
-- test4: normal read
do_read(
ab_dat,ab_adr,ab_rd_n,ab_wr_n,ab_ce_n,ab_byteen_n,ab_wait,
"00010010",
"00010010",
502 ns,
55 ns,
wait_mode
);
 
wait for 55 ns;
 
-- test5: normal write
do_write(
ab_dat,ab_adr,ab_rd_n,ab_wr_n,ab_ce_n,ab_byteen_n,ab_wait,
"10000011",
"01000011",
202 ns,
55 ns,
wait_mode
);
 
wait for 55 ns;
-- test4: overlapped read: should wait until posted write finishes
do_read(
ab_dat,ab_adr,ab_rd_n,ab_wr_n,ab_ce_n,ab_byteen_n,ab_wait,
"00000100",
"00000100",
202 ns,
55 ns,
wait_mode
);
wait for 5 ns;
-- test4: out-of-order read: should handled correctly without loosing sync
do_read(
ab_dat,ab_adr,ab_rd_n,ab_wr_n,ab_ce_n,ab_byteen_n,ab_wait,
"00000100",
"00000100",
85 ns,
55 ns,
wait_mode
);
wait for 5 ns;
-- test4: out-of-order read: should handled correctly without loosing sync
do_read(
ab_dat,ab_adr,ab_rd_n,ab_wr_n,ab_ce_n,ab_byteen_n,ab_wait,
"00000100",
"00000100",
85 ns,
55 ns,
2 --wait_mode
);
-- wait for 200 ns;
-- do_read(
-- ab_dat,ab_adr,ab_rd_n,ab_wr_n,ab_ce_n,ab_byteen_n,ab_wait,
--
-- "00000100",
-- "00000100",
-- 202 ns,
-- 55 ns,
-- wait_mode
-- );
wait for 200 ns;
 
-- test5: normal write
do_write(
ab_dat,ab_adr,ab_rd_n,ab_wr_n,ab_ce_n,ab_byteen_n,ab_wait,
"10000101",
"01000101",
202 ns,
55 ns,
wait_mode
);
 
wait for 55 ns;
-- test5: overlapped write: should wait until posted write finishes
do_write(
ab_dat,ab_adr,ab_rd_n,ab_wr_n,ab_ce_n,ab_byteen_n,ab_wait,
"10000110",
"01000110",
202 ns,
55 ns,
wait_mode
);
 
if wait_mode = 0 then
wait for 450 ns;
wait_mode <= 1;
wait for 50 ns;
else
wait;
end if;
end process;
 
UUT: wb_async_master_2
port map (
wb_clk_i => wb_clk_i,
wb_rst_i => wb_rst_i,
 
-- interfaceto wb slave devices
wb_adr_o => wb_adr_o,
wb_sel_o => wb_sel_o,
wb_dat_i => wb_dat_i,
wb_dat_o => wb_dat_o,
wb_cyc_o => wb_cyc_o,
wb_ack_i => wb_ack_i,
wb_err_i => wb_err_i,
wb_rty_i => wb_rty_i,
wb_we_o => wb_we_o,
wb_stb_o => wb_stb_o,
 
-- interfaceto asyncron master device
ab_dat => ab_dat,
ab_adr => ab_adr,
ab_rd_n => ab_rd_n,
ab_wr_n => ab_wr_n,
ab_ce_n => ab_ce_n,
ab_byteen_n => ab_byteen_n,
ab_wait_n => ab_wait_n,
ab_waiths => ab_waiths
);
end xilinx;
 
/trunk/wb_async_slave.vhd
16,6 → 16,7
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
 
library wb_tk;
use wb_tk.technology.all;
22,35 → 23,35
 
entity wb_async_slave is
generic (
width: positive := 16;
addr_width: positive := 20
dat_width: positive := 16;
adr_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 => '-');
adr_i: in std_logic_vector (adr_width-1 downto 0);
sel_i: in std_logic_vector ((adr_width/8)-1 downto 0);
dat_i: in std_logic_vector (dat_width-1 downto 0);
dat_o: out std_logic_vector (dat_width-1 downto 0);
dat_oi: in std_logic_vector (dat_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_data: inout std_logic_vector (dat_width-1 downto 0) := (others => 'Z');
a_addr: out std_logic_vector (adr_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)
a_byen: out std_logic_vector ((dat_width/8)-1 downto 0)
);
end wb_async_slave;
 
65,11 → 66,11
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));
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
i_ack_gen: process
begin
wait on sm_ack, stb_i, wait_state, state;
if (wait_state = "0000") then
81,9 → 82,9
i_ack <= sm_ack;
end if;
end process;
 
-- SRAM signal-handler process
sram_signals: process is
sram_signals: process
begin
wait on state,we_i,a_data,adr_i,rst_i, stb_i, sel_i, dat_i;
if (rst_i = '1') then
92,7 → 93,7
a_cen <= '1';
a_addr <= (others => '-');
a_data <= (others => 'Z');
a_byen <= (others => '1');
a_byen <= (others => '1');
else
case (state) is
when sm_deact =>
101,15 → 102,15
a_cen <= '1';
a_addr <= (others => '-');
a_data <= (others => 'Z');
a_byen <= (others => '1');
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;
a_byen <= not sel_i;
if (we_i = '1') then
a_data <= dat_i;
else
a_data <= (others => 'Z');
end if;
118,7 → 119,7
end process;
 
-- Aysnc access state-machine.
async_sm: process is
async_sm: process
-- variable cnt: std_logic_vector(3 downto 0) := "0000";
-- variable state: states := init;
begin
154,12 → 155,12
sm_ack <= '0';
cnt <= "0000";
else
if (add_one(cnt) = wait_state) then
if (cnt+"1" = wait_state) then
sm_ack <= '1';
else
sm_ack <= '0';
end if;
cnt <= add_one(cnt);
cnt <=cnt+"1";
end if;
when sm_deact =>
if (stb_i = '1') then
/trunk/wb_bus_resize.vhd
16,17 → 16,15
 
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
m_dat_width: positive := 32; -- master bus width
m_adr_width: positive := 19; -- master bus width
s_dat_width: positive := 16; -- slave bus width
s_adr_width: positive := 20; -- master bus width
little_endien: boolean := true -- if set to false, big endien
);
port (
34,11 → 32,11
-- 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_adr_i: in std_logic_vector (m_adr_width-1 downto 0);
m_sel_i: in std_logic_vector ((m_dat_width/8)-1 downto 0) := (others => '1');
m_dat_i: in std_logic_vector (m_dat_width-1 downto 0);
m_dat_oi: in std_logic_vector (m_dat_width-1 downto 0) := (others => '-');
m_dat_o: out std_logic_vector (m_dat_width-1 downto 0);
m_cyc_i: in std_logic;
m_ack_o: out std_logic;
m_ack_oi: in std_logic := '-';
50,10 → 48,10
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_adr_o: out std_logic_vector (s_adr_width-1 downto 0);
s_sel_o: out std_logic_vector ((s_dat_width/8)-1 downto 0);
s_dat_i: in std_logic_vector (s_dat_width-1 downto 0);
s_dat_o: out std_logic_vector (s_dat_width-1 downto 0);
s_cyc_o: out std_logic;
s_ack_i: in std_logic;
s_err_i: in std_logic := '-';
64,24 → 62,24
end wb_bus_resize;
 
architecture wb_bus_resize of wb_bus_resize is
component wb_bus_upsize is
component wb_bus_upsize
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
m_dat_width: positive := 8; -- master bus width
m_adr_width: positive := 21; -- master bus width
s_dat_width: positive := 16; -- slave bus width
s_adr_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_adr_i: in std_logic_vector (m_adr_width-1 downto 0);
m_sel_i: in std_logic_vector ((m_dat_width/8)-1 downto 0) := (others => '1');
m_dat_i: in std_logic_vector (m_dat_width-1 downto 0);
m_dat_oi: in std_logic_vector (m_dat_width-1 downto 0) := (others => '-');
m_dat_o: out std_logic_vector (m_dat_width-1 downto 0);
m_cyc_i: in std_logic;
m_ack_o: out std_logic;
m_ack_oi: in std_logic := '-';
91,12 → 89,12
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_adr_o: out std_logic_vector (s_adr_width-1 downto 0);
s_sel_o: out std_logic_vector ((s_dat_width/8)-1 downto 0);
s_dat_i: in std_logic_vector (s_dat_width-1 downto 0);
s_dat_o: out std_logic_vector (s_dat_width-1 downto 0);
s_cyc_o: out std_logic;
s_ack_i: in std_logic;
s_err_i: in std_logic := '-';
106,24 → 104,24
);
end component;
 
component wb_bus_dnsize is
component wb_bus_dnsize
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
m_dat_width: positive := 32; -- master bus width
m_adr_width: positive := 20; -- master bus width
s_dat_width: positive := 16; -- slave bus width
s_adr_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_adr_i: in std_logic_vector (m_adr_width-1 downto 0);
m_sel_i: in std_logic_vector ((m_dat_width/8)-1 downto 0) := (others => '1');
m_dat_i: in std_logic_vector (m_dat_width-1 downto 0);
m_dat_oi: in std_logic_vector (m_dat_width-1 downto 0) := (others => '-');
m_dat_o: out std_logic_vector (m_dat_width-1 downto 0);
m_cyc_i: in std_logic;
m_ack_o: out std_logic;
m_ack_oi: in std_logic := '-';
133,12 → 131,12
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_adr_o: out std_logic_vector (s_adr_width-1 downto 0);
s_sel_o: out std_logic_vector ((s_dat_width/8)-1 downto 0);
s_dat_i: in std_logic_vector (s_dat_width-1 downto 0);
s_dat_o: out std_logic_vector (s_dat_width-1 downto 0);
s_cyc_o: out std_logic;
s_ack_i: in std_logic;
s_err_i: in std_logic := '-';
148,13 → 146,13
);
end component;
begin
dn_sel: if (m_bus_width > s_bus_width) generate
dn_sel: if (m_dat_width > s_dat_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,
m_dat_width => m_dat_width,
m_adr_width => m_adr_width,
s_dat_width => s_dat_width,
s_adr_width => s_adr_width,
little_endien => little_endien
)
port map
184,13 → 182,13
s_stb_o => s_stb_o
);
end generate;
up_sel: if (m_bus_width < s_bus_width) generate
up_sel: if (m_dat_width < s_dat_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,
m_dat_width => m_dat_width,
m_adr_width => m_adr_width,
s_dat_width => s_dat_width,
s_adr_width => s_adr_width,
little_endien => little_endien
)
port map
220,7 → 218,7
s_stb_o => s_stb_o
);
end generate;
eq_sel: if (m_bus_width = s_bus_width) generate
eq_sel: if (m_dat_width = s_dat_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;
236,14 → 234,3
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/technology_altera.vhd
0,0 → 1,338
--
-- Technology mapping library. ALTERA edition.
--
-- (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.
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
library exemplar;
--use exemplar.exemplar_1164.all;
library synopsys;
--use synopsys.std_logic_arith.all;
 
package body technology is
function to_std_logic_vector(ARG: INTEGER; SIZE: INTEGER) return STD_LOGIC_VECTOR is
begin
return std_logic_arith.CONV_STD_LOGIC_VECTOR(arg,size);
end;
 
function to_integer(arg:std_logic_vector) return integer is
begin
return CONV_INTEGER(arg);
end;
 
-- function "+"(op_l, op_r: std_logic_vector) return std_logic_vector is
-- begin
-- return exemplar_1164."+"(op_l, op_r);
-- end;
--
-- function "-"(op_l, op_r: std_logic_vector) return std_logic_vector is
-- begin
-- return exemplar_1164."-"(op_l, op_r);
-- end;
--
-- function add_one(inp : std_logic_vector) return std_logic_vector is
-- variable one: std_logic_vector(inp'RANGE) := (others => '0');
-- begin
-- one(0) := '1';
-- return exemplar_1164."+"(inp,one);
-- end;
--
-- function sub_one(inp : std_logic_vector) return std_logic_vector is
-- variable minus_one: std_logic_vector(inp'RANGE) := (others => '1');
-- begin
-- return exemplar_1164."+"(inp,minus_one);
-- end;
 
function is_zero(inp : std_logic_vector) return boolean is
variable zero: std_logic_vector(inp'RANGE) := (others => '0');
begin
return (inp = zero);
end;
 
function sl(l: std_logic_vector; r: integer) return std_logic_vector is
begin
return exemplar_1164.sl(l,r);
end;
 
function sr(l: std_logic_vector; r: integer) return std_logic_vector is
begin
return sl(l,-r);
end function;
 
function max2(a : integer; b: integer) return integer is
begin
if (a > b) then return a; end if;
return b;
end;
 
function min2(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 < 65536) then return 15; end if;
return 16;
end;
 
function bus_resize2adr_bits(in_bus : integer; out_bus: integer) return integer is
begin
if (in_bus = out_bus) then return 0; end if;
if (in_bus < out_bus) then return -log2(out_bus/in_bus); end if;
if (in_bus > out_bus) then return log2(in_bus/out_bus); end if;
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 <= 65536) 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 := to_std_logic_vector(b,a'HIGH+1);
return (a = b_s);
end;
 
end package body technology;
 
library IEEE;
use IEEE.std_logic_1164.all;
 
library altera;
use altera.maxplus2.all;
library alt_vtl;
use alt_vtl.all;
 
architecture altera of d_ff is
signal clrn,prn: std_logic;
begin
clrn <= not clr;
prn <= not pre;
ff: dffe port map (
D => d,
CLK => clk,
ENA => ena,
CLRN => clrn,
PRN => prn,
Q => q
);
end altera;
 
library ieee;
use ieee.std_logic_1164.all;
library wb_tk;
use wb_tk.technology.all;
library lpm;
use lpm.all;
 
-- GENERIC usage
-------------------
-- default_out : Not used in altera implementation
-- default_content : Not used in altera implementation
-- adr_width : Correctly used
-- dat_width : Correctly used
-- async_read : Correctly used
architecture altera of dpmem is
signal wren, rden: std_logic;
 
COMPONENT lpm_ram_dp
generic (LPM_WIDTH : positive;
LPM_WIDTHAD : positive;
LPM_NUMWORDS : natural := 0;
LPM_INDATA : string := "REGISTERED";
LPM_OUTDATA : string := "REGISTERED";
LPM_RDADDRESS_CONTROL : string := "REGISTERED";
LPM_WRADDRESS_CONTROL : string := "REGISTERED";
LPM_FILE : string := "UNUSED";
LPM_TYPE : string := "LPM_RAM_DP";
LPM_HINT : string := "UNUSED"
);
port (RDCLOCK : in std_logic := '0';
RDCLKEN : in std_logic := '1';
RDADDRESS : in std_logic_vector(LPM_WIDTHad-1 downto 0);
RDEN : in std_logic := '1';
DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
WRADDRESS : in std_logic_vector(LPM_WIDTHad-1 downto 0);
WREN : in std_logic;
WRCLOCK : in std_logic := '0';
WRCLKEN : in std_logic := '1';
Q : out std_logic_vector(LPM_WIDTH-1 downto 0)
);
END COMPONENT;
begin
wren <= w_we_i and w_stb_i;
rden <= not r_we_i and r_stb_i;
 
w_ack_o <= '1'; -- 0-wait-state for writes
r_ack_o <= '1'; -- 0-wait-state for reads
sync_gen: if (not async_read) generate
mem_core: lpm_ram_dp
GENERIC MAP (
lpm_width => dat_width,
lpm_widthad => adr_width,
lpm_indata => "REGISTERED",
lpm_wraddress_control => "REGISTERED",
lpm_rdaddress_control => "REGISTERED",
lpm_outdata => "UNREGISTERED",
lpm_hint => "USE_EAB=ON"
)
PORT MAP (
rdclock => r_clk_i,
wren => wren,
wrclock => w_clk_i,
q => r_dat_o,
rden => rden,
data => w_dat_i,
rdaddress => r_adr_i,
wraddress => w_adr_i
);
end generate;
async_gen: if (async_read) generate
mem_core: lpm_ram_dp
GENERIC MAP (
lpm_width => dat_width,
lpm_widthad => adr_width,
lpm_indata => "REGISTERED",
lpm_wraddress_control => "REGISTERED",
lpm_rdaddress_control => "UNREGISTERED",
lpm_outdata => "UNREGISTERED",
lpm_hint => "USE_EAB=ON"
)
PORT MAP (
rdclock => r_clk_i,
wren => wren,
wrclock => w_clk_i,
q => r_dat_o,
rden => rden,
data => w_dat_i,
rdaddress => r_adr_i,
wraddress => w_adr_i
);
end generate;
end altera;
 
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.all;
library wb_tk;
use wb_tk.technology.all;
 
architecture altera of fifo is
-- One additional bit is added to detect over and under-flow
signal w_adr : std_logic_vector(adr_width downto 0); -- internal write address
signal r_adr : std_logic_vector(adr_width downto 0); -- internal read address
begin
read_proc : process (r_clk_i, reset)
begin
if reset = '1' then
r_adr <= (others => '0');
elsif r_clk_i'event and r_clk_i = '1' then
if (r_stb_i = '1' and r_we_i = '0') then
r_adr <= r_adr+"1";
end if;
end if;
end process read_proc;
 
write_proc : process (w_clk_i, reset)
begin
if reset = '1' then
w_adr <= (others => '0');
elsif w_clk_i'event and w_clk_i = '1' then
if (w_stb_i = '1' and w_we_i = '1') then
w_adr <= w_adr+"1";
end if;
end if;
end process write_proc;
 
empty_o <= '1' when r_adr = w_adr else '0';
full_o <= '1' when (w_adr(adr_width-1 downto 0) = r_adr(adr_width-1 downto 0)) and (w_adr(adr_width) /= r_adr(adr_width)) else '0';
used_o <= w_adr - r_adr;
 
mem_core: dpmem
generic map (default_out,default_content,adr_width,dat_width,async_read)
port map (
-- signals for the read port
r_clk_i => r_clk_i,
r_stb_i => r_stb_i,
r_we_i => r_we_i,
r_adr_i => r_adr(adr_width-1 downto 0),
r_dat_o => r_dat_o,
r_ack_o => r_ack_o,
-- signals for the write port
w_clk_i => w_clk_i,
w_stb_i => w_stb_i,
w_we_i => w_we_i,
w_adr_i => w_adr(adr_width-1 downto 0),
w_dat_i => w_dat_i,
w_ack_o => w_ack_o
);
end altera;
 
library ieee;
use ieee.std_logic_1164.all;
library wb_tk;
use wb_tk.technology.all;
 
architecture altera of spmem is
signal r_ack: std_logic;
signal w_ack: std_logic;
begin
mem_core: dpmem generic map (default_out,default_content,adr_width,dat_width,async_read)
port map(
-- Signals for the read port
clk_i,
stb_i,
we_i,
adr_i,
dat_o,
r_ack,
-- Signals for the write port
clk_i,
stb_i,
we_i,
adr_i,
dat_i,
w_ack
);
ack_o <= '1';
end altera;
/trunk/technology_xilinx.vhd
0,0 → 1,262
--
-- Technology mapping library. XILINX edition.
--
-- (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.
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
--library xul;
 
package body technology is
function to_std_logic_vector(ARG: INTEGER; SIZE: INTEGER) return STD_LOGIC_VECTOR is
variable RetVal: std_logic_vector(size-1 downto 0) := (others => '0');
variable L_Arg: integer;
begin
-- return ul_utils.int_2_std_logic_vector(ARG,SIZE);
L_Arg := ARG;
if (L_Arg < 0) then L_Arg := -L_Arg; end if;
for i in 0 to SIZE-1 loop
if (L_Arg mod 2) = 1 then
RetVal(i) := '1';
end if;
L_Arg := L_Arg/2;
end loop;
-- Compute two's complement if arg was negative
if (ARG < 0) then
RetVal := not RetVal;
RetVal := RetVal+"1";
end if;
return RetVal;
end;
 
function to_integer(arg:std_logic_vector) return integer is
begin
return CONV_INTEGER(arg);
end;
 
-- function add_one(inp : std_logic_vector) return std_logic_vector is
-- begin
-- return inp+"1";
-- end;
--
-- function sub_one(inp : std_logic_vector) return std_logic_vector is
-- variable minus_one: std_logic_vector(inp'RANGE) := (others => '1');
-- begin
-- return inp+minus_one;
-- end;
 
function is_zero(inp : std_logic_vector) return boolean is
variable zero: std_logic_vector(inp'RANGE) := (others => '0');
begin
return (inp = zero);
end;
 
function sl(l: std_logic_vector; r: integer) return std_logic_vector is
variable RetVal : std_logic_vector (l'length-1 downto 0) ;
variable LL: std_logic_vector(l'length-1 downto 0) := l;
begin
RetVal := (others => '0');
if (ABS(r) < l'length) then
if (r >= 0) then
RetVal(l'length-1 downto r) := ll(l'length-1-r downto 0);
else -- (r < 0)
RetVal(l'length-1+r downto 0) := ll(l'length-1 downto -r);
end if ;
end if;
return RetVal ;
end sl ;
 
function sr(l: std_logic_vector; r: integer) return std_logic_vector is
begin
return sl(l,-r);
end sr;
 
function max2(a : integer; b: integer) return integer is
begin
if (a > b) then return a; end if;
return b;
end max2;
 
function min2(a : integer; b: integer) return integer is
begin
if (a < b) then return a; end if;
return b;
end min2;
 
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 < 65536) then return 15; end if;
return 16;
end log2;
 
function bus_resize2adr_bits(in_bus : integer; out_bus: integer) return integer is
begin
if (in_bus = out_bus) then return 0; end if;
if (in_bus < out_bus) then return -log2(out_bus/in_bus); end if;
if (in_bus > out_bus) then return log2(in_bus/out_bus); end if;
end bus_resize2adr_bits;
 
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 <= 65536) then return 16; end if;
return 17;
end size2bits;
 
function equ(a : std_logic_vector; b : integer) return boolean is
variable b_s : std_logic_vector(a'RANGE);
begin
b_s := to_std_logic_vector(b,a'HIGH+1);
return (a = b_s);
end equ;
 
end technology;
 
library IEEE;
use IEEE.std_logic_1164.all;
 
library unisim;
use unisim.vcomponents.all;
 
architecture xilinx of d_ff is
-- signal clrn,pren: std_logic;
begin
-- clrn <= not clr;
-- pren <= not pre;
ff: FDCPE port map (
D => d,
C => clk,
CE => ena,
CLR => clr,
PRE => pre,
Q => q
);
end xilinx;
 
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.all;
library wb_tk;
use wb_tk.technology.all;
 
architecture xilinx of fifo is
-- One additional bit is added to detect over and under-flow
signal w_adr : std_logic_vector(adr_width downto 0); -- internal write address
signal r_adr : std_logic_vector(adr_width downto 0); -- internal read address
signal dont_care : std_logic_vector(dat_width downto 0) := (others => '-');
signal w_ack, r_ack: std_logic;
begin
dont_care <= (others => '-');
read_proc : process (r_clk_i, reset)
begin
if reset = '1' then
r_adr <= (others => '0');
elsif r_clk_i'event and r_clk_i = '1' then
if (r_stb_i = '1' and r_we_i = '0' and r_ack = '1') then
r_adr <= r_adr+"1";
end if;
end if;
end process read_proc;
 
write_proc : process (w_clk_i, reset)
begin
if reset = '1' then
w_adr <= (others => '0');
elsif w_clk_i'event and w_clk_i = '1' then
if (w_stb_i = '1' and w_we_i = '1' and w_ack = '1') then
w_adr <= w_adr+"1";
end if;
end if;
end process write_proc;
 
empty_o <= '1' when r_adr = w_adr else '0';
full_o <= '1' when (w_adr(adr_width-1 downto 0) = r_adr(adr_width-1 downto 0)) and (w_adr(adr_width) /= r_adr(adr_width)) else '0';
used_o <= w_adr - r_adr;
 
mem_core: dpmem
generic map (default_out,default_content,adr_width,dat_width,async_read)
port map (
a_clk_i => r_clk_i,
a_stb_i => r_stb_i,
a_we_i => r_we_i,
a_adr_i => r_adr(adr_width-1 downto 0),
a_dat_i => dont_care,
a_dat_o => r_dat_o,
a_ack_o => r_ack,
 
b_clk_i => w_clk_i,
b_stb_i => w_stb_i,
b_we_i => w_we_i,
b_adr_i => w_adr(adr_width-1 downto 0),
b_dat_i => w_dat_i,
-- b_dat_o
b_ack_o => w_ack
);
end xilinx;
 
library ieee;
use ieee.std_logic_1164.all;
library wb_tk;
use wb_tk.technology.all;
 
architecture xilinx of spmem is
signal w_ack, r_ack: std_logic;
signal dont_care : std_logic_vector(dat_width downto 0) := (others => '-');
begin
dont_care <= (others => '-');
 
mem_core: dpmem generic map (default_out,default_content,adr_width,dat_width,async_read)
port map (
a_clk_i => clk_i,
a_stb_i => stb_i,
a_we_i => we_i,
a_adr_i => adr_i,
a_dat_i => dont_care,
a_dat_o => dat_o,
a_ack_o => r_ack,
 
b_clk_i => clk_i,
b_stb_i => stb_i,
b_we_i => we_i,
b_adr_i => adr_i,
b_dat_i => dat_i,
-- b_dat_o
b_ack_o => w_ack
);
ack_o <= ('0' and not stb_i) or (r_ack and (stb_i and not we_i)) or (w_ack and (stb_i and we_i));
end xilinx;
/trunk/wb_ram.vhd
22,17 → 22,17
 
entity wb_ram is
generic (
data_width: positive := 8;
addr_width: positive := 10
dat_width: positive := 8;
adr_width: positive := 10
);
port (
clk_i: in std_logic;
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);
adr_i: in std_logic_vector (adr_width-1 downto 0);
-- sel_i: in std_logic_vector ((dat_width/8)-1 downto 0) := (others => '1');
dat_i: in std_logic_vector (dat_width-1 downto 0);
dat_oi: in std_logic_vector (dat_width-1 downto 0) := (others => '-');
dat_o: out std_logic_vector (dat_width-1 downto 0);
cyc_i: in std_logic;
ack_o: out std_logic;
ack_oi: in std_logic := '-';
46,40 → 46,32
end wb_ram;
 
architecture wb_ram of wb_ram is
component ram
generic (
data_width : positive;
addr_width : positive
signal mem_stb: std_logic;
signal mem_dat_o: std_logic_vector(dat_width-1 downto 0);
signal mem_ack: std_logic;
begin
mem_stb <= stb_i and cyc_i;
tech_ram: spmem
generic map (
default_out => 'X',
default_content => '0',
adr_width => adr_width,
dat_width => dat_width,
async_read => true
)
port map (
stb_i => mem_stb,
clk_i => clk_i,
-- reset => '0',
adr_i => adr_i,
dat_i => dat_i,
dat_o => mem_dat_o,
we_i => we_i
);
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));
 
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 <= (mem_ack and stb_i and cyc_i) or (ack_oi and not (stb_i and cyc_i));
end wb_ram;
 
/trunk/wb_test.vhd
13,9 → 13,10
 
library IEEE;
use IEEE.std_logic_1164.all;
library synopsys;
use synopsys.std_logic_arith.all;
 
library wb_tk;
use wb_tk.technology.all;
 
package wb_test is
procedure wr_chk_val(
signal clk_i: in STD_LOGIC;
119,159 → 120,159
 
 
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_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 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;
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 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 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 wr_chk_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
284,11 → 285,11
constant addr: in integer;
constant data: in STD_LOGIC_VECTOR
) is
variable sadr: std_logic_vector(adr_i'RANGE);
variable sadr: std_logic_vector(adr_i'RANGE);
begin
sadr := CONV_STD_LOGIC_VECTOR(addr,adr_i'HIGH+1);
wr_chk_val(clk_i,adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,sadr,data);
end procedure;
sadr := to_std_logic_vector(addr,adr_i'HIGH+1);
wr_chk_val(clk_i,adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,sadr,data);
end;
procedure wr_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
301,11 → 302,11
constant addr: in integer;
constant data: in STD_LOGIC_VECTOR
) is
variable sadr: std_logic_vector(adr_i'RANGE);
variable sadr: std_logic_vector(adr_i'RANGE);
begin
sadr := CONV_STD_LOGIC_VECTOR(addr,adr_i'HIGH+1);
wr_val(clk_i,adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,sadr,data);
end procedure;
sadr := to_std_logic_vector(addr,adr_i'HIGH+1);
wr_val(clk_i,adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,sadr,data);
end;
procedure rd_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
318,11 → 319,11
constant addr: in integer;
variable data: out STD_LOGIC_VECTOR
) is
variable sadr: std_logic_vector(adr_i'RANGE);
variable sadr: std_logic_vector(adr_i'RANGE);
begin
sadr := CONV_STD_LOGIC_VECTOR(addr,adr_i'HIGH+1);
rd_val(clk_i,adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,sadr,data);
end procedure;
sadr := to_std_logic_vector(addr,adr_i'HIGH+1);
rd_val(clk_i,adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,sadr,data);
end;
procedure chk_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
335,11 → 336,11
constant addr: in integer;
constant data: in STD_LOGIC_VECTOR
) is
variable sadr: std_logic_vector(adr_i'RANGE);
variable sadr: std_logic_vector(adr_i'RANGE);
begin
sadr := CONV_STD_LOGIC_VECTOR(addr,adr_i'HIGH+1);
chk_val(clk_i,adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,sadr,data);
end procedure;
end package body wb_test;
sadr := to_std_logic_vector(addr,adr_i'HIGH+1);
chk_val(clk_i,adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,sadr,data);
end;
 
end wb_test;
 
/trunk/technology.vhd
1,5 → 1,5
--
-- Technology mapping library. ALTERA edition.
-- Technology mapping library. Interface.
--
-- (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.
7,425 → 7,210
 
library IEEE;
use IEEE.std_logic_1164.all;
library exemplar;
use exemplar.exemplar_1164.all;
 
package technology is
function add_one(inp : std_logic_vector) return std_logic_vector;
-- originaly in synopsys. Naming convention is changed to resolve potential name conflict.
function to_std_logic_vector(ARG: INTEGER; SIZE: INTEGER) return STD_LOGIC_VECTOR;
function to_integer(arg:std_logic_vector) return integer;
 
-- function add_one(inp : std_logic_vector) return std_logic_vector;
-- function sub_one(inp : std_logic_vector) return std_logic_vector;
function is_zero(inp : std_logic_vector) return boolean;
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 sl(l: std_logic_vector; r: integer) return std_logic_vector;
function sr(l: std_logic_vector; r: integer) return std_logic_vector;
-- function "+"(op_l, op_r: std_logic_vector) return std_logic_vector;
-- function "-"(op_l, op_r: std_logic_vector) return std_logic_vector;
function log2(inp : integer) return integer;
function bus_resize2adr_bits(in_bus : integer; out_bus: integer) return integer;
function size2bits(inp : integer) return integer;
function max(a : integer; b: integer) return integer;
function max2(a : integer; b: integer) return integer;
function min2(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;
clk: in STD_LOGIC;
ena: in STD_LOGIC := '1';
clr: in STD_LOGIC := '0';
pre: in STD_LOGIC := '0';
q : out STD_LOGIC
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;
component fifo is
generic (fifo_width : positive;
used_width : positive;
fifo_depth : positive
component spmem
generic (
default_out : std_logic := 'X'; -- Default output
default_content : std_logic := '0'; -- Simple initialization data
adr_width : integer := 3;
dat_width : integer := 8;
async_read : boolean := true
);
port (d_in : in std_logic_vector(fifo_width-1 downto 0);
clk : in std_logic;
wr : in std_logic;
rd : in std_logic;
a_clr : in std_logic := '0';
s_clr : in std_logic := '0';
d_out : out std_logic_vector(fifo_width-1 downto 0);
used : out std_logic_vector(used_width-1 downto 0);
full : out std_logic;
empty : out std_logic
port (
stb_i : std_logic; -- chip select
clk_i : in std_logic; -- write clock
adr_i : in std_logic_vector(adr_width -1 downto 0); -- Address
dat_i : in std_logic_vector(dat_width -1 downto 0); -- input data
dat_o : out std_logic_vector(dat_width -1 downto 0); -- Output Data
we_i : in std_logic; -- Read Write Enable
ack_o : out std_logic -- Ready output
);
end component;
end technology;
library IEEE;
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
begin
return exemplar_1164."+"(op_l, op_r);
end;
component dpmem
generic (
default_out : std_logic := 'X'; -- Default output
default_content : std_logic := '0'; -- Simple initialization data
adr_width : integer := 3;
dat_width : integer := 8;
async_read : boolean := true
);
port (
-- Signals for the port A
a_clk_i : in std_logic; -- Read clock
a_stb_i : in std_logic; -- Read port select
a_we_i : in std_logic; -- Read port Write enable
a_adr_i : in std_logic_vector(adr_width -1 downto 0); -- Read Address
a_dat_i : in std_logic_vector(dat_width -1 downto 0); -- Input data
a_dat_o : out std_logic_vector(dat_width -1 downto 0); -- Output data
a_ack_o : out std_logic; -- Read ready output
function add_one(inp : std_logic_vector) return std_logic_vector is
variable one: std_logic_vector(inp'RANGE) := (others => '0');
begin
one(0) := '1';
return exemplar_1164."+"(inp,one);
end;
-- Signals for the port B
b_clk_i : in std_logic; -- Write clock
b_stb_i : in std_logic; -- Write port select
b_we_i : in std_logic; -- Write Enable
b_adr_i : in std_logic_vector(adr_width -1 downto 0); -- Write Address
b_dat_i : in std_logic_vector(dat_width -1 downto 0); -- Input data
b_dat_o : out std_logic_vector(dat_width -1 downto 0); -- Output data
b_ack_o : out std_logic -- Write ready output
);
end component;
component fifo
generic (
default_out : std_logic := 'X'; -- Default output
default_content : std_logic := '0'; -- Simple initialization data
adr_width : integer := 3;
dat_width : integer := 8;
async_read : boolean := true -- Controls memory only. For FIFO logic clock is still needed.
);
port (
reset : in std_logic; -- System reset
 
function is_zero(inp : std_logic_vector) return boolean is
variable zero: std_logic_vector(inp'RANGE) := (others => '0');
begin
return (inp = zero);
end;
r_clk_i : in std_logic; -- Read clock
r_stb_i : in std_logic; -- Read port select
r_we_i : in std_logic := '0'; -- Read port Write enable (should be '0')
r_dat_o : out std_logic_vector(dat_width-1 downto 0); -- Data out
r_ack_o : out std_logic; -- Read ready output
 
function sl(l: std_logic_vector; r: integer) return std_logic_vector is
begin
return exemplar_1164.sl(l,r);
end;
-- procedure inc(data : inout std_logic_vector) is
-- 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 min2(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;
w_clk_i : in std_logic; -- Write clock
w_stb_i : in std_logic; -- Write port select
w_we_i : in std_logic := '1'; -- Write port write enable
w_dat_i : in std_logic_vector(dat_width-1 downto 0); -- Data in
w_ack_o : out std_logic; -- Write ready output
 
function bus_resize2adr_bits(in_bus : integer; out_bus: integer) return integer is
begin
if (in_bus = out_bus) then return 0; end if;
if (in_bus < out_bus) then return -log2(out_bus/in_bus); end if;
if (in_bus > out_bus) then return log2(in_bus/out_bus); end if;
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;
 
library IEEE;
use IEEE.std_logic_1164.all;
 
library exemplar;
use exemplar.exemplar_1164.all;
 
library lpm;
use lpm.all;
 
entity fifo is
generic (fifo_width : positive;
used_width : positive;
fifo_depth : positive
);
port (d_in : in std_logic_vector(fifo_width-1 downto 0);
clk : in std_logic;
wr : in std_logic;
rd : in std_logic;
a_clr : in std_logic := '0';
s_clr : in std_logic := '0';
d_out : out std_logic_vector(fifo_width-1 downto 0);
used : out std_logic_vector(used_width-1 downto 0);
full : out std_logic;
empty : out std_logic
);
end fifo;
 
architecture altera of fifo is
component lpm_fifo
generic (LPM_WIDTH : positive;
LPM_WIDTHU : positive;
LPM_NUMWORDS : positive;
LPM_SHOWAHEAD : string := "OFF";
LPM_TYPE : string := "LPM_FIFO";
LPM_HINT : string := "UNUSED");
port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
CLOCK : in std_logic;
WRREQ : in std_logic;
RDREQ : in std_logic;
ACLR : in std_logic;
SCLR : in std_logic;
Q : out std_logic_vector(LPM_WIDTH-1 downto 0);
USEDW : out std_logic_vector(LPM_WIDTHU-1 downto 0);
FULL : out std_logic;
EMPTY : out std_logic);
full_o : out std_logic; -- Full Flag (combinational)
empty_o : out std_logic; -- Empty flag (combinational)
used_o : out std_logic_vector(adr_width downto 0) -- number of data in the fifo (combinational)
);
end component;
begin
altera_fifo: lpm_fifo
generic map (
LPM_WIDTH => fifo_width,
LPM_WIDTHU => used_width,
LPM_NUMWORDS => fifo_depth,
LPM_SHOWAHEAD => "OFF",
LPM_TYPE => "LPM_FIFO",
LPM_HINT => "UNUSED"
)
port map (
DATA => d_in,
CLOCK => clk,
WRREQ => wr,
RDREQ => rd,
ACLR => a_clr,
SCLR => s_clr,
Q => d_out,
USEDW => used,
FULL => full,
EMPTY => empty
);
end altera;
end technology;
 
library IEEE;
use IEEE.std_logic_1164.all;
 
library exemplar;
use exemplar.exemplar_1164.all;
 
library lpm;
use lpm.all;
 
entity ram is
entity spmem is
generic (
data_width : positive;
addr_width : positive
default_out : std_logic := 'X'; -- Default output
default_content : std_logic := '0'; -- Simple initialization data
adr_width : integer := 3;
dat_width : integer := 8;
async_read : boolean := true
);
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)
stb_i : std_logic; -- chip select
clk_i : in std_logic; -- write clock
adr_i : in std_logic_vector(adr_width -1 downto 0); -- Address
dat_i : in std_logic_vector(dat_width -1 downto 0); -- input data
dat_o : out std_logic_vector(dat_width -1 downto 0); -- Output Data
we_i : in std_logic; -- Read Write Enable
ack_o : out std_logic -- Ready output
);
end ram;
end spmem;
 
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',
library IEEE;
use IEEE.std_logic_1164.all;
 
wrclock => clk,
wrclken => '1',
wraddress => addr,
data => d_in,
wren => we
);
end altera;
entity dpmem is
generic (
default_out : std_logic := 'X'; -- Default output
default_content : std_logic := '0'; -- Simple initialization data
adr_width : integer := 3;
dat_width : integer := 8;
async_read : boolean := true
);
port (
-- Signals for the port A
a_clk_i : in std_logic; -- Read clock
a_stb_i : in std_logic; -- Read port select
a_we_i : in std_logic; -- Read port Write enable
a_adr_i : in std_logic_vector(adr_width -1 downto 0); -- Read Address
a_dat_i : in std_logic_vector(dat_width -1 downto 0); -- Input data
a_dat_o : out std_logic_vector(dat_width -1 downto 0); -- Output data
a_ack_o : out std_logic; -- Read ready output
 
-- Signals for the port B
b_clk_i : in std_logic; -- Write clock
b_stb_i : in std_logic; -- Write port select
b_we_i : in std_logic; -- Write Enable
b_adr_i : in std_logic_vector(adr_width -1 downto 0); -- Write Address
b_dat_i : in std_logic_vector(dat_width -1 downto 0); -- Input data
b_dat_o : out std_logic_vector(dat_width -1 downto 0); -- Output data
b_ack_o : out std_logic -- Write ready output
);
end dpmem;
 
 
 
 
library IEEE;
use IEEE.std_logic_1164.all;
 
library exemplar;
use exemplar.exemplar_1164.all;
 
library lpm;
use lpm.all;
 
entity dpram is
entity fifo is
generic (
data_width : positive;
addr_width : positive
default_out : std_logic := 'X'; -- Default output
default_content : std_logic := '0'; -- Simple initialization data
adr_width : integer := 3;
dat_width : integer := 8;
async_read : boolean := true -- Controls memory only. For FIFO logic clock is still needed.
);
port (
clk : in std_logic;
reset : in std_logic; -- System reset
 
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);
r_clk_i : in std_logic; -- Read clock
r_stb_i : in std_logic; -- Read port select
r_we_i : in std_logic := '0'; -- Read port Write enable (should be '0')
r_dat_o : out std_logic_vector(dat_width-1 downto 0); -- Data out
r_ack_o : out std_logic; -- Read ready output
 
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)
w_clk_i : in std_logic; -- Write clock
w_stb_i : in std_logic; -- Write port select
w_we_i : in std_logic := '1'; -- Write port write enable
w_dat_i : in std_logic_vector(dat_width-1 downto 0); -- Data in
w_ack_o : out std_logic; -- Write ready output
 
full_o : out std_logic; -- Full Flag (combinational)
empty_o : out std_logic; -- Empty flag (combinational)
used_o : out std_logic_vector(adr_width downto 0) -- number of data in the fifo (combinational)
);
end dpram;
end fifo;
 
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;
 
entity d_ff is
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
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 d_ff;
 
architecture altera of d_ff is
component dffe
port ( D : in STD_LOGIC;
CLK: in STD_LOGIC;
ENA: in STD_LOGIC;
CLRN: in STD_LOGIC;
PRN: in STD_LOGIC;
Q : out STD_LOGIC);
end component;
signal clrn,prn: std_logic;
begin
clrn <= not clr;
prn <= not pre;
ff: dffe port map (
D => d,
CLK => clk,
ENA => ena,
CLRN => clrn,
PRN => prn,
Q => q
);
end altera;
 
-- Sythetizer library. Contains STD_LOGIC arithmetics
 
/trunk/technology_behav.vhd
0,0 → 1,326
--
-- Technology mapping library. Behavioral edition.
-- Contains technology primitive implementations in a behavioral,
-- thus not 100% synthetizable form. Use this library to functional verification
-- and as a specification of thecnology primitives when porting to a particular
-- technology.
--
-- (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.
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
 
package body technology is
function to_std_logic_vector(ARG: INTEGER; SIZE: INTEGER) return STD_LOGIC_VECTOR is
variable RetVal: std_logic_vector(size-1 downto 0) := (others => '0');
variable L_Arg: integer;
begin
L_Arg := ARG;
if (L_Arg < 0) then L_Arg := -L_Arg; end if;
for i in 0 to SIZE-1 loop
if (L_Arg mod 2) = 1 then
RetVal(i) := '1';
end if;
L_Arg := L_Arg/2;
end loop;
-- Compute two's complement if arg was negative
if (ARG < 0) then
RetVal := not RetVal;
RetVal := RetVal+"1";
end if;
return RetVal;
end;
function to_integer(arg:std_logic_vector) return integer is
begin
return CONV_INTEGER(arg);
end;
 
 
-- function "+"(op_l, op_r: std_logic_vector) return std_logic_vector is
-- begin
-- return to_std_logic_vector(to_integer(op_l)+to_integer(op_r),max2(op_l'length, op_r'length));
-- end;
--
-- function "-"(op_l, op_r: std_logic_vector) return std_logic_vector is
-- begin
-- return to_std_logic_vector(to_integer(op_l)-to_integer(op_r),max2(op_l'length, op_r'length));
-- end;
--
-- function add_one(inp : std_logic_vector) return std_logic_vector is
-- begin
-- return to_std_logic_vector(to_integer(inp)+1,inp'length);
-- end;
--
-- function sub_one(inp : std_logic_vector) return std_logic_vector is
-- begin
-- return to_std_logic_vector(to_integer(inp)-1,inp'length);
-- end;
 
function is_zero(inp : std_logic_vector) return boolean is
variable zero: std_logic_vector(inp'RANGE) := (others => '0');
begin
-- return std_logic_unsigned."="(inp,zero);
return inp = zero;
end;
 
function sl(l: std_logic_vector; r: integer) return std_logic_vector is
variable RetVal : std_logic_vector (l'length-1 downto 0) ;
variable LL: std_logic_vector(l'length-1 downto 0) := l;
begin
RetVal := (others => '0');
if (ABS(r) < l'length) then
if (r >= 0) then
RetVal(l'length-1 downto r) := ll(l'length-1-r downto 0);
else -- (r < 0)
RetVal(l'length-1+r downto 0) := ll(l'length-1 downto -r);
end if ;
end if;
return RetVal ;
end sl ;
 
function sr(l: std_logic_vector; r: integer) return std_logic_vector is
begin
return sl(l,-r);
end sr;
 
function max2(a : integer; b: integer) return integer is
begin
if (a > b) then return a; end if;
return b;
end;
 
function min2(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 < 65536) then return 15; end if;
return 16;
end;
 
function bus_resize2adr_bits(in_bus : integer; out_bus: integer) return integer is
begin
if (in_bus = out_bus) then return 0; end if;
if (in_bus < out_bus) then return -log2(out_bus/in_bus); end if;
if (in_bus > out_bus) then return log2(in_bus/out_bus); end if;
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 <= 65536) 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 := to_std_logic_vector(b,a'HIGH+1);
return a = b_s;
end;
 
end technology;
 
library IEEE;
use IEEE.std_logic_1164.all;
 
architecture behavioral of d_ff is
signal l_q: STD_LOGIC := 'X';
begin
d_ff: process
variable clrpre: std_logic_vector(1 downto 0);
begin
wait until clk'EVENT or clr'EVENT or pre'EVENT;
clrpre := clr & pre;
case clrpre is
when "10" =>
l_q <= '0';
when "01" =>
l_q <= '1';
when "11" =>
--assert true report "Set and preset cannot be active at the same time" severity error;
l_q <= 'X';
when "00" =>
if (clk'EVENT) then
if (clk = '1') then
if (ena = '1') then
l_q <= d;
else
if (ena /= '0') then
l_q <= 'X';
end if;
end if;
end if;
end if;
when others =>
l_q <= 'X';
end case;
end process;
q <= l_q;
 
end behavioral;
 
library ieee;
use ieee.std_logic_1164.all;
library wb_tk;
use wb_tk.technology.all;
 
architecture behavioral of dpmem is
type data_array is array (integer range <>) of std_logic_vector(dat_width-1 downto 0); -- Memory Type
signal data : data_array(0 to (2** adr_width-1) ) := (others => (others => default_content)); -- Local data
signal r_clk: std_logic;
signal l_r_ack: std_logic := '0';
begin
async_clk: if (async_read) generate
r_dat_o <= data(to_integer(r_adr_i)) when (r_stb_i = '1' and r_we_i = '0') else (others => default_out);
r_ack_o <= '1'; -- async read is 0 wait-state
end generate;
sync_clk: if (not async_read) generate
ReProc : process (r_clk_i)
begin
if r_clk_i'event and r_clk_i = '1' then
if r_stb_i = '1' and r_we_i = '0' then
r_dat_o <= data(to_integer(r_adr_i));
l_r_ack <= not l_r_ack;
else
r_dat_o <= (others => default_out);
l_r_ack <= '0';
end if;
end if;
end process ReProc;
r_ack_o <= l_r_ack;
end generate;
 
w_ack_o <= '1'; -- write is allways 0 wait-state
WrProc : process (w_clk_i)
begin
if w_clk_i'event and w_clk_i = '1' then
if w_stb_i = '1' and w_we_i = '1' then
data(to_integer(w_adr_i)) <= w_dat_i;
end if;
end if;
end process WrProc;
end behavioral;
 
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.all;
library wb_tk;
use wb_tk.technology.all;
 
architecture behavioral of fifo is
-- One additional bit is added to detect over and under-flow
signal w_adr : std_logic_vector(adr_width downto 0); -- internal write address
signal r_adr : std_logic_vector(adr_width downto 0); -- internal read address
signal w_ack, r_ack: std_logic;
begin
read_proc : process (r_clk_i, reset)
begin
if reset = '1' then
r_adr <= (others => '0');
elsif r_clk_i'event and r_clk_i = '1' then
if (r_stb_i = '1' and r_we_i = '0' and r_ack = '1') then
r_adr <= r_adr+"1";
end if;
end if;
end process read_proc;
 
write_proc : process (w_clk_i, reset)
begin
if reset = '1' then
w_adr <= (others => '0');
elsif w_clk_i'event and w_clk_i = '1' then
if (w_stb_i = '1' and w_we_i = '1' and w_ack = '1') then
w_adr <= w_adr+"1";
end if;
end if;
end process write_proc;
 
empty_o <= '1' when r_adr = w_adr else '0';
full_o <= '1' when (w_adr(adr_width-1 downto 0) = r_adr(adr_width-1 downto 0)) and (w_adr(adr_width) /= r_adr(adr_width)) else '0';
used_o <= w_adr - r_adr;
 
mem_core: dpmem
generic map (default_out,default_content,adr_width,dat_width,async_read)
port map (
-- signals for the read port
r_clk_i => r_clk_i,
r_stb_i => r_stb_i,
r_we_i => r_we_i,
r_adr_i => r_adr(adr_width-1 downto 0),
r_dat_o => r_dat_o,
r_ack_o => r_ack,
-- signals for the write port
w_clk_i => w_clk_i,
w_stb_i => w_stb_i,
w_we_i => w_we_i,
w_adr_i => w_adr(adr_width-1 downto 0),
w_dat_i => w_dat_i,
w_ack_o => w_ack
);
end behavioral;
 
library ieee;
use ieee.std_logic_1164.all;
library wb_tk;
use wb_tk.technology.all;
 
architecture behavioral of spmem is
signal w_ack, r_ack: std_logic;
begin
mem_core: dpmem generic map (default_out,default_content,adr_width,dat_width,async_read)
port map(
-- Signals for the read port
clk_i,
stb_i,
we_i,
adr_i,
dat_o,
r_ack,
-- Signals for the write port
clk_i,
stb_i,
we_i,
adr_i,
dat_i,
w_ack
);
ack_o <= ('0' and not stb_i) or (r_ack and (stb_i and not we_i)) or (w_ack and (stb_i and we_i));
end behavioral;
/trunk/wb_arbiter.vhd
24,7 → 24,7
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;
35,7 → 35,7
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;
54,7 → 54,7
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
66,16 → 66,16
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
 
sm: process
variable state: states;
begin
wait on a_cyc_i, b_cyc_i, priority, rst_i;
if (rst_i = '1') then
if (rst_i = '1') then
state := idle;
i_mux_signal <= priority;
else
118,8 → 118,8
end if;
e_state <= state;
end process;
signal_mux: process is
 
signal_mux: process
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,
153,35 → 153,37
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';
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;
 
signal one: std_logic := '1';
begin
one <= '1';
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',
d => one,
clk => aa_clk,
ena => aa_ena,
clr => aa_clr,
188,13 → 190,13
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',
d => one,
clk => ba_clk,
ena => ba_ena,
clr => ba_clr,
201,10 → 203,10
pre => ba_pre,
q => ba_s
);
 
i_mux_signal <= (priority and idle_s) or ba_s;
signal_mux: process is
 
signal_mux: process
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,
231,8 → 233,8
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
 
gen_e_state: process
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;
/trunk/wb_async_master.vhd
1,127 → 1,278
--
-- 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.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
-------------------------------------------------------------------------------
--
-- wb_async_master
--
-------------------------------------------------------------------------------
entity wb_async_master is
generic (
dat_width: positive := 16;
adr_width: positive := 20;
ab_rd_delay: positive := 1
);
port (
wb_clk_i: in std_logic;
wb_rst_i: in std_logic := '0';
 
library IEEE;
use IEEE.std_logic_1164.all;
-- interface to wb slave devices
wb_adr_o: out std_logic_vector (adr_width-1 downto 0);
wb_sel_o: out std_logic_vector ((dat_width/8)-1 downto 0);
wb_dat_i: in std_logic_vector (dat_width-1 downto 0);
wb_dat_o: out std_logic_vector (dat_width-1 downto 0);
wb_cyc_o: out std_logic;
wb_ack_i: in std_logic;
wb_err_i: in std_logic := '-';
wb_rty_i: in std_logic := '-';
wb_we_o: out std_logic;
wb_stb_o: out std_logic;
 
library wb_tk;
use wb_tk.technology.all;
-- interface to the asyncronous master device
ab_dat: inout std_logic_vector (dat_width-1 downto 0) := (others => 'Z');
ab_adr: in std_logic_vector (adr_width-1 downto 0) := (others => 'U');
ab_rd_n: in std_logic := '1';
ab_wr_n: in std_logic := '1';
ab_ce_n: in std_logic := '1';
ab_byteen_n: in std_logic_vector ((dat_width/8)-1 downto 0);
ab_wait_n: out std_logic; -- wait-state request 'open-drain' output
ab_waiths: out std_logic -- handshake-type totem-pole output
 
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;
architecture xilinx of wb_async_master is
constant ab_wr_delay: positive := 2;
-- delay lines for rd/wr edge detection
signal rd_delay_rst: std_logic;
signal rd_delay: std_logic_vector(ab_rd_delay downto 0);
signal wr_delay: std_logic_vector(ab_wr_delay downto 0);
-- one-cycle long pulses upon rd/wr edges
signal ab_wr_pulse: std_logic;
signal ab_rd_pulse: std_logic;
-- one-cycle long pulse to latch address for writes
signal ab_wr_latch_pulse: std_logic;
-- WB data input register
signal wb_dat_reg: std_logic_vector (dat_width-1 downto 0);
-- internal copies of WB signals for feedback
signal wb_cyc_l: std_logic;
signal wb_we_l: std_logic;
-- Comb. logic for active cycles
signal ab_rd: std_logic;
signal ab_wr: std_logic;
signal ab_active: std_logic;
-- internal copies of wait signals for feedback
signal ab_wait_n_rst: std_logic;
signal ab_wait_n_l: std_logic;
signal ab_waiths_l: std_logic;
signal ab_wait_n_l_delayed: std_logic;
signal ab_waiths_l_delayed: std_logic;
-- active when WB slave terminates the cycle (for any reason)
signal wb_ack: std_logic;
-- signals a scheduled or commencing posted write
signal write_in_progress: 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;
ab_rd <= (not ab_ce_n) and (not ab_rd_n) and ab_wr_n;
ab_wr <= (not ab_ce_n) and (not ab_wr_n) and ab_rd_n;
ab_active <= not ab_ce_n;
 
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;
wb_ack <= wb_cyc_l and (wb_ack_i or wb_err_i or wb_rty_i);
 
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;
write_in_progress_gen: process
begin
if (wb_rst_i = '1') then
write_in_progress <= '0';
end if;
wait until wb_clk_i'EVENT and wb_clk_i = '1';
if ab_wr = '0' and wr_delay(wr_delay'HIGH) = '1' then
write_in_progress <= '1';
end if;
if wb_ack = '1' then
write_in_progress <= '0';
end if;
end process;
 
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;
-- Registers addr/data lines.
reg_bus_lines: process
begin
if (wb_rst_i = '1') then
wb_adr_o <= (others => '-');
wb_sel_o <= (others => '-');
wb_dat_o <= (others => '-');
wb_dat_reg <= (others => '0');
end if;
wait until wb_clk_i'EVENT and wb_clk_i = '1';
-- Store and sycnronize data and address lines if no (posted) write
-- is in progress and there is an active asyncronous bus cycle.
-- We store addresses for reads at the same time we sample the data so setup and hold
-- times are the same.
if (ab_wr = '1' or ab_rd_pulse = '1') and (write_in_progress = '0' or wb_ack = '1') then
wb_adr_o <= ab_adr;
for i in wb_sel_o'RANGE loop
wb_sel_o(i) <= not ab_byteen_n(i);
end loop;
end if;
if (ab_wr = '1') and (write_in_progress = '0' or wb_ack = '1') then
wb_dat_o <= ab_dat;
end if;
 
-- en-register data input at the end of a read cycle
if wb_ack = '1' then
if wb_we_l = '0' then
-- read cycle completed, store the result
wb_dat_reg <= wb_dat_i;
end if;
end if;
end process;
 
-- Registers asycn bus control lines for sync edge detection.
async_bus_wr_ctrl : process(wb_rst_i,wb_clk_i)
begin
if (wb_rst_i = '1') then
wr_delay <= (others => '0');
-- end if;
-- Post-layout simulation shows glitches on the output that violates setup times.
-- Clock on the other edge to solve this issue
-- elsif wb_clk_i'EVENT and wb_clk_i = '1' then
elsif wb_clk_i'EVENT and wb_clk_i = '0' then
-- wait until wb_clk_i'EVENT and wb_clk_i = '1';
-- wait until wb_clk_i'EVENT and wb_clk_i = '0';
-- delayed signals will be used in edge-detection
for i in wr_delay'HIGH downto 1 loop
wr_delay(i) <= wr_delay(i-1);-- and ab_rd;
end loop;
wr_delay(0) <= ab_wr;
end if;
end process;
 
rd_delay_rst <= wb_rst_i or not ab_rd;
async_bus_rd_ctrl : process(rd_delay_rst,wb_clk_i)
begin
if (rd_delay_rst = '1') then
rd_delay <= (others => '0');
-- Post-layout simulation shows glitches on the output that violates setup times.
-- Clock on the other edge to solve this issue
-- elsif wb_clk_i'EVENT and wb_clk_i = '1' then
elsif wb_clk_i'EVENT and wb_clk_i = '0' then
-- a sync-reset shift-register to delay read signal
for i in rd_delay'HIGH downto 1 loop
rd_delay(i) <= rd_delay(i-1) and ab_rd;
end loop;
if (wb_cyc_l = '1') then
rd_delay(0) <= rd_delay(0);
else
rd_delay(0) <= ab_rd and not write_in_progress;
end if;
end if;
end process;
-- will be one for one cycle at the proper end of the async cycle
ab_wr_pulse <= wr_delay(wr_delay'HIGH) and not wr_delay(wr_delay'HIGH-1);
ab_wr_latch_pulse <= not wr_delay(wr_delay'HIGH) and wr_delay(wr_delay'HIGH-1);
ab_rd_pulse <= not rd_delay(rd_delay'HIGH) and rd_delay(rd_delay'HIGH-1);
 
-- Generates WishBone control signals
wb_ctrl_gen: process
begin
if (wb_rst_i = '1') then
wb_stb_o <= '0';
wb_cyc_l <= '0';
wb_we_l <= '0';
end if;
wait until wb_clk_i'EVENT and wb_clk_i = '1';
-- if wb_ack = '1' then
if wb_ack = '1' and ab_wr_pulse = '0' and ab_rd_pulse = '0' then
wb_stb_o <= '0';
wb_cyc_l <= '0';
wb_we_l <= '0';
end if;
 
if ab_wr_pulse = '1' or ab_rd_pulse = '1' then
wb_stb_o <= '1';
wb_cyc_l <= '1';
wb_we_l <= ab_wr_pulse;
end if;
end process;
 
-- Generate asyncronous wait signal
ab_wait_n_rst <= wb_rst_i or not ab_active;
a_wait_n_gen: process(ab_wait_n_rst, wb_clk_i)
begin
if (ab_wait_n_rst = '1') then
ab_wait_n_l <= '1';
elsif wb_clk_i'EVENT and wb_clk_i = '1' then
-- At the beginning of a read cycle, move wait low
if ab_wait_n_l = '1' and ab_rd = '1' and rd_delay(0) = '0' then
ab_wait_n_l <= '0';
end if;
-- At the beginning of any cycle, if the ss-master part is busy, wait
if (ab_wait_n_l = '1' and (ab_rd = '1' or ab_wr = '1')) and
(wb_cyc_l = '1')
then
ab_wait_n_l <= '0';
end if;
-- At the end of an ss-master cycle, remove wait
if wb_ack = '1' and (
(wb_we_l = '1' and ab_rd = '0') or -- no pending read
wb_we_l = '0') -- was a read operation
then
ab_wait_n_l <= '1';
end if;
end if;
end process;
 
-- Generate handshake-type wait signal
a_waiths_gen: process(wb_rst_i,wb_clk_i)
begin
if (wb_rst_i = '1') then
ab_waiths_l <= '0';
elsif wb_clk_i'EVENT and wb_clk_i = '1' then
-- Write handling
if wb_cyc_l = '0' and ab_wr = '1' then
ab_waiths_l <= '1';
end if;
if wb_ack = '1' and ab_waiths_l = '1' then
ab_waiths_l <= '0';
end if;
 
-- Read handling
if wb_ack = '1' and ab_rd = '1' then
ab_waiths_l <= '1';
end if;
 
if wb_cyc_l = '0' and ab_rd = '0' and ab_wr = '0' and wr_delay(wr_delay'HIGH) = '0'
then
ab_waiths_l <= '0';
end if;
end if;
end process;
 
-- connect local signals to external pins
wb_cyc_o <= wb_cyc_l;
wb_we_o <= wb_we_l;
-- ab_wait_n <= '0' when ab_wait_n_l = '0' else '1';
ab_dat <= wb_dat_reg when ab_rd = '1' else (others => 'Z');
 
-- On post-layout simulation it turned out that the data is not stable upon
-- the raising edge of these wait signals. So we delay the raising edge with one-half clock
delay_wait: process(wb_clk_i)
begin
if wb_clk_i'EVENT and wb_clk_i = '0' then
ab_wait_n_l_delayed <= ab_wait_n_l;
ab_waiths_l_delayed <= ab_waiths_l;
end if;
end process;
ab_wait_n <= ab_wait_n_l and ab_wait_n_l_delayed;
ab_waiths <= ab_waiths_l and ab_waiths_l_delayed;
 
-- ab_dat_gen: process(wb_clk_i,wb_rst_i)
-- begin
-- if (wb_rst_i = '1') then
-- ab_dat <= (others => 'Z');
-- elsif wb_clk_i'EVENT and wb_clk_i = '1' then
-- if (ab_rd = '1') then
-- ab_dat <= wb_dat_reg;
-- else
-- ab_dat <= (others => 'Z');
-- end if;
-- end if;
-- end process;
 
end xilinx;
 
/trunk/wb_bus_upsize.vhd
22,10 → 22,10
 
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
m_dat_width: positive := 8; -- master bus width
m_adr_width: positive := 21; -- master bus width
s_dat_width: positive := 16; -- slave bus width
s_adr_width: positive := 20; -- master bus width
little_endien: boolean := true -- if set to false, big endien
);
port (
33,11 → 33,11
-- 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_adr_i: in std_logic_vector (m_adr_width-1 downto 0);
m_sel_i: in std_logic_vector ((m_dat_width/8)-1 downto 0) := (others => '1');
m_dat_i: in std_logic_vector (m_dat_width-1 downto 0);
m_dat_oi: in std_logic_vector (m_dat_width-1 downto 0) := (others => '-');
m_dat_o: out std_logic_vector (m_dat_width-1 downto 0);
m_cyc_i: in std_logic;
m_ack_o: out std_logic;
m_ack_oi: in std_logic := '-';
49,10 → 49,10
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_adr_o: out std_logic_vector (s_adr_width-1 downto 0);
s_sel_o: out std_logic_vector ((s_dat_width/8)-1 downto 0);
s_dat_i: in std_logic_vector (s_dat_width-1 downto 0);
s_dat_o: out std_logic_vector (s_dat_width-1 downto 0);
s_cyc_o: out std_logic;
s_ack_i: in std_logic;
s_err_i: in std_logic := '-';
63,11 → 63,11
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);
constant addr_diff: integer := log2(s_dat_width/m_dat_width);
signal i_m_dat_o: std_logic_vector(m_dat_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);
assert (m_adr_width = s_adr_width+addr_diff) report "Address widths are not consistent" severity FAILURE;
s_adr_o <= m_adr_i(m_adr_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);
74,9 → 74,9
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
 
sel_dat_mux: process
begin
wait on s_dat_i, m_adr_i;
if (little_endien) then
101,7 → 101,7
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));
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
/trunk/components.vhd
0,0 → 1,401
--
-- 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. Currently only 8->16 bit bus resize is supported
-- 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 components is
component wb_bus_upsize
generic (
m_dat_width: positive := 8; -- master bus width
m_adr_width: positive := 21; -- master bus width
s_dat_width: positive := 16; -- slave bus width
s_adr_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_adr_width-1 downto 0);
m_sel_i: in std_logic_vector ((m_dat_width/8)-1 downto 0) := (others => '1');
m_dat_i: in std_logic_vector (m_dat_width-1 downto 0);
m_dat_oi: in std_logic_vector (m_dat_width-1 downto 0) := (others => '-');
m_dat_o: out std_logic_vector (m_dat_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_adr_width-1 downto 0);
s_sel_o: out std_logic_vector ((s_dat_width/8)-1 downto 0);
s_dat_i: in std_logic_vector (s_dat_width-1 downto 0);
s_dat_o: out std_logic_vector (s_dat_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
generic (
m_dat_width: positive := 32; -- master bus width
m_adr_width: positive := 20; -- master bus width
s_dat_width: positive := 16; -- slave bus width
s_adr_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_adr_width-1 downto 0);
m_sel_i: in std_logic_vector ((m_dat_width/8)-1 downto 0) := (others => '1');
m_dat_i: in std_logic_vector (m_dat_width-1 downto 0);
m_dat_oi: in std_logic_vector (m_dat_width-1 downto 0) := (others => '-');
m_dat_o: out std_logic_vector (m_dat_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_adr_width-1 downto 0);
s_sel_o: out std_logic_vector ((s_dat_width/8)-1 downto 0);
s_dat_i: in std_logic_vector (s_dat_width-1 downto 0);
s_dat_o: out std_logic_vector (s_dat_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
generic (
m_dat_width: positive := 32; -- master bus width
m_adr_width: positive := 20; -- master bus width
s_dat_width: positive := 16; -- slave bus width
s_adr_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_adr_width-1 downto 0);
m_sel_i: in std_logic_vector ((m_dat_width/8)-1 downto 0) := (others => '1');
m_dat_i: in std_logic_vector (m_dat_width-1 downto 0);
m_dat_oi: in std_logic_vector (m_dat_width-1 downto 0) := (others => '-');
m_dat_o: out std_logic_vector (m_dat_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_adr_width-1 downto 0);
s_sel_o: out std_logic_vector ((s_dat_width/8)-1 downto 0);
s_dat_i: in std_logic_vector (s_dat_width-1 downto 0);
s_dat_o: out std_logic_vector (s_dat_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_ro_async_master
generic (
dat_width: positive;
adr_width: positive;
ab_rd_delay: positive
);
port (
wb_clk_i: in std_logic;
wb_rst_i: in std_logic := '0';
 
-- interface to wb slave devices
wb_adr_o: out std_logic_vector (adr_width-1 downto 0);
wb_sel_o: out std_logic_vector ((dat_width/8)-1 downto 0);
wb_dat_i: in std_logic_vector (dat_width-1 downto 0);
wb_dat_o: out std_logic_vector (dat_width-1 downto 0);
wb_cyc_o: out std_logic;
wb_ack_i: in std_logic;
wb_err_i: in std_logic := '-';
wb_rty_i: in std_logic := '-';
wb_we_o: out std_logic;
wb_stb_o: out std_logic;
 
-- interface to the asyncronous master device
ab_dat: inout std_logic_vector (dat_width-1 downto 0) := (others => 'Z');
ab_adr: in std_logic_vector (adr_width-1 downto 0) := (others => 'U');
ab_rd_n: in std_logic := '1';
ab_wr_n: in std_logic := '1';
ab_ce_n: in std_logic := '1';
ab_byteen_n: in std_logic_vector ((dat_width/8)-1 downto 0);
ab_wait_n: out std_logic; -- wait-state request 'open-drain' output
ab_waiths: out std_logic -- handshake-type totem-pole output
);
end component;
 
component wb_async_master
generic (
dat_width: positive;
adr_width: positive;
ab_rd_delay: positive
);
port (
wb_clk_i: in std_logic;
wb_rst_i: in std_logic := '0';
 
-- interface to wb slave devices
wb_adr_o: out std_logic_vector (adr_width-1 downto 0);
wb_sel_o: out std_logic_vector ((dat_width/8)-1 downto 0);
wb_dat_i: in std_logic_vector (dat_width-1 downto 0);
wb_dat_o: out std_logic_vector (dat_width-1 downto 0);
wb_cyc_o: out std_logic;
wb_ack_i: in std_logic;
wb_err_i: in std_logic := '-';
wb_rty_i: in std_logic := '-';
wb_we_o: out std_logic;
wb_stb_o: out std_logic;
 
-- interface to the asyncronous master device
ab_dat: inout std_logic_vector (dat_width-1 downto 0) := (others => 'Z');
ab_adr: in std_logic_vector (adr_width-1 downto 0) := (others => 'U');
ab_rd_n: in std_logic := '1';
ab_wr_n: in std_logic := '1';
ab_ce_n: in std_logic := '1';
ab_byteen_n: in std_logic_vector ((dat_width/8)-1 downto 0);
ab_wait_n: out std_logic; -- wait-state request 'open-drain' output
ab_waiths: out std_logic -- handshake-type totem-pole output
);
end component;
 
component wb_async_master_2
generic (
dat_width: positive;
adr_width: positive;
ab_rd_delay: positive
);
port (
wb_clk_i: in std_logic;
wb_rst_i: in std_logic := '0';
 
-- interface to wb slave devices
wb_adr_o: out std_logic_vector (adr_width-1 downto 0);
wb_sel_o: out std_logic_vector ((dat_width/8)-1 downto 0);
wb_dat_i: in std_logic_vector (dat_width-1 downto 0);
wb_dat_o: out std_logic_vector (dat_width-1 downto 0);
wb_cyc_o: out std_logic;
wb_ack_i: in std_logic;
wb_err_i: in std_logic := '-';
wb_rty_i: in std_logic := '-';
wb_we_o: out std_logic;
wb_stb_o: out std_logic;
 
-- interface to the asyncronous master device
ab_dat: inout std_logic_vector (dat_width-1 downto 0) := (others => 'Z');
ab_adr: in std_logic_vector (adr_width-1 downto 0) := (others => 'U');
ab_rd_n: in std_logic := '1';
ab_wr_n: in std_logic := '1';
ab_ce_n: in std_logic := '1';
ab_byteen_n: in std_logic_vector ((dat_width/8)-1 downto 0);
ab_wait_n: out std_logic; -- wait-state request 'open-drain' output
ab_waiths: out std_logic; -- handshake-type totem-pole output
 
-- debug signals
db_rd_pulse: out std_logic
);
end component;
 
component wb_async_slave
generic (
dat_width: positive := 16;
adr_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 (adr_width-1 downto 0);
sel_i: in std_logic_vector ((adr_width/8)-1 downto 0);
dat_i: in std_logic_vector (dat_width-1 downto 0);
dat_o: out std_logic_vector (dat_width-1 downto 0);
dat_oi: in std_logic_vector (dat_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 (dat_width-1 downto 0) := (others => 'Z');
a_addr: out std_logic_vector (adr_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 ((dat_width/8)-1 downto 0)
);
end component;
 
component wb_arbiter
port (
-- clk_i: 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 component;
 
component wb_out_reg
generic (
reg_width : positive := 8;
dat_width: positive := 8;
offset: integer := 0
);
port (
clk_i: in std_logic;
rst_i: in std_logic;
rst_val: std_logic_vector(reg_width-1 downto 0) := (others => '0');
 
cyc_i: in std_logic := '1';
stb_i: in std_logic;
sel_i: in std_logic_vector (max2((dat_width/8)-1,0) 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((reg_width+offset+dat_width-1)/dat_width)-1 downto 0) := (others => '0');
dat_i: in std_logic_vector (dat_width-1 downto 0);
dat_oi: in std_logic_vector (dat_width-1 downto 0) := (others => '-');
dat_o: out std_logic_vector (dat_width-1 downto 0);
q: out std_logic_vector (reg_width-1 downto 0)
);
end component;
 
component wb_in_reg
generic (
reg_width : positive := 8;
dat_width: positive := 8;
offset: integer := 0
);
port (
clk_i: in std_logic;
rst_i: in std_logic;
 
cyc_i: in std_logic := '1';
stb_i: in std_logic;
sel_i: in std_logic_vector (max2((dat_width/8)-1,0) 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((reg_width+offset+dat_width-1)/dat_width)-1 downto 0) := (others => '0');
dat_oi: in std_logic_vector (dat_width-1 downto 0) := (others => '-');
dat_o: out std_logic_vector (dat_width-1 downto 0);
i: in std_logic_vector (reg_width-1 downto 0)
);
end component;
 
component wb_ram
generic (
dat_width: positive := 8;
adr_width: positive := 10
);
port (
clk_i: in std_logic;
-- rst_i: in std_logic := '0';
adr_i: in std_logic_vector (adr_width-1 downto 0);
-- sel_i: in std_logic_vector ((dat_width/8)-1 downto 0) := (others => '1');
dat_i: in std_logic_vector (dat_width-1 downto 0);
dat_oi: in std_logic_vector (dat_width-1 downto 0) := (others => '-');
dat_o: out std_logic_vector (dat_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 component;
end components;
 
/trunk/wb_in_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_in_reg is
generic (
reg_width : positive := 8;
dat_width: positive := 8;
offset: integer := 0
);
port (
clk_i: in std_logic;
rst_i: in std_logic;
 
cyc_i: in std_logic := '1';
stb_i: in std_logic;
sel_i: in std_logic_vector (max2((dat_width/8)-1,0) 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((reg_width+offset+dat_width-1)/dat_width)-1 downto 0) := (others => '0');
dat_oi: in std_logic_vector (dat_width-1 downto 0) := (others => '-');
dat_o: out std_logic_vector (dat_width-1 downto 0);
i: in std_logic_vector (reg_width-1 downto 0)
);
end wb_in_reg;
 
architecture wb_in_reg of wb_in_reg is
signal content : std_logic_vector (reg_width-1 downto 0);
signal word_en: std_logic_vector ((reg_width / dat_width)-1 downto 0);
begin
-- address demux
adr_demux: process (adr_i)
begin
word_en <= (others => '0');
--:::TA Possible problem: index range can be out of bounds at least accroding to XST
word_en(to_integer(adr_i)) <= '1';
end process;
 
-- output bus handling with logic
gen_dat_o: process(
dat_oi, we_i, stb_i, content, word_en, cyc_i, sel_i
)
variable rd_sel: std_logic;
variable dat_idx: integer;
begin
rd_sel := cyc_i and stb_i and not we_i;
 
-- The default is the input, we'll override it if we need to
for i in dat_o'RANGE loop
dat_o(i) <= dat_oi(i);
end loop;
for i in content'RANGE loop
dat_idx := (i+offset) mod dat_width;
if (
-- (sel_i((i/8) mod (dat_width/8)) = '1') and
(word_en(i/dat_width) = '1') and
(rd_sel = '1')
) then
-- dat_o(dat_idx) <= (dat_oi(dat_idx) and not rd_sel) or (content(i) and rd_sel);
dat_o(dat_idx) <= content(i);
end if;
end loop;
end process;
-- dat_o <= dat_oi;
 
-- this item never generates any wait-states
ack_o <= stb_i or ack_oi;
 
reg: process
begin
wait until clk_i'EVENT and clk_i='1';
content <= i;
end process;
end wb_in_reg;
/trunk/wb_out_reg.vhd
23,69 → 23,86
 
entity wb_out_reg is
generic (
width : positive := 8;
bus_width: positive := 8;
reg_width : positive := 8;
dat_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');
rst_val: std_logic_vector(reg_width-1 downto 0) := (others => '0');
 
cyc_i: in std_logic := '1';
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');
sel_i: in std_logic_vector (max2((dat_width/8)-1,0) 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)
adr_i: in std_logic_vector (size2bits((reg_width+offset+dat_width-1)/dat_width)-1 downto 0) := (others => '0');
dat_i: in std_logic_vector (dat_width-1 downto 0);
dat_oi: in std_logic_vector (dat_width-1 downto 0) := (others => '-');
dat_o: out std_logic_vector (dat_width-1 downto 0);
q: out std_logic_vector (reg_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);
signal content : std_logic_vector (reg_width-1 downto 0);
signal word_en: std_logic_vector ((reg_width / dat_width)-1 downto 0);
begin
-- address demux
adr_demux: process (adr_i)
begin
word_en <= (others => '0');
word_en(to_integer(adr_i)) <= '1';
end process;
 
-- output bus handling with logic
gen_dat_o: process is
gen_dat_o: process(
dat_oi, we_i, stb_i, content, word_en, cyc_i, sel_i
)
variable rd_sel: std_logic;
variable adr: integer;
variable reg_i: integer;
variable dat_idx: 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);
rd_sel := cyc_i and stb_i and not we_i;
-- The default is the input, we'll override it if we need to
for i in dat_o'RANGE loop
dat_o(i) <= dat_oi(i);
end loop;
for i in content'RANGE loop
dat_idx := (i+offset) mod dat_width;
if (
-- (sel_i((i/8) mod (dat_width/8)) = '1') and
(word_en(i/dat_width) = '1') and
(rd_sel = '1')
) then
-- dat_o(dat_idx) <= (dat_oi(dat_idx) and not rd_sel) or (content(i) and rd_sel);
dat_o(dat_idx) <= content(i);
end if;
end loop;
end process;
-- dat_o <= dat_oi;
 
-- this item never generates any wait-states
-- this item never generates any wait-states
ack_o <= stb_i or ack_oi;
reg: process is
variable adr: integer;
variable reg_i: integer;
 
reg: process
variable dat_idx: integer;
begin
wait until clk_i'EVENT and clk_i='1';
if (rst_i = '1') then
content <= rst_val;
else
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;
for i in content'RANGE loop
dat_idx := (i+offset) mod dat_width;
if (
-- (sel_i((i/8) mod (dat_width/8)) = '1') and
(word_en(i/dat_width) = '1')
) then
content(i) <= dat_i(dat_idx);
end if;
end loop;
end if;
end if;
/trunk/wb_bus_dnsize.vhd
23,15 → 23,12
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
m_dat_width: positive := 32; -- master bus width
m_adr_width: positive := 20; -- master bus width
s_dat_width: positive := 16; -- slave bus width
s_adr_width: positive := 21; -- master bus width
little_endien: boolean := true -- if set to false, big endien
);
port (
39,11 → 36,11
-- 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_adr_i: in std_logic_vector (m_adr_width-1 downto 0);
m_sel_i: in std_logic_vector ((m_dat_width/8)-1 downto 0) := (others => '1');
m_dat_i: in std_logic_vector (m_dat_width-1 downto 0);
m_dat_oi: in std_logic_vector (m_dat_width-1 downto 0) := (others => '-');
m_dat_o: out std_logic_vector (m_dat_width-1 downto 0);
m_cyc_i: in std_logic;
m_ack_o: out std_logic;
m_ack_oi: in std_logic := '-';
55,10 → 52,10
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_adr_o: out std_logic_vector (s_adr_width-1 downto 0);
s_sel_o: out std_logic_vector ((s_dat_width/8)-1 downto 0);
s_dat_i: in std_logic_vector (s_dat_width-1 downto 0);
s_dat_o: out std_logic_vector (s_dat_width-1 downto 0);
s_cyc_o: out std_logic;
s_ack_i: in std_logic;
s_err_i: in std_logic := '-';
69,53 → 66,55
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);
constant addr_diff: integer := log2(m_dat_width/s_dat_width);
constant mux_mask: integer := ((m_dat_width / 8)-1) - ((s_dat_width/8)-1);
signal i_m_dat_o: std_logic_vector(m_dat_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;
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;
assert (s_adr_width = m_adr_width+addr_diff) report "Address widths are not consistent" severity FAILURE;
 
-- Reconstructing address bits (mux_sel)
compute_mux_sel: process is
-- Reconstructing address bits (mux_sel)
compute_mux_sel: process(m_sel_i)
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));
-- wait on m_sel_i;
i := prior_decode(m_sel_i);
mux_sel <= to_std_logic_vector(i,log2(m_sel_i'HIGH+1)) and to_std_logic_vector(mux_mask,log2(m_sel_i'HIGH+1));
end process;
i_mux_sel <= CONV_INTEGER(mux_sel);
i_mux_sel <= to_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
 
-- create slave address bus
s_adr_o(s_adr_width-1 downto addr_diff) <= m_adr_i;
s_adr_o_gen: process
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);
--:::TA This does not work under webpack. Re-simulate!!!!
-- wait on mux_sel(mux_sel'HIGH downto mux_sel'HIGH-addr_diff+1);
wait on mux_sel;
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;
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_sel_o <= m_sel_i(i_mux_sel+(s_dat_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);
122,16 → 121,16
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
 
-- Multiplex data-bus down to the slave width
s_dat_o <= m_dat_i((i_mux_sel)*8-1+s_dat_width downto (i_mux_sel)*8);
 
m_dat_o_mux: process
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;
m_dat_o((i_mux_sel)*8-1+s_dat_width downto (i_mux_sel)*8) <= s_dat_i;
end if;
end process;
end wb_bus_dnsize;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.