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_bus_dnsize_TB.vhd
File deleted
/trunk/TestBench/wb_out_reg_TB.vhd
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; |