OpenCores
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_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;

powered by: WebSVN 2.1.0

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