URL
https://opencores.org/ocsvn/wb_vga/wb_vga/trunk
Subversion Repositories wb_vga
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 6 to Rev 5
- ↔ Reverse comparison
Rev 6 → Rev 5
/trunk/vga_core_v2.vhd
File deleted
/trunk/TestBench/vga_core_v2_TB.vhd
File deleted
/trunk/TestBench/vga_chip_TB.vhd
10,6 → 10,11
use wb_vga.constants.all; |
|
entity vga_chip_tb is |
-- Generic declarations of the tested unit |
generic( |
v_mem_width : POSITIVE := 16; |
fifo_size : POSITIVE := 256; |
v_addr_width : POSITIVE := 20 ); |
end vga_chip_tb; |
|
architecture TB of vga_chip_tb is |
84,29 → 89,28
signal blank : std_logic; |
signal video_out : std_logic_vector(7 downto 0); |
|
constant reg_total0 : integer := 0; |
constant reg_total1 : integer := 1; |
constant reg_total2 : integer := 2; |
constant reg_total3 : integer := 3; |
constant reg_ofs0 : integer := 4; |
constant reg_ofs1 : integer := 5; |
constant reg_ofs2 : integer := 6; |
constant reg_ofs3 : integer := 7; |
constant reg_total0 : std_logic_vector(v_addr_width downto 0) := "000000000000000000000"; |
constant reg_total1 : std_logic_vector(v_addr_width downto 0) := "000000000000000000001"; |
constant reg_total2 : std_logic_vector(v_addr_width downto 0) := "000000000000000000010"; |
constant reg_total3 : std_logic_vector(v_addr_width downto 0) := "000000000000000000011"; |
constant reg_ofs0 : std_logic_vector(v_addr_width downto 0) := "000000000000000000100"; |
constant reg_ofs1 : std_logic_vector(v_addr_width downto 0) := "000000000000000000101"; |
constant reg_ofs2 : std_logic_vector(v_addr_width downto 0) := "000000000000000000110"; |
constant reg_ofs3 : std_logic_vector(v_addr_width downto 0) := "000000000000000000111"; |
constant reg_ws : std_logic_vector(v_addr_width downto 0) := "000000000000000001000"; |
|
constant reg_fifo_treshold : integer := 16; |
constant reg_bpp : integer := 17; |
constant reg_hbs : integer := 18; |
constant reg_hss : integer := 19; |
constant reg_hse : integer := 20; |
constant reg_htotal : integer := 21; |
constant reg_vbs : integer := 22; |
constant reg_vss : integer := 23; |
constant reg_vse : integer := 24; |
constant reg_vtotal : integer := 25; |
constant reg_pps : integer := 26; |
constant reg_sync_pol : integer := 27; |
|
constant reg_ws : integer := 32; |
constant reg_fifo_treshold : std_logic_vector(v_addr_width downto 0) := "000000000000000010000"; |
constant reg_bpp : std_logic_vector(v_addr_width downto 0) := "000000000000000010001"; |
constant reg_hbs : std_logic_vector(v_addr_width downto 0) := "000000000000000010010"; |
constant reg_hss : std_logic_vector(v_addr_width downto 0) := "000000000000000010011"; |
constant reg_hse : std_logic_vector(v_addr_width downto 0) := "000000000000000010100"; |
constant reg_htotal : std_logic_vector(v_addr_width downto 0) := "000000000000000010101"; |
constant reg_vbs : std_logic_vector(v_addr_width downto 0) := "000000000000000010110"; |
constant reg_vss : std_logic_vector(v_addr_width downto 0) := "000000000000000010111"; |
constant reg_vse : std_logic_vector(v_addr_width downto 0) := "000000000000000011000"; |
constant reg_vtotal : std_logic_vector(v_addr_width downto 0) := "000000000000000011001"; |
constant reg_pps : std_logic_vector(v_addr_width downto 0) := "000000000000000011010"; |
constant reg_sync_pol : std_logic_vector(v_addr_width downto 0) := "000000000000000011011"; |
|
constant val_total0 : std_logic_vector(7 downto 0) := "00001111"; |
constant val_total1 : std_logic_vector(7 downto 0) := "00000000"; |
116,6 → 120,7
constant val_ofs1 : std_logic_vector(7 downto 0) := "00000000"; |
constant val_ofs2 : std_logic_vector(7 downto 0) := "00000000"; |
constant val_ofs3 : std_logic_vector(7 downto 0) := "00000000"; |
constant val_ws : std_logic_vector(7 downto 0) := "00000010"; |
constant val_fifo_treshold : std_logic_vector(7 downto 0) := "00000011"; |
constant val_bpp : std_logic_vector(7 downto 0) := "00000011"; |
constant val_hbs : std_logic_vector(7 downto 0) := "00000111"; |
128,7 → 133,6
constant val_vtotal : std_logic_vector(7 downto 0) := "00000100"; |
constant val_pps : std_logic_vector(7 downto 0) := "00000001"; |
constant val_sync_pol : std_logic_vector(7 downto 0) := "10000000"; |
constant val_ws : std_logic_vector(7 downto 0) := "00000010"; |
|
begin |
|
194,69 → 198,34
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
|
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_total0 ,val_total0); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_total1 ,val_total1); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_total2 ,val_total2); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_total3 ,val_total3); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_ofs0 ,val_ofs0); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_ofs1 ,val_ofs1); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_ofs2 ,val_ofs2); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_ofs3 ,val_ofs3); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_ws ,val_ws); |
|
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
|
if (cpu_dat_width = 8) then |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_total0 ,val_total0); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_total1 ,val_total1); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_total2 ,val_total2); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_total3 ,val_total3); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_ofs0 ,val_ofs0); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_ofs1 ,val_ofs1); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_ofs2 ,val_ofs2); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_ofs3 ,val_ofs3); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_ws ,val_ws); |
|
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
|
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_fifo_treshold ,val_fifo_treshold); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_bpp ,val_bpp); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_hbs ,val_hbs); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_hss ,val_hss); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_hse ,val_hse); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_htotal ,val_htotal); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_vbs ,val_vbs); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_vss ,val_vss); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_vse ,val_vse); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_vtotal ,val_vtotal); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_pps ,val_pps); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_sync_pol ,val_sync_pol); |
end if; |
if (cpu_dat_width = 16) then |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_total0/2 ,val_total1 & val_total0); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_total2/2 ,val_total3 & val_total2); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_ofs0/2 ,val_ofs1 & val_ofs0); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_ofs2/2 ,val_ofs3 & val_ofs2); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_ws/2 ,"00000000" & val_ws ); |
|
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
|
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_fifo_treshold/2 ,val_bpp & val_fifo_treshold); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_hbs/2 ,val_hss & val_hbs); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_hse/2 ,val_htotal & val_hse); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_vbs/2 ,val_vss & val_vbs); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_vse/2 ,val_vtotal & val_vse); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_pps/2 ,val_sync_pol & val_pps); |
end if; |
if (cpu_dat_width = 32) then |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_total0/4 ,val_total3 & val_total2 & val_total1 & val_total0); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_ofs0/4 ,val_ofs3 & val_ofs2 & val_ofs1 & val_ofs0); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_ws/4 ,"000000000000000000000000" & val_ws ); |
|
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
wait until clk_i'EVENT and clk_i = '1'; |
|
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_fifo_treshold/4 ,val_hss & val_hbs & val_bpp & val_fifo_treshold); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_hse/4 ,val_vss & val_vbs & val_htotal & val_hse); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_vse/4 ,val_sync_pol & val_pps & val_vtotal & val_vse); |
end if; |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_fifo_treshold ,val_fifo_treshold); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_bpp ,val_bpp); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_hbs ,val_hbs); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_hss ,val_hss); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_hse ,val_hse); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_htotal ,val_htotal); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_vbs ,val_vbs); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_vss ,val_vss); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_vse ,val_vse); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_vtotal ,val_vtotal); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_pps ,val_pps); |
wr_chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_sync_pol ,val_sync_pol); |
|
wait; |
end process; |
266,7 → 235,7
wait on s_data,s_addr,s_oen,s_wrhn,s_wrln,s_cen; |
if (s_cen = '0') then |
if (s_oen = '0') then |
s_data <= s_addr(v_dat_width-1 downto 0); |
s_data <= s_addr(v_mem_width-1 downto 0); |
elsif (s_wrhn = '0' or s_wrln = '0') then |
if (s_wrhn = '0') then |
else |
/trunk/mem_reader.vhd
24,8 → 24,7
pix_clk_en: in std_logic; |
reset: in std_logic := '0'; |
|
v_mem_end: in std_logic_vector(v_addr_width-1 downto 0); -- video memory end address in words |
v_mem_start: in std_logic_vector(v_addr_width-1 downto 0) := (others => '0'); -- video memory start adderss in words |
total: in std_logic_vector(v_addr_width-1 downto 0); -- total video memory size in bytes 7..0 |
fifo_treshold: in std_logic_vector(7 downto 0); -- priority change threshold |
bpp: in std_logic_vector(1 downto 0); -- number of bits makes up a pixel valid values: 1,2,4,8 |
multi_scan: in std_logic_vector(1 downto 0); -- number of repeated scans |
176,14 → 175,14
begin |
wait until clk'EVENT and clk='1'; |
if (reset = '1') then |
pixel_cnt := v_mem_start; |
pixel_cnt := (others => '0'); |
else |
-- A little cheet. It won't work with constant v_mem_rdy. |
if (v_mem_rdy = '1') then |
-- data is already written to the FIFO, all we need to do is to update the counter, |
-- and remove the request |
if (pixel_cnt = v_mem_end) then |
pixel_cnt := v_mem_start; |
if (pixel_cnt = total) then |
pixel_cnt := (others => '0'); |
else |
pixel_cnt := add_one(pixel_cnt); |
end if; |
/trunk/vga_chip.vhd
11,9 → 11,8
package constants is |
constant v_dat_width: positive := 16; |
constant v_adr_width : positive := 20; |
constant cpu_dat_width: positive := 32; |
constant cpu_adr_width: positive := 19; |
constant reg_adr_width: positive := 5; |
constant cpu_dat_width: positive := 8; |
constant cpu_adr_width: positive := 21; |
constant fifo_size: positive := 256; |
-- constant addr_diff: integer := log2(cpu_dat_width/v_dat_width); |
end constants; |
35,17 → 34,20
port ( |
clk_i: in std_logic; |
clk_en: in std_logic := '1'; |
rstn: in std_logic := '1'; |
rst_i: in std_logic := '0'; |
|
-- CPU bus interface |
data: inout std_logic_vector (cpu_dat_width-1 downto 0) := (others => 'Z'); |
addr: in std_logic_vector (cpu_adr_width-1 downto 0) := (others => 'U'); |
rdn: in std_logic := '1'; |
wrn: in std_logic := '1'; |
vmem_cen: in std_logic := '1'; |
reg_cen: in std_logic := '1'; |
byen: in std_logic_vector ((cpu_dat_width/8)-1 downto 0); |
waitn: out std_logic; |
dat_i: in std_logic_vector (cpu_dat_width-1 downto 0); |
dat_oi: in std_logic_vector (cpu_dat_width-1 downto 0); |
dat_o: out std_logic_vector (cpu_dat_width-1 downto 0); |
cyc_i: in std_logic; |
ack_o: out std_logic; |
ack_oi: in std_logic; |
we_i: in std_logic; |
vmem_stb_i: in std_logic; |
reg_stb_i: in std_logic; |
adr_i: in std_logic_vector (cpu_adr_width-1 downto 0); |
sel_i: in std_logic_vector ((cpu_dat_width/8)-1 downto 0) := (others => '1'); |
|
-- video memory SRAM interface |
s_data : inout std_logic_vector(v_dat_width-1 downto 0); |
102,45 → 104,13
); |
end component; |
|
component wb_async_master |
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 component; |
|
component vga_core |
generic ( |
-- cannot be overwritten at the moment... |
v_dat_width: positive := 16; |
v_adr_width : positive := 20; |
cpu_dat_width: positive := 16; |
cpu_adr_width: positive := 20; |
reg_adr_width: positive := 20; |
cpu_dat_width: positive := 8; |
cpu_adr_width: positive := 21; |
fifo_size: positive := 256 |
); |
port ( |
147,31 → 117,22
clk_i: in std_logic; |
clk_en: in std_logic := '1'; |
rst_i: in std_logic := '0'; |
|
-- CPU memory bus interface |
vmem_cyc_i: in std_logic; |
vmem_we_i: in std_logic; |
|
-- CPU bus interface |
cyc_i: in std_logic; |
we_i: in std_logic; |
vmem_stb_i: in std_logic; -- selects video memory |
vmem_ack_o: out std_logic; |
vmem_ack_oi: in std_logic; |
vmem_adr_i: in std_logic_vector (cpu_adr_width-1 downto 0); |
vmem_sel_i: in std_logic_vector ((cpu_dat_width/8)-1 downto 0) := (others => '1'); |
vmem_dat_i: in std_logic_vector (cpu_dat_width-1 downto 0); |
vmem_dat_oi: in std_logic_vector (cpu_dat_width-1 downto 0); |
vmem_dat_o: out std_logic_vector (cpu_dat_width-1 downto 0); |
|
-- CPU register bus interface |
reg_cyc_i: in std_logic; |
reg_we_i: in std_logic; |
reg_stb_i: in std_logic; -- selects configuration registers |
reg_ack_o: out std_logic; |
reg_ack_oi: in std_logic; |
reg_adr_i: in std_logic_vector (reg_adr_width-1 downto 0); |
reg_sel_i: in std_logic_vector ((cpu_dat_width/8)-1 downto 0) := (others => '1'); |
reg_dat_i: in std_logic_vector (cpu_dat_width-1 downto 0); |
reg_dat_oi: in std_logic_vector (cpu_dat_width-1 downto 0); |
reg_dat_o: out std_logic_vector (cpu_dat_width-1 downto 0); |
|
total_stb_i: in std_logic; -- selects total register |
ofs_stb_i: in std_logic; -- selects offset register |
reg_bank_stb_i: in std_logic; -- selects all other registers (in a single bank) |
ack_o: out std_logic; |
ack_oi: in std_logic; |
adr_i: in std_logic_vector (v_adr_width downto 0); |
sel_i: in std_logic_vector ((cpu_dat_width/8)-1 downto 0) := (others => '1'); |
dat_i: in std_logic_vector (cpu_dat_width-1 downto 0); |
dat_oi: in std_logic_vector (cpu_dat_width-1 downto 0); |
dat_o: out std_logic_vector (cpu_dat_width-1 downto 0); |
|
-- video memory interface |
v_adr_o: out std_logic_vector (v_adr_width-1 downto 0); |
v_sel_o: out std_logic_vector ((v_dat_width/8)-1 downto 0); |
181,7 → 142,7
v_ack_i: in std_logic; |
v_we_o: out std_logic; |
v_stb_o: out std_logic; |
|
|
-- sync blank and video signal outputs |
h_sync: out std_logic; |
h_blank: out std_logic; |
219,10 → 180,9
); |
end component; |
|
signal reg_ack_o: std_logic; |
signal reg_dat_o: std_logic_vector(cpu_dat_width-1 downto 0); |
|
signal reg_stb: std_logic; |
signal total_stb: std_logic; |
signal ofs_stb: std_logic; |
signal reg_bank_stb: std_logic; |
signal ws_stb: std_logic; |
signal wait_state: std_logic_vector(3 downto 0); |
|
241,29 → 201,7
signal ws_ack_o: std_logic; |
|
signal s_wrn: std_logic; |
|
|
signal dat_i: std_logic_vector (cpu_dat_width-1 downto 0); |
signal dat_oi: std_logic_vector (cpu_dat_width-1 downto 0); |
signal dat_o: std_logic_vector (cpu_dat_width-1 downto 0); |
signal cyc_i: std_logic; |
signal ack_o: std_logic; |
signal ack_oi: std_logic; |
signal we_i: std_logic; |
signal vmem_stb_i: std_logic; |
signal reg_stb_i: std_logic; |
signal adr_i: std_logic_vector (cpu_adr_width-1 downto 0); |
signal sel_i: std_logic_vector ((cpu_dat_width/8)-1 downto 0) := (others => '1'); |
|
signal cen: std_logic; |
signal stb: std_logic; |
|
signal rst_i: std_logic := '0'; |
|
constant vga_reg_size: integer := size2bits((32*8+cpu_dat_width-1)/cpu_dat_width); |
begin |
rst_i <= not rstn; |
|
ws_reg: wb_out_reg |
generic map( width => 4, bus_width => cpu_dat_width , offset => 0 ) |
port map( |
283,7 → 221,6
v_adr_width => v_adr_width, |
cpu_dat_width => cpu_dat_width, |
cpu_adr_width => cpu_adr_width, |
reg_adr_width => reg_adr_width, |
fifo_size => fifo_size |
) |
port map ( |
290,32 → 227,20
clk_i => clk_i, |
clk_en => clk_en, |
rst_i => rst_i, |
|
-- CPU bus interface |
vmem_cyc_i => cyc_i, |
vmem_we_i => we_i, |
vmem_stb_i => vmem_stb_i, |
vmem_ack_o => ack_o, |
vmem_ack_oi => reg_ack_o, |
vmem_adr_i => adr_i, |
vmem_sel_i => sel_i, |
vmem_dat_i => dat_i, |
vmem_dat_oi => reg_dat_o, |
vmem_dat_o => dat_o, |
|
-- CPU register bus interface |
reg_cyc_i => cyc_i, |
reg_we_i => we_i, |
reg_stb_i => reg_stb_i, |
reg_ack_o => reg_ack_o, |
reg_ack_oi => ack_oi, |
reg_adr_i => adr_i(reg_adr_width-1 downto 0), |
reg_sel_i => sel_i, |
reg_dat_i => dat_i, |
reg_dat_oi => dat_oi, |
reg_dat_o => reg_dat_o, |
|
|
cyc_i => cyc_i, |
we_i => we_i, |
vmem_stb_i => vmem_stb_i, |
total_stb_i => total_stb, |
ofs_stb_i => ofs_stb, |
reg_bank_stb_i => reg_bank_stb, |
ack_o => ack_o, |
ack_oi => ws_ack_o, |
adr_i => adr_i, |
sel_i => sel_i, |
dat_i => dat_i, |
dat_oi => ws_dat_o, |
dat_o => dat_o, |
-- video memory interface |
v_adr_o => v_adr_o, |
v_sel_o => v_sel_o, |
365,52 → 290,26
s_wrln <= s_wrn or s_byen(0); |
s_wrhn <= s_wrn or s_byen(1); |
|
master: wb_async_master |
generic map ( |
width => cpu_dat_width, |
addr_width => cpu_adr_width |
) |
port map ( |
clk_i => clk_i, |
rst_i => rst_i, |
|
-- interface to wb slave devices |
s_adr_o => adr_i, |
s_sel_o => sel_i, |
s_dat_i => dat_o, |
s_dat_o => dat_i, |
s_cyc_o => cyc_i, |
s_ack_i => ack_o, |
s_err_i => '0', |
s_rty_i => '0', |
s_we_o => we_i, |
s_stb_o => stb, |
|
-- interface to asyncron master device |
a_data => data, |
a_addr => addr, |
a_rdn => rdn, |
a_wrn => wrn, |
a_cen => cen, |
a_byen => byen, |
a_waitn => waitn |
); |
|
cen <= vmem_cen and reg_cen; |
vmem_stb_i <= stb and not vmem_cen; |
reg_stb_i <= stb and not reg_cen; |
|
addr_decoder: process is |
begin |
wait on reg_stb_i, adr_i; |
|
reg_stb <= '0'; |
total_stb <= '0'; |
ofs_stb <= '0'; |
reg_bank_stb <= '0'; |
ws_stb <= '0'; |
|
if (reg_stb_i = '1') then |
case (adr_i(vga_reg_size)) is |
when '0' => reg_stb <= '1'; |
when '1' => ws_stb <= '1'; |
case (adr_i(4)) is |
when '0' => |
case (adr_i(3 downto 2)) is |
when "00" => total_stb <= '1'; |
when "01" => ofs_stb <= '1'; |
when "10" => ws_stb <= '1'; |
when others => |
end case; |
when '1' => reg_bank_stb <= '1'; |
when others => |
end case; |
end if; |
/trunk/compile.sh
72,5 → 72,4
compile_file accel.vhd |
compile_file palette.vhd |
compile_file vga_core.vhd |
compile_file vga_core_v2.vhd |
compile_file vga_chip.vhd |
/trunk/vga_core.vhd
17,11 → 17,11
|
entity vga_core is |
generic ( |
-- cannot be overwritten at the moment... |
v_dat_width: positive := 16; |
v_adr_width : positive := 20; |
cpu_dat_width: positive := 16; |
cpu_adr_width: positive := 20; |
reg_adr_width: positive := 20; |
cpu_dat_width: positive := 8; |
cpu_adr_width: positive := 21; |
fifo_size: positive := 256 |
); |
port ( |
29,30 → 29,21
clk_en: in std_logic := '1'; |
rst_i: in std_logic := '0'; |
|
-- CPU memory bus interface |
vmem_cyc_i: in std_logic; |
vmem_we_i: in std_logic; |
-- CPU bus interface |
cyc_i: in std_logic; |
we_i: in std_logic; |
vmem_stb_i: in std_logic; -- selects video memory |
vmem_ack_o: out std_logic; |
vmem_ack_oi: in std_logic; |
vmem_adr_i: in std_logic_vector (cpu_adr_width-1 downto 0); |
vmem_sel_i: in std_logic_vector ((cpu_dat_width/8)-1 downto 0) := (others => '1'); |
vmem_dat_i: in std_logic_vector (cpu_dat_width-1 downto 0); |
vmem_dat_oi: in std_logic_vector (cpu_dat_width-1 downto 0); |
vmem_dat_o: out std_logic_vector (cpu_dat_width-1 downto 0); |
total_stb_i: in std_logic; -- selects total register |
ofs_stb_i: in std_logic; -- selects offset register |
reg_bank_stb_i: in std_logic; -- selects all other registers (in a single bank) |
ack_o: out std_logic; |
ack_oi: in std_logic; |
adr_i: in std_logic_vector (v_adr_width downto 0); |
sel_i: in std_logic_vector ((cpu_dat_width/8)-1 downto 0) := (others => '1'); |
dat_i: in std_logic_vector (cpu_dat_width-1 downto 0); |
dat_oi: in std_logic_vector (cpu_dat_width-1 downto 0); |
dat_o: out std_logic_vector (cpu_dat_width-1 downto 0); |
|
-- CPU register bus interface |
reg_cyc_i: in std_logic; |
reg_we_i: in std_logic; |
reg_stb_i: in std_logic; -- selects configuration registers |
reg_ack_o: out std_logic; |
reg_ack_oi: in std_logic; |
reg_adr_i: in std_logic_vector (reg_adr_width-1 downto 0); |
reg_sel_i: in std_logic_vector ((cpu_dat_width/8)-1 downto 0) := (others => '1'); |
reg_dat_i: in std_logic_vector (cpu_dat_width-1 downto 0); |
reg_dat_oi: in std_logic_vector (cpu_dat_width-1 downto 0); |
reg_dat_o: out std_logic_vector (cpu_dat_width-1 downto 0); |
|
-- video memory interface |
v_adr_o: out std_logic_vector (v_adr_width-1 downto 0); |
v_sel_o: out std_logic_vector ((v_dat_width/8)-1 downto 0); |
88,8 → 79,7
clk_en: in std_logic := '1'; |
reset: in std_logic := '0'; |
|
v_mem_end: in std_logic_vector(v_addr_width-1 downto 0); -- video memory end address in words |
v_mem_start: in std_logic_vector(v_addr_width-1 downto 0) := (others => '0'); -- video memory start adderss in words |
total: in std_logic_vector(v_addr_width-1 downto 0); -- total video memory size in bytes 7..0 |
fifo_treshold: in std_logic_vector(7 downto 0); -- priority change threshold |
bpp: in std_logic_vector(1 downto 0); -- number of bits makes up a pixel valid values: 1,2,4,8 |
multi_scan: in std_logic_vector(1 downto 0); -- number of repeated scans |
192,10 → 182,10
|
component wb_bus_resize |
generic ( |
m_bus_width: positive; |
m_addr_width: positive; |
s_bus_width: positive; |
s_addr_width: positive; |
m_bus_width: positive := 8; -- master bus width |
m_addr_width: positive := 21; -- master bus width |
s_bus_width: positive := 16; -- slave bus width |
s_addr_width: positive := 20; -- master bus width |
little_endien: boolean := true -- if set to false, big endien |
); |
port ( |
232,8 → 222,8
); |
end component; |
|
signal v_mem_start: std_logic_vector(v_adr_width-1 downto 0); |
signal v_mem_end: std_logic_vector(v_adr_width-1 downto 0); |
signal total: std_logic_vector(v_adr_width-1 downto 0); |
signal offset: std_logic_vector(v_adr_width-1 downto 0); |
|
signal reg_bank: std_logic_vector((8*12)-1 downto 0); |
|
252,18 → 242,18
alias sync_pol: std_logic_vector (3 downto 0) is reg_bank(91 downto 88); |
alias reset_core: std_logic_vector(0 downto 0) is reg_bank(95 downto 95); |
|
signal v_mem_start_stb: std_logic; -- selects total register |
signal v_mem_end_stb: std_logic; -- selects offset register |
signal reg_bank_stb: std_logic; -- selects all other registers (in a single bank) |
|
signal reg_bank_do: std_logic_vector(cpu_dat_width-1 downto 0); |
signal v_mem_start_do: std_logic_vector(cpu_dat_width-1 downto 0); |
signal total_do: std_logic_vector(cpu_dat_width-1 downto 0); |
signal ofs_do: std_logic_vector(cpu_dat_width-1 downto 0); |
signal vm_do: std_logic_vector(cpu_dat_width-1 downto 0); |
|
signal reg_bank_ack: std_logic; |
signal v_mem_start_ack: std_logic; |
signal total_ack: std_logic; |
signal ofs_ack: std_logic; |
signal vm_ack: std_logic; |
|
signal a_adr_o : std_logic_vector((v_adr_width-1) downto 0); |
signal a_sel_o : std_logic_vector((v_dat_width/8)-1 downto 0); |
signal a_sel_o : std_logic_vector((v_adr_width/8)-1 downto 0); |
signal a_dat_o : std_logic_vector((v_dat_width-1) downto 0); |
signal a_dat_i : std_logic_vector((v_dat_width-1) downto 0); |
signal a_we_o : std_logic; |
272,7 → 262,7
signal a_ack_i : std_logic; |
|
signal b_adr_o : std_logic_vector((v_adr_width-1) downto 0); |
signal b_sel_o : std_logic_vector((v_dat_width/8)-1 downto 0); |
signal b_sel_o : std_logic_vector((v_adr_width/8)-1 downto 0); |
-- signal b_dat_o : std_logic_vector((v_dat_width-1) downto 0); |
signal b_dat_i : std_logic_vector((v_dat_width-1) downto 0); |
signal b_stb_o : std_logic; |
295,8 → 285,6
|
constant v_adr_zero : std_logic_vector(v_adr_width-1 downto 0) := (others => '0'); |
constant reg_bank_rst_val: std_logic_vector(reg_bank'Range) := (others => '0'); |
constant reg_bank_size: integer := size2bits((reg_bank'HIGH+cpu_dat_width)/cpu_dat_width); |
constant tot_ofs_size: integer := size2bits((v_adr_width+cpu_dat_width-1)/cpu_dat_width); |
begin |
-- map all registers: |
-- adr_i: in std_logic_vector (max(log2((width+offset+bus_width-1)/bus_width)-1,0) downto 0) := (others => '0'); |
304,39 → 292,39
reg_bank_reg: wb_out_reg |
generic map( width => reg_bank'HIGH+1, bus_width => cpu_dat_width , offset => 0 ) |
port map( |
stb_i => reg_bank_stb, |
stb_i => reg_bank_stb_i, |
q => reg_bank, |
rst_val => reg_bank_rst_val, |
dat_oi => reg_dat_oi, |
dat_oi => vm_do, |
dat_o => reg_bank_do, |
ack_oi => reg_ack_oi, |
ack_oi => vm_ack, |
ack_o => reg_bank_ack, |
adr_i => reg_adr_i(reg_bank_size-1 downto 0), |
sel_i => reg_sel_i, cyc_i => reg_cyc_i, we_i => reg_we_i, clk_i => clk_i, rst_i => rst_i, dat_i => reg_dat_i ); |
v_mem_start_reg: wb_out_reg |
adr_i => adr_i(3 downto 0), -- range should be calculated !!! |
sel_i => sel_i, cyc_i => cyc_i, we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i ); |
ofs_reg: wb_out_reg |
generic map( width => v_adr_width, bus_width => cpu_dat_width , offset => 0 ) |
port map( |
stb_i => v_mem_start_stb, |
q => v_mem_start, |
stb_i => ofs_stb_i, |
q => offset, |
rst_val => v_adr_zero, |
dat_oi => reg_bank_do, |
dat_o => v_mem_start_do, |
dat_o => ofs_do, |
ack_oi => reg_bank_ack, |
ack_o => v_mem_start_ack, |
adr_i => reg_adr_i(tot_ofs_size-1 downto 0), |
sel_i => reg_sel_i, cyc_i => reg_cyc_i, we_i => reg_we_i, clk_i => clk_i, rst_i => rst_i, dat_i => reg_dat_i ); |
v_mem_end_reg: wb_out_reg |
ack_o => ofs_ack, |
adr_i => adr_i(1 downto 0), -- range should be calculated !!! |
sel_i => sel_i, cyc_i => cyc_i, we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i ); |
total_reg: wb_out_reg |
generic map( width => v_adr_width, bus_width => cpu_dat_width , offset => 0 ) |
port map( |
stb_i => v_mem_end_stb, |
q => v_mem_end, |
stb_i => total_stb_i, |
q => total, |
rst_val => v_adr_zero, |
dat_oi => v_mem_start_do, |
dat_o => reg_dat_o, -- END OF THE CHAIN |
ack_oi => v_mem_start_ack, |
ack_o => reg_ack_o, -- END OF THE CHAIN |
adr_i => reg_adr_i(tot_ofs_size-1 downto 0), |
sel_i => reg_sel_i, cyc_i => reg_cyc_i, we_i => reg_we_i, clk_i => clk_i, rst_i => rst_i, dat_i => reg_dat_i ); |
dat_oi => ofs_do, |
dat_o => dat_o, -- END OF THE CHAIN |
ack_oi => ofs_ack, |
ack_o => ack_o, -- END OF THE CHAIN |
adr_i => adr_i(1 downto 0), -- range should be calculated !!! |
sel_i => sel_i, cyc_i => cyc_i, we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i ); |
|
reset_engine <= rst_i or not reset_core(0); |
|
346,8 → 334,7
clk => clk_i, |
clk_en => clk_en, |
reset => reset_engine, |
v_mem_start => v_mem_start, |
v_mem_end => v_mem_end, |
total => total, |
fifo_treshold => fifo_treshold, |
bpp => bpp, |
multi_scan => multi_scan, |
385,18 → 372,18
|
resize: wb_bus_resize |
generic map ( |
m_bus_width => cpu_dat_width, s_bus_width => v_dat_width, m_addr_width => cpu_adr_width, s_addr_width => v_adr_width, little_endien => true |
m_bus_width => cpu_dat_width, s_bus_width => v_dat_width, m_addr_width => cpu_adr_width |
) |
port map ( |
m_adr_i => vmem_adr_i, |
m_cyc_i => vmem_cyc_i, |
m_sel_i => vmem_sel_i, |
m_dat_i => vmem_dat_i, |
m_dat_oi => vmem_dat_oi, |
m_dat_o => vmem_dat_o, |
m_ack_o => vmem_ack_o, |
m_ack_oi => vmem_ack_oi, -- Beginning of the chain |
m_we_i => vmem_we_i, |
m_adr_i => adr_i, |
m_cyc_i => cyc_i, |
m_sel_i => sel_i, |
m_dat_i => dat_i, |
m_dat_oi => dat_oi, -- Beginning of the chain |
m_dat_o => vm_do, |
m_ack_o => vm_ack, |
m_ack_oi => ack_oi, -- Beginning of the chain |
m_we_i => we_i, |
m_stb_i => vmem_stb_i, |
|
s_adr_o => a_adr_o, |
456,26 → 443,5
end if; |
end process; |
|
addr_decoder: process is |
begin |
wait on reg_stb_i, reg_adr_i; |
|
v_mem_start_stb <= '0'; |
v_mem_end_stb <= '0'; |
reg_bank_stb <= '0'; |
|
if (reg_stb_i = '1') then |
case (reg_adr_i(reg_bank_size)) is |
when '0' => |
case (reg_adr_i(reg_bank_size-2)) is |
when '0' => v_mem_end_stb <= '1'; |
when '1' => v_mem_start_stb <= '1'; |
when others => |
end case; |
when '1' => reg_bank_stb <= '1'; |
when others => |
end case; |
end if; |
end process; |
end vga_core; |
|
/trunk/accel.vhd
22,6 → 22,7
generic ( |
accel_size: positive := 9; |
video_addr_width: positive := 20; |
video_data_width: positive := 16; |
data_width: positive := 16 |
); |
port ( |
48,12 → 49,11
-- Master interface to the video memory side. |
v_we_o: out std_logic; |
v_cyc_o: out std_logic; |
v_stb_o: out std_logic; |
v_sel_o: out std_logic; |
|
v_adr_o: out std_logic_vector (video_addr_width-1 downto 0); |
v_sel_o: out std_logic_vector ((data_width/8)-1 downto 0); |
v_dat_o: out std_logic_vector (data_width-1 downto 0); |
v_dat_i: in std_logic_vector (data_width-1 downto 0); |
v_dat_o: out std_logic_vector (video_data_width-1 downto 0); |
v_dat_i: in std_logic_vector (video_data_width-1 downto 0); |
|
v_ack_i: in std_logic |
); |
125,9 → 125,7
accel_ram_stb <= acc_stb_i or mem_stb_i; |
accel_ram_we <= we_i and acc_stb_i; |
accel_ram_clk <= clk_i; |
accel_ram_dat_i(min2(video_addr_width-1 |
,data_width-1) downto 0) <= |
dat_i(min2(video_addr_width,data_width) - 1 downto 0); |
accel_ram_dat_i(min(video_addr_width,data_width)-1 downto 0) <= dat_i; |
high_accel_dat_gen: if (video_addr_width > data_width) generate |
accel_ram_dat_i(video_addr_width-1 downto data_width) <= ext_value; |
end generate; |
147,7 → 145,7
ack_o => accel_ram_ack |
); |
|
v_stb_o <= mem_stb_i; |
v_sel_o <= mem_stb_i; |
v_cyc_o <= mem_stb_i and cyc_i; |
v_adr_o <= cursor; |
v_we_o <= we_i; |
166,7 → 164,7
port map ( |
clk_i => clk_i, |
rst_i => rst_i, |
rst_val => (video_addr_width - data_width-1 downto 0 => '0'), |
rst_val => (others => '0'), |
|
cyc_i => cyc_i, |
stb_i => ext_stb_i, |
190,15 → 188,10
end generate; |
|
cur_reg: wb_io_reg |
generic map ( |
width => video_addr_width, |
bus_width => data_width, |
offset => 0 |
) |
port map ( |
clk_i => clk_i, |
rst_i => rst_i, |
rst_val => (video_addr_width-1 downto 0 => '0'), |
rst_val => (others => '0'), |
|
cyc_i => cyc_i, |
stb_i => cur_stb_i, |
217,20 → 210,11
|
cur_update <= mem_stb_i and cyc_i and v_ack_i; |
|
v_sel_o <= sel_i; |
gen_dat_o: for i in dat_o'RANGE generate |
gen_dat_o1: if (i < video_addr_width) generate |
mem_dat_o(i) <= ( |
(cyc_i and ((accel_ram_d_out(i) and acc_stb_i) or (v_dat_i(i) and mem_stb_i))) or |
(dat_oi(i) and ((not (acc_stb_i or mem_stb_i or cur_stb_i)) or (not cyc_i))) |
); |
end generate; |
gen_dat_o2: if (i >= video_addr_width) generate |
mem_dat_o(i) <= ( |
(cyc_i and (('0' and acc_stb_i) or (v_dat_i(i) and mem_stb_i))) or |
(dat_oi(i) and ((not (acc_stb_i or mem_stb_i or cur_stb_i)) or (not cyc_i))) |
); |
end generate; |
mem_dat_o(i) <= ( |
(cyc_i and ((accel_ram_d_out(i) and acc_stb_i) or (v_dat_i(i) and mem_stb_i))) or |
(dat_oi(i) and ((not (acc_stb_i or mem_stb_i or cur_stb_i)) or (not cyc_i))) |
); |
end generate; |
mem_ack_o <= ( |
(cyc_i and ((accel_ram_ack and acc_stb_i) or (v_ack_i and mem_stb_i))) or |
/trunk/video_engine.vhd
23,8 → 23,7
clk_en: in std_logic := '1'; |
reset: in std_logic := '0'; |
|
v_mem_end: in std_logic_vector(v_addr_width-1 downto 0); -- video memory end address in words |
v_mem_start: in std_logic_vector(v_addr_width-1 downto 0) := (others => '0'); -- video memory start adderss in words |
total: in std_logic_vector(v_addr_width-1 downto 0); -- total video memory size in bytes 7..0 |
fifo_treshold: in std_logic_vector(7 downto 0); -- priority change threshold |
bpp: in std_logic_vector(1 downto 0); -- number of bits makes up a pixel valid values: 1,2,4,8 |
multi_scan: in std_logic_vector(1 downto 0); -- number of repeated scans |
97,8 → 96,7
pix_clk_en: in std_logic; |
reset: in std_logic := '0'; |
|
v_mem_end: in std_logic_vector(v_addr_width-1 downto 0); -- video memory end address in words |
v_mem_start: in std_logic_vector(v_addr_width-1 downto 0) := (others => '0'); -- video memory start adderss in words |
total: in std_logic_vector(v_addr_width-1 downto 0); -- total video memory size in bytes 7..0 |
fifo_treshold: in std_logic_vector(7 downto 0); -- priority change threshold |
bpp: in std_logic_vector(1 downto 0); -- number of bits makes up a pixel valid values: 1,2,4,8 |
multi_scan: in std_logic_vector(1 downto 0); -- number of repeated scans |
161,8 → 159,7
clk_en => clk_en, |
pix_clk_en => pix_clk_en, |
reset => reset, |
v_mem_end => v_mem_end, |
v_mem_start => v_mem_start, |
total => total, |
fifo_treshold => fifo_treshold, |
bpp => bpp, |
multi_scan => multi_scan, |
/trunk/wb_tk.vhd
0,0 → 1,914
-- |
-- 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. |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
package wb_tk is |
component wb_bus_upsize is |
generic ( |
m_bus_width: positive := 8; -- master bus width |
m_addr_width: positive := 21; -- master bus width |
s_bus_width: positive := 16; -- slave bus width |
s_addr_width: positive := 20; -- master bus width |
little_endien: boolean := true -- if set to false, big endien |
); |
port ( |
-- clk_i: in std_logic; |
-- rst_i: in std_logic := '0'; |
|
-- Master bus interface |
m_adr_i: in std_logic_vector (m_addr_width-1 downto 0); |
m_sel_i: in std_logic_vector ((m_bus_width/8)-1 downto 0) := (others => '1'); |
m_dat_i: in std_logic_vector (m_bus_width-1 downto 0); |
m_dat_oi: in std_logic_vector (m_bus_width-1 downto 0) := (others => '-'); |
m_dat_o: out std_logic_vector (m_bus_width-1 downto 0); |
m_cyc_i: in std_logic; |
m_ack_o: out std_logic; |
m_ack_oi: in std_logic := '-'; |
m_err_o: out std_logic; |
m_err_oi: in std_logic := '-'; |
m_rty_o: out std_logic; |
m_rty_oi: in std_logic := '-'; |
m_we_i: in std_logic; |
m_stb_i: in std_logic; |
|
-- Slave bus interface |
s_adr_o: out std_logic_vector (s_addr_width-1 downto 0); |
s_sel_o: out std_logic_vector ((s_bus_width/8)-1 downto 0); |
s_dat_i: in std_logic_vector (s_bus_width-1 downto 0); |
s_dat_o: out std_logic_vector (s_bus_width-1 downto 0); |
s_cyc_o: out std_logic; |
s_ack_i: in std_logic; |
s_err_i: in std_logic := '-'; |
s_rty_i: in std_logic := '-'; |
s_we_o: out std_logic; |
s_stb_o: out std_logic |
); |
end component; |
|
component wb_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 component; |
|
component wb_async_slave is |
generic ( |
width: positive := 16; |
addr_width: positive := 20 |
); |
port ( |
clk_i: in std_logic; |
rst_i: in std_logic := '0'; |
|
-- interface for wait-state generator state-machine |
wait_state: in std_logic_vector (3 downto 0); |
|
-- interface to wishbone master device |
adr_i: in std_logic_vector (addr_width-1 downto 0); |
sel_i: in std_logic_vector ((addr_width/8)-1 downto 0); |
dat_i: in std_logic_vector (width-1 downto 0); |
dat_o: out std_logic_vector (width-1 downto 0); |
dat_oi: in std_logic_vector (width-1 downto 0) := (others => '-'); |
we_i: in std_logic; |
stb_i: in std_logic; |
ack_o: out std_logic := '0'; |
ack_oi: in std_logic := '-'; |
|
-- interface to async slave |
a_data: inout std_logic_vector (width-1 downto 0) := (others => 'Z'); |
a_addr: out std_logic_vector (addr_width-1 downto 0) := (others => 'U'); |
a_rdn: out std_logic := '1'; |
a_wrn: out std_logic := '1'; |
a_cen: out std_logic := '1'; |
-- byte-enable signals |
a_byen: out std_logic_vector ((width/8)-1 downto 0) |
); |
end component; |
|
component wb_arbiter is |
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 is |
generic ( |
width : positive := 8; |
bus_width: positive := 8; |
offset: integer := 0 |
); |
port ( |
clk_i: in std_logic; |
rst_i: in std_logic; |
rst_val: std_logic_vector(width-1 downto 0) := (others => '0'); |
|
dat_i: in std_logic_vector (bus_width-1 downto 0); |
dat_oi: in std_logic_vector (bus_width-1 downto 0) := (others => '-'); |
dat_o: out std_logic_vector (bus_width-1 downto 0); |
q: out std_logic_vector (width-1 downto 0); |
we_i: in std_logic; |
stb_i: in std_logic; |
ack_o: out std_logic; |
ack_oi: in std_logic := '-' |
); |
end component; |
end wb_tk; |
|
------------------------------------------------------------------------------- |
-- |
-- wb_bus_upsize |
-- |
------------------------------------------------------------------------------- |
|
library IEEE; |
library synopsys; |
use IEEE.std_logic_1164.all; |
use synopsys.std_logic_arith.all; |
|
library work; |
use work.technology.all; |
|
entity wb_bus_upsize is |
generic ( |
m_bus_width: positive := 8; -- master bus width |
m_addr_width: positive := 21; -- master bus width |
s_bus_width: positive := 16; -- slave bus width |
s_addr_width: positive := 20; -- master bus width |
little_endien: boolean := true -- if set to false, big endien |
); |
port ( |
-- clk_i: in std_logic; |
-- rst_i: in std_logic := '0'; |
|
-- Master bus interface |
m_adr_i: in std_logic_vector (m_addr_width-1 downto 0); |
m_sel_i: in std_logic_vector ((m_bus_width/8)-1 downto 0) := (others => '1'); |
m_dat_i: in std_logic_vector (m_bus_width-1 downto 0); |
m_dat_oi: in std_logic_vector (m_bus_width-1 downto 0) := (others => '-'); |
m_dat_o: out std_logic_vector (m_bus_width-1 downto 0); |
m_cyc_i: in std_logic; |
m_ack_o: out std_logic; |
m_ack_oi: in std_logic := '-'; |
m_err_o: out std_logic; |
m_err_oi: in std_logic := '-'; |
m_rty_o: out std_logic; |
m_rty_oi: in std_logic := '-'; |
m_we_i: in std_logic; |
m_stb_i: in std_logic; |
|
-- Slave bus interface |
s_adr_o: out std_logic_vector (s_addr_width-1 downto 0); |
s_sel_o: out std_logic_vector ((s_bus_width/8)-1 downto 0); |
s_dat_i: in std_logic_vector (s_bus_width-1 downto 0); |
s_dat_o: out std_logic_vector (s_bus_width-1 downto 0); |
s_cyc_o: out std_logic; |
s_ack_i: in std_logic; |
s_err_i: in std_logic := '-'; |
s_rty_i: in std_logic := '-'; |
s_we_o: out std_logic; |
s_stb_o: out std_logic |
); |
end wb_bus_upsize; |
|
architecture wb_bus_upsize of wb_bus_upsize is |
function log2(inp : integer) return integer is |
begin |
if (inp < 1) then return 0; end if; |
if (inp < 2) then return 0; end if; |
if (inp < 4) then return 1; end if; |
if (inp < 8) then return 2; end if; |
if (inp < 16) then return 3; end if; |
if (inp < 32) then return 4; end if; |
if (inp < 64) then return 5; end if; |
if (inp < 128) then return 6; end if; |
if (inp < 256) then return 7; end if; |
if (inp < 512) then return 8; end if; |
if (inp < 1024) then return 9; end if; |
if (inp < 2048) then return 10; end if; |
if (inp < 4096) then return 11; end if; |
if (inp < 8192) then return 12; end if; |
if (inp < 16384) then return 13; end if; |
if (inp < 32768) then return 14; end if; |
if (inp < 65538) then return 15; end if; |
return 16; |
end; |
function equ(a : std_logic_vector; b : integer) return boolean is |
variable b_s : std_logic_vector(a'RANGE); |
begin |
b_s := CONV_STD_LOGIC_VECTOR(b,a'HIGH+1); |
return (a = b_s); |
end; |
constant addr_diff: integer := log2(s_bus_width/m_bus_width); |
signal i_m_dat_o: std_logic_vector(m_bus_width-1 downto 0); |
begin |
assert (m_addr_width = s_addr_width+addr_diff) report "Address widths are not consistent" severity FAILURE; |
s_adr_o <= m_adr_i(m_addr_width-addr_diff downto addr_diff); |
s_we_o <= m_we_i; |
m_ack_o <= (m_stb_i and s_ack_i) or (not m_stb_i and m_ack_oi); |
m_err_o <= (m_stb_i and s_err_i) or (not m_stb_i and m_err_oi); |
m_rty_o <= (m_stb_i and s_rty_i) or (not m_stb_i and m_rty_oi); |
s_stb_o <= m_stb_i; |
s_cyc_o <= m_cyc_i; |
|
|
sel_dat_mux: process is |
begin |
wait on s_dat_i, m_adr_i; |
if (little_endien) then |
for i in s_sel_o'RANGE loop |
if (equ(m_adr_i(addr_diff-1 downto 0),i)) then |
s_sel_o(i) <= '1'; |
i_m_dat_o <= s_dat_i(8*i+7 downto 8*i+0); |
else |
s_sel_o(i) <= '0'; |
end if; |
end loop; |
else |
for i in s_sel_o'RANGE loop |
if (equ(m_adr_i(addr_diff-1 downto 0),i)) then |
s_sel_o(s_sel_o'HIGH-i) <= '1'; |
i_m_dat_o <= s_dat_i(s_dat_i'HIGH-8*i downto s_dat_i'HIGH-8*i-7); |
else |
s_sel_o(s_sel_o'HIGH-i) <= '0'; |
end if; |
end loop; |
end if; |
end process; |
|
d_i_for: for i in m_dat_o'RANGE generate |
m_dat_o(i) <= (m_stb_i and i_m_dat_o(i)) or (not m_stb_i and m_dat_oi(i)); |
end generate; |
|
d_o_for: for i in s_sel_o'RANGE generate |
s_dat_o(8*i+7 downto 8*i+0) <= m_dat_i; |
end generate; |
end wb_bus_upsize; |
|
------------------------------------------------------------------------------- |
-- |
-- wb_async_master |
-- |
------------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
library work; |
use work.technology.all; |
|
entity wb_async_master is |
generic ( |
width: positive := 16; |
addr_width: positive := 20 |
); |
port ( |
clk_i: in std_logic; |
rst_i: in std_logic := '0'; |
|
-- interface to wb slave devices |
s_adr_o: out std_logic_vector (addr_width-1 downto 0); |
s_sel_o: out std_logic_vector ((width/8)-1 downto 0); |
s_dat_i: in std_logic_vector (width-1 downto 0); |
s_dat_o: out std_logic_vector (width-1 downto 0); |
s_cyc_o: out std_logic; |
s_ack_i: in std_logic; |
s_err_i: in std_logic := '-'; |
s_rty_i: in std_logic := '-'; |
s_we_o: out std_logic; |
s_stb_o: out std_logic; |
|
-- interface to asyncron master device |
a_data: inout std_logic_vector (width-1 downto 0) := (others => 'Z'); |
a_addr: in std_logic_vector (addr_width-1 downto 0) := (others => 'U'); |
a_rdn: in std_logic := '1'; |
a_wrn: in std_logic := '1'; |
a_cen: in std_logic := '1'; |
a_byen: in std_logic_vector ((width/8)-1 downto 0); |
a_waitn: out std_logic |
); |
end wb_async_master; |
|
architecture wb_async_master of wb_async_master is |
component d_ff |
port ( d : in STD_LOGIC; |
clk: in STD_LOGIC; |
ena: in STD_LOGIC := '1'; |
clr: in STD_LOGIC := '0'; |
pre: in STD_LOGIC := '0'; |
q : out STD_LOGIC |
); |
end component; |
signal wg_clk, wg_pre, wg_q: std_logic; |
signal i_cyc_o, i_stb_o, i_we_o: std_logic; |
signal i_waitn: std_logic; |
begin |
ctrl: process is |
begin |
wait until clk_i'EVENT and clk_i = '1'; |
if (rst_i = '1') then |
i_cyc_o <= '0'; |
i_stb_o <= '0'; |
i_we_o <= '0'; |
else |
if (a_cen = '0') then |
i_stb_o <= not (a_rdn and a_wrn); |
i_we_o <= not a_wrn; |
i_cyc_o <= '1'; |
else |
i_cyc_o <= '0'; |
i_stb_o <= '0'; |
i_we_o <= '0'; |
end if; |
end if; |
end process; |
s_cyc_o <= i_cyc_o and not i_waitn; |
s_stb_o <= i_stb_o and not i_waitn; |
s_we_o <= i_we_o and not i_waitn; |
|
w_ff1: d_ff port map ( |
d => s_ack_i, |
clk => clk_i, |
ena => '1', |
clr => rst_i, |
pre => '0', |
q => wg_q |
); |
|
wg_clk <= not a_cen; |
wg_pre <= wg_q or rst_i; |
w_ff2: d_ff port map ( |
d => '0', |
clk => wg_clk, |
ena => '1', |
clr => '0', |
pre => wg_pre, |
q => i_waitn |
); |
a_waitn <= i_waitn; |
|
s_adr_o <= a_addr; |
negate: for i in s_sel_o'RANGE generate s_sel_o(i) <= not a_byen(i); end generate; |
s_dat_o <= a_data; |
|
a_data_out: process is |
begin |
wait on s_dat_i, a_rdn, a_cen; |
if (a_rdn = '0' and a_cen = '0') then |
a_data <= s_dat_i; |
else |
a_data <= (others => 'Z'); |
end if; |
end process; |
end wb_async_master; |
|
------------------------------------------------------------------------------- |
-- |
-- wb_async_slave |
-- |
------------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
library work; |
use work.technology.all; |
|
entity wb_async_slave is |
generic ( |
width: positive := 16; |
addr_width: positive := 20 |
); |
port ( |
clk_i: in std_logic; |
rst_i: in std_logic := '0'; |
|
-- interface for wait-state generator state-machine |
wait_state: in std_logic_vector (3 downto 0); |
|
-- interface to wishbone master device |
adr_i: in std_logic_vector (addr_width-1 downto 0); |
sel_i: in std_logic_vector ((addr_width/8)-1 downto 0); |
dat_i: in std_logic_vector (width-1 downto 0); |
dat_o: out std_logic_vector (width-1 downto 0); |
dat_oi: in std_logic_vector (width-1 downto 0) := (others => '-'); |
we_i: in std_logic; |
stb_i: in std_logic; |
ack_o: out std_logic := '0'; |
ack_oi: in std_logic := '-'; |
|
-- interface to async slave |
a_data: inout std_logic_vector (width-1 downto 0) := (others => 'Z'); |
a_addr: out std_logic_vector (addr_width-1 downto 0) := (others => 'U'); |
a_rdn: out std_logic := '1'; |
a_wrn: out std_logic := '1'; |
a_cen: out std_logic := '1'; |
-- byte-enable signals |
a_byen: out std_logic_vector ((width/8)-1 downto 0) |
); |
end wb_async_slave; |
|
architecture wb_async_slave of wb_async_slave is |
-- multiplexed access signals to memory |
signal i_ack: std_logic; |
signal sm_ack: std_logic; |
|
type states is (sm_idle, sm_wait, sm_deact); |
signal state: states; |
signal cnt: std_logic_vector(3 downto 0); |
begin |
ack_o <= (stb_i and i_ack) or (not stb_i and ack_oi); |
dat_o_gen: for i in dat_o'RANGE generate |
dat_o(i) <= (stb_i and a_data(i)) or (not stb_i and dat_oi(i)); |
end generate; |
|
-- For 0WS operation i_ack is an async signal otherwise it's a sync one. |
i_ack_gen: process is |
begin |
wait on sm_ack, stb_i, wait_state, state; |
if (wait_state = "0000") then |
case (state) is |
when sm_deact => i_ack <= '0'; |
when others => i_ack <= stb_i; |
end case; |
else |
i_ack <= sm_ack; |
end if; |
end process; |
|
-- SRAM signal-handler process |
sram_signals: process is |
begin |
wait on state,we_i,a_data,adr_i,rst_i, stb_i, sel_i, dat_i; |
if (rst_i = '1') then |
a_wrn <= '1'; |
a_rdn <= '1'; |
a_cen <= '1'; |
a_addr <= (others => '-'); |
a_data <= (others => 'Z'); |
a_byen <= (others => '1'); |
else |
case (state) is |
when sm_deact => |
a_wrn <= '1'; |
a_rdn <= '1'; |
a_cen <= '1'; |
a_addr <= (others => '-'); |
a_data <= (others => 'Z'); |
a_byen <= (others => '1'); |
when others => |
a_addr <= adr_i; |
a_rdn <= not (not we_i and stb_i); |
a_wrn <= not (we_i and stb_i); |
a_cen <= not stb_i; |
a_byen <= not sel_i; |
if (we_i = '1') then |
a_data <= dat_i; |
else |
a_data <= (others => 'Z'); |
end if; |
end case; |
end if; |
end process; |
|
-- Aysnc access state-machine. |
async_sm: process is |
-- variable cnt: std_logic_vector(3 downto 0) := "0000"; |
-- variable state: states := init; |
begin |
wait until clk_i'EVENT and clk_i = '1'; |
if (rst_i = '1') then |
state <= sm_idle; |
cnt <= ((0) => '1', others => '0'); |
sm_ack <= '0'; |
else |
case (state) is |
when sm_idle => |
-- Check if anyone needs access to the memory. |
-- it's rdy signal will already be pulled low, so we only have to start the access |
if (stb_i = '1') then |
case wait_state is |
when "0000" => |
sm_ack <= '1'; |
state <= sm_deact; |
when "0001" => |
sm_ack <= '1'; |
cnt <= "0001"; |
state <= sm_wait; |
when others => |
sm_ack <= '0'; |
cnt <= "0001"; |
state <= sm_wait; |
end case; |
end if; |
when sm_wait => |
if (cnt = wait_state) then |
-- wait cycle completed. |
state <= sm_deact; |
sm_ack <= '0'; |
cnt <= "0000"; |
else |
if (add_one(cnt) = wait_state) then |
sm_ack <= '1'; |
else |
sm_ack <= '0'; |
end if; |
cnt <= add_one(cnt); |
end if; |
when sm_deact => |
if (stb_i = '1') then |
case wait_state is |
when "0000" => |
cnt <= "0000"; |
sm_ack <= '0'; |
state <= sm_wait; |
when others => |
sm_ack <= '0'; |
cnt <= "0000"; |
state <= sm_wait; |
end case; |
else |
sm_ack <= '0'; |
state <= sm_idle; |
end if; |
end case; |
end if; |
end process; |
end wb_async_slave; |
|
------------------------------------------------------------------------------- |
-- |
-- wb_arbiter |
-- |
------------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
library work; |
use work.technology.all; |
|
entity wb_arbiter is |
port ( |
-- clk: in std_logic; |
rst_i: in std_logic := '0'; |
|
-- interface to master device a |
a_we_i: in std_logic; |
a_stb_i: in std_logic; |
a_cyc_i: in std_logic; |
a_ack_o: out std_logic; |
a_ack_oi: in std_logic := '-'; |
a_err_o: out std_logic; |
a_err_oi: in std_logic := '-'; |
a_rty_o: out std_logic; |
a_rty_oi: in std_logic := '-'; |
|
-- interface to master device b |
b_we_i: in std_logic; |
b_stb_i: in std_logic; |
b_cyc_i: in std_logic; |
b_ack_o: out std_logic; |
b_ack_oi: in std_logic := '-'; |
b_err_o: out std_logic; |
b_err_oi: in std_logic := '-'; |
b_rty_o: out std_logic; |
b_rty_oi: in std_logic := '-'; |
|
-- interface to shared devices |
s_we_o: out std_logic; |
s_stb_o: out std_logic; |
s_cyc_o: out std_logic; |
s_ack_i: in std_logic; |
s_err_i: in std_logic := '-'; |
s_rty_i: in std_logic := '-'; |
|
mux_signal: out std_logic; -- 0: select A signals, 1: select B signals |
|
-- misc control lines |
priority: in std_logic -- 0: A have priority over B, 1: B have priority over A |
); |
end wb_arbiter; |
|
-- This acthitecture is a clean asyncron state-machine. However it cannot be mapped to FPGA architecture |
architecture behaviour of wb_arbiter is |
type states is (idle,aa,ba); |
signal i_mux_signal: std_logic; |
|
signal e_state: states; |
begin |
mux_signal <= i_mux_signal; |
|
sm: process is |
variable state: states; |
begin |
wait on a_cyc_i, b_cyc_i, priority, rst_i; |
if (rst_i = '1') then |
state := idle; |
i_mux_signal <= priority; |
else |
case (state) is |
when idle => |
if (a_cyc_i = '1' and (priority = '0' or b_cyc_i = '0')) then |
state := aa; |
i_mux_signal <= '0'; |
elsif (b_cyc_i = '1' and (priority = '1' or a_cyc_i = '0')) then |
state := ba; |
i_mux_signal <= '1'; |
else |
i_mux_signal <= priority; |
end if; |
when aa => |
if (a_cyc_i = '0') then |
if (b_cyc_i = '1') then |
state := ba; |
i_mux_signal <= '1'; |
else |
state := idle; |
i_mux_signal <= priority; |
end if; |
else |
i_mux_signal <= '0'; |
end if; |
when ba => |
if (b_cyc_i = '0') then |
if (a_cyc_i = '1') then |
state := aa; |
i_mux_signal <= '0'; |
else |
state := idle; |
i_mux_signal <= priority; |
end if; |
else |
i_mux_signal <= '1'; |
end if; |
end case; |
end if; |
e_state <= state; |
end process; |
|
signal_mux: process is |
begin |
wait on a_we_i, a_stb_i, a_ack_oi, a_err_oi, a_rty_oi, a_cyc_i, |
b_we_i, b_stb_i, b_ack_oi, b_err_oi, b_rty_oi, b_cyc_i, |
s_ack_i, s_err_i, s_rty_i, i_mux_signal; |
if (i_mux_signal = '0') then |
s_we_o <= a_we_i; |
s_stb_o <= a_stb_i; |
s_cyc_o <= a_cyc_i; |
a_ack_o <= (a_stb_i and s_ack_i) or (not a_stb_i and a_ack_oi); |
a_err_o <= (a_stb_i and s_err_i) or (not a_stb_i and a_err_oi); |
a_rty_o <= (a_stb_i and s_rty_i) or (not a_stb_i and a_rty_oi); |
b_ack_o <= (b_stb_i and '0') or (not b_stb_i and b_ack_oi); |
b_err_o <= (b_stb_i and '0') or (not b_stb_i and b_err_oi); |
b_rty_o <= (b_stb_i and '0') or (not b_stb_i and b_rty_oi); |
else |
s_we_o <= b_we_i; |
s_stb_o <= b_stb_i; |
s_cyc_o <= b_cyc_i; |
b_ack_o <= (b_stb_i and s_ack_i) or (not b_stb_i and b_ack_oi); |
b_err_o <= (b_stb_i and s_err_i) or (not b_stb_i and b_err_oi); |
b_rty_o <= (b_stb_i and s_rty_i) or (not b_stb_i and b_rty_oi); |
a_ack_o <= (a_stb_i and '0') or (not a_stb_i and a_ack_oi); |
a_err_o <= (a_stb_i and '0') or (not a_stb_i and a_err_oi); |
a_rty_o <= (a_stb_i and '0') or (not a_stb_i and a_rty_oi); |
end if; |
end process; |
end behaviour; |
|
-- This acthitecture is a more-or-less structural implementation. Fits for FPGA realization. |
architecture FPGA of wb_arbiter is |
component d_ff |
port ( d : in STD_LOGIC; |
clk: in STD_LOGIC; |
ena: in STD_LOGIC := '1'; |
clr: in STD_LOGIC := '0'; |
pre: in STD_LOGIC := '0'; |
q : out STD_LOGIC |
); |
end component; |
|
signal i_mux_signal: std_logic; |
|
type states is (idle,aa,ba,XX); |
signal e_state: states; |
|
-- signals for a DFF in FPGA |
signal idle_s, aa_s, ba_s: std_logic; |
|
signal aa_clk, aa_ena, aa_clr, aa_pre: std_logic; |
signal ba_clk, ba_ena, ba_clr, ba_pre: std_logic; |
|
begin |
mux_signal <= i_mux_signal; |
|
idle_s <= not (a_cyc_i or b_cyc_i); |
|
aa_clr <= rst_i or not a_cyc_i; |
aa_clk <= a_cyc_i; |
aa_ena <= not b_cyc_i and priority; |
aa_pre <= (a_cyc_i and not priority and not ba_s) or (a_cyc_i and not b_cyc_i); |
aa_ff: d_ff port map ( |
d => '1', |
clk => aa_clk, |
ena => aa_ena, |
clr => aa_clr, |
pre => aa_pre, |
q => aa_s |
); |
|
ba_clr <= rst_i or not b_cyc_i; |
ba_clk <= b_cyc_i; |
ba_ena <= not a_cyc_i and not priority; |
ba_pre <= (b_cyc_i and priority and not aa_s) or (b_cyc_i and not a_cyc_i); |
ba_ff: d_ff port map ( |
d => '1', |
clk => ba_clk, |
ena => ba_ena, |
clr => ba_clr, |
pre => ba_pre, |
q => ba_s |
); |
|
i_mux_signal <= (priority and idle_s) or ba_s; |
|
signal_mux: process is |
begin |
wait on a_we_i, a_stb_i, a_ack_oi, a_err_oi, a_rty_oi, a_cyc_i, |
b_we_i, b_stb_i, b_ack_oi, b_err_oi, b_rty_oi, b_cyc_i, |
s_ack_i, s_err_i, s_rty_i, i_mux_signal; |
if (i_mux_signal = '0') then |
s_we_o <= a_we_i; |
s_stb_o <= a_stb_i; |
s_cyc_o <= a_cyc_i; |
a_ack_o <= (a_stb_i and s_ack_i) or (not a_stb_i and a_ack_oi); |
a_err_o <= (a_stb_i and s_err_i) or (not a_stb_i and a_err_oi); |
a_rty_o <= (a_stb_i and s_rty_i) or (not a_stb_i and a_rty_oi); |
b_ack_o <= (b_stb_i and '0') or (not b_stb_i and b_ack_oi); |
b_err_o <= (b_stb_i and '0') or (not b_stb_i and b_err_oi); |
b_rty_o <= (b_stb_i and '0') or (not b_stb_i and b_rty_oi); |
else |
s_we_o <= b_we_i; |
s_stb_o <= b_stb_i; |
s_cyc_o <= b_cyc_i; |
b_ack_o <= (b_stb_i and s_ack_i) or (not b_stb_i and b_ack_oi); |
b_err_o <= (b_stb_i and s_err_i) or (not b_stb_i and b_err_oi); |
b_rty_o <= (b_stb_i and s_rty_i) or (not b_stb_i and b_rty_oi); |
a_ack_o <= (a_stb_i and '0') or (not a_stb_i and a_ack_oi); |
a_err_o <= (a_stb_i and '0') or (not a_stb_i and a_err_oi); |
a_rty_o <= (a_stb_i and '0') or (not a_stb_i and a_rty_oi); |
end if; |
end process; |
|
gen_e_state: process is |
begin |
wait on idle_s,aa_s,ba_s; |
if (idle_s = '1' and ba_s = '0' and aa_s = '0') then e_state <= idle; |
elsif (idle_s = '0' and ba_s = '1' and aa_s = '0') then e_state <= aa; |
elsif (idle_s = '0' and ba_s = '0' and aa_s = '1') then e_state <= ba; |
else e_state <= XX; |
end if; |
end process; |
end FPGA; |
|
------------------------------------------------------------------------------- |
-- |
-- wb_out_reg |
-- |
------------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
library work; |
use work.technology.all; |
|
entity wb_out_reg is |
generic ( |
width : positive := 8; |
bus_width: positive := 8; |
offset: integer := 0 |
); |
port ( |
clk_i: in std_logic; |
rst_i: in std_logic; |
rst_val: std_logic_vector(width-1 downto 0) := (others => '0'); |
|
dat_i: in std_logic_vector (bus_width-1 downto 0); |
dat_oi: in std_logic_vector (bus_width-1 downto 0) := (others => '-'); |
dat_o: out std_logic_vector (bus_width-1 downto 0); |
q: out std_logic_vector (width-1 downto 0); |
we_i: in std_logic; |
stb_i: in std_logic; |
ack_o: out std_logic; |
ack_oi: in std_logic := '-' |
); |
end wb_out_reg; |
|
architecture wb_out_reg of wb_out_reg is |
signal content : std_logic_vector (width-1 downto 0); |
begin |
-- output bus handling with logic |
gen_dat_o: process is |
variable rd_sel: std_logic; |
begin |
wait on dat_oi, we_i, stb_i, content; |
rd_sel := stb_i and not we_i; |
for i in bus_width-1 downto 0 loop |
if (i >= offset and i < offset+width) then |
dat_o(i) <= (dat_oi(i) and not rd_sel) or (content(i-offset) and rd_sel); |
else |
dat_o(i) <= dat_oi(i); |
end if; |
end loop; |
end process; |
|
-- this item never generates any wait-states |
ack_o <= stb_i or ack_oi; |
|
reg: process is |
begin |
wait until clk_i'EVENT and clk_i='1'; |
if (rst_i = '1') then |
content <= rst_val; |
else |
if (stb_i = '1' and we_i = '1') then |
content <= dat_i(width+offset-1 downto offset); |
end if; |
end if; |
end process; |
q <= content; |
end wb_out_reg; |