head	1.2;
access;
symbols;
locks; strict;
comment	@# @;


1.2
date	2001.04.27.14.28.47;	author tantos;	state Exp;
branches;
next	1.1;

1.1
date	2001.04.25.15.04.05;	author tantos;	state Exp;
branches;
next	;


desc
@@


1.2
log
@Version 2 features tested, many small and large changes
@
text
@--
--  Address generator and accelerator.
--
--  (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.
--


-- Standard library.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

library wb_tk;
use wb_tk.technology.all;
use wb_tk.all;

library wb_vga;
use wb_vga.all;

entity accel is
	generic (
		accel_size: positive := 9;
		video_addr_width: positive := 20;
		data_width: positive := 16
	);
	port (
		clk_i: in std_logic;
		rst_i: in std_logic := '0';

		-- Slave interface to the CPU side
		we_i: in std_logic;
		cyc_i: in std_logic;
		cur_stb_i: in std_logic;
		ext_stb_i: in std_logic;
		acc_stb_i: in std_logic;
		mem_stb_i: in std_logic;
		
        sel_i: in std_logic_vector ((data_width/8)-1 downto 0) := (others => '1');
		adr_i: in std_logic_vector(accel_size-1 downto 0);
		dat_i: in std_logic_vector(data_width-1 downto 0);
		dat_o: out std_logic_vector(data_width-1 downto 0);
		dat_oi: in std_logic_vector(data_width-1 downto 0);

		ack_o: out std_logic;
		ack_oi: in std_logic;

		-- 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_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_ack_i: in std_logic
	);
end accel;

architecture accel of accel is
	component wb_io_reg
		generic (
			width : positive := video_addr_width;
			bus_width: positive := data_width;
			offset: integer := 0
		);
		port (
			clk_i: in std_logic;
			rst_i: in std_logic;
			rst_val: std_logic_vector(width-1 downto 0) := (others => '0');
	
	        cyc_i: in std_logic := '1';
			stb_i: in std_logic;
	        sel_i: in std_logic_vector ((bus_width/8)-1 downto 0) := (others => '1');
			we_i: in std_logic;
			ack_o: out std_logic;
			ack_oi: in std_logic := '-';
			adr_i: in std_logic_vector (size2bits((width+offset+bus_width-1)/bus_width)-1 downto 0) := (others => '0');
			dat_i: in std_logic_vector (bus_width-1 downto 0);
			dat_oi: in std_logic_vector (bus_width-1 downto 0) := (others => '-');
			dat_o: out std_logic_vector (bus_width-1 downto 0);
			q: out std_logic_vector (width-1 downto 0);
			ext_d: in std_logic_vector (width-1 downto 0) := (others => '-');
			ext_we: in std_logic := '0'
		);
	end component;
	
	component wb_ram 
		generic (
			data_width: positive := 8;
			addr_width: positive := 10
		);
		port (
	    	clk_i: in std_logic;
			adr_i: in std_logic_vector (addr_width-1 downto 0);
			dat_i: in std_logic_vector (data_width-1 downto 0);
			dat_oi: in std_logic_vector (data_width-1 downto 0) := (others => '-');
			dat_o: out std_logic_vector (data_width-1 downto 0);
			cyc_i: in std_logic;
			ack_o: out std_logic;
			ack_oi: in std_logic := '-';
			we_i: in std_logic;
			stb_i: in std_logic
		);
	end component;

	signal cursor: std_logic_vector(video_addr_width-1 downto 0);
	signal accel_ram_d_out: std_logic_vector(video_addr_width-1 downto 0);
	signal accel_ram_dat_i: std_logic_vector(video_addr_width-1 downto 0);
	signal accel_ram_stb: std_logic;
	signal accel_ram_ack: std_logic;
	signal accel_ram_we: std_logic;
	signal accel_ram_clk: std_logic;
	signal next_cur: std_logic_vector(video_addr_width-1 downto 0);
	signal cur_update: std_logic := '0';
	signal mem_ack_o: std_logic := '1';
	signal mem_dat_o: std_logic_vector(data_width-1 downto 0);
	signal cur_ack_o: std_logic := '1';
	signal cur_dat_o: std_logic_vector(data_width-1 downto 0);
	signal ext_value: std_logic_vector(max(video_addr_width - data_width,1)-1 downto 0);
	signal ext_ext_we: std_logic;
begin
	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);
	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;
	accel_ram: wb_ram 
		generic map (
			data_width => video_addr_width,
			addr_width => accel_size
		)
		port map (
			clk_i => clk_i,
			cyc_i => cyc_i,
			stb_i => accel_ram_stb,
			we_i => accel_ram_we,
			adr_i => adr_i,
			dat_i => accel_ram_dat_i,
			dat_o => accel_ram_d_out,
			ack_o => accel_ram_ack
		);

	v_stb_o <= mem_stb_i;
	v_cyc_o <= mem_stb_i and cyc_i;
	v_adr_o <= cursor;
	v_we_o <= we_i;
	v_dat_o <= dat_i;
	
	next_cur <= cursor + accel_ram_d_out;
	
	ext_ext_we <= acc_stb_i and not we_i;
	ext_reg_gen: if (video_addr_width > data_width) generate
		ext_reg: wb_io_reg
			generic map (
				width => video_addr_width - data_width,
				bus_width => data_width,
				offset => 0
			)
			port map (
				clk_i => clk_i,
				rst_i => rst_i,
				rst_val => (video_addr_width - data_width-1 downto 0 => '0'),
		
		        cyc_i => cyc_i,
				stb_i => ext_stb_i,
		        sel_i => sel_i,
				we_i => we_i,
				ack_o => ack_o,
				ack_oi => cur_ack_o,
				adr_i => adr_i(size2bits((video_addr_width-1)/data_width)-1 downto 0),
				dat_i => dat_i,
				dat_oi => cur_dat_o,
				dat_o => dat_o,
				q => ext_value,
				ext_d => accel_ram_d_out(video_addr_width-1 downto data_width),
				ext_we => ext_ext_we
			);
	end generate;
	ext_gen: if (video_addr_width <= data_width) generate
		dat_o <= cur_dat_o;
		ack_o <= cur_ack_o;
		ext_value(0) <= '0';
	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'),
	
	        cyc_i => cyc_i,
			stb_i => cur_stb_i,
	        sel_i => sel_i,
			we_i => we_i,
			ack_o => cur_ack_o,
			ack_oi => mem_ack_o,
			adr_i => adr_i(size2bits((video_addr_width+data_width-1)/data_width)-1 downto 0),
			dat_i => dat_i,
			dat_oi => mem_dat_o,
			dat_o => cur_dat_o,
			q => cursor,
			ext_d => next_cur,
			ext_we => cur_update
		);

	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;
	end generate;
	mem_ack_o <= (
		(cyc_i and ((accel_ram_ack and acc_stb_i) or (v_ack_i and mem_stb_i))) or 
		(ack_oi and ((not (acc_stb_i or mem_stb_i or cur_stb_i)) or (not cyc_i)))
	);

end accel;
@


1.1
log
@Major reorganization and some Phase 2 features added
@
text
@a24 1
		video_data_width: positive := 16;
d51 1
a51 1
		v_sel_o: out std_logic;
d54 3
a56 2
		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);
d128 3
a130 1
	accel_ram_dat_i(min(video_addr_width,data_width)-1 downto 0) <= dat_i;
d150 1
a150 1
	v_sel_o <= mem_stb_i;
d169 1
a169 1
				rst_val => (others => '0'),
d193 5
d201 1
a201 1
			rst_val => (others => '0'),
d220 1
d222 12
a233 4
		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)))
		);
@

