head	1.21;
access;
symbols
	bg2_23:1.19
	bg2_22:1.19
	bg2_21:1.19
	bg2_20:1.19
	bg2_16:1.18
	bg2_15:1.17
	bg2_12:1.15
	bg2_07:1.15
	isorc2008_submission:1.9
	handbook_alpha_edition:1.9
	jtres2007_submission:1.9
	bg1_07:1.5
	bg1_06:1.5
	bg1_05:1.5
	TAL_101:1.5
	TAL_100:1.5
	jtres_submission:1.5
	wises06_submission:1.4
	lctes2006_submission:1.4
	rtgc_isorc2006:1.4.0.4
	isorc2006:1.4.0.2
	rtgc_paper:1.4;
locks; strict;
comment	@# @;


1.21
date	2008.10.10.22.18.29;	author martin;	state Exp;
branches;
next	1.20;
commitid	3c348efd4b44567;

1.20
date	2008.10.10.22.06.31;	author martin;	state Exp;
branches;
next	1.19;
commitid	7cb848efd1e54567;

1.19
date	2008.07.21.15.13.08;	author martin;	state Exp;
branches;
next	1.18;
commitid	45b4884a7834567;

1.18
date	2008.06.13.12.10.06;	author jeuneS2;	state Exp;
branches;
next	1.17;
commitid	1c61485263804567;

1.17
date	2008.05.29.16.47.44;	author 9914pich;	state Exp;
branches;
next	1.16;
commitid	445c483ede2e4567;

1.16
date	2008.05.28.17.43.26;	author jeuneS2;	state Exp;
branches;
next	1.15;
commitid	4168483d999e4567;

1.15
date	2008.04.30.17.00.37;	author jeuneS2;	state Exp;
branches;
next	1.14;
commitid	2924818a59a4567;

1.14
date	2008.03.03.13.42.49;	author martin;	state Exp;
branches;
next	1.13;
commitid	c3d47cc00574567;

1.13
date	2008.02.23.23.18.46;	author martin;	state Exp;
branches;
next	1.12;
commitid	b7347c0a9b84567;

1.12
date	2008.02.22.13.17.12;	author 9914pich;	state Exp;
branches;
next	1.11;
commitid	cdf47becb574567;

1.11
date	2008.02.20.14.29.32;	author martin;	state Exp;
branches;
next	1.10;
commitid	4d7c47bc39384567;

1.10
date	2008.02.19.10.19.28;	author jeuneS2;	state Exp;
branches;
next	1.9;
commitid	77f47baad164567;

1.9
date	2007.06.01.13.05.15;	author 9914pich;	state Exp;
branches;
next	1.8;
commitid	6473466019894567;

1.8
date	2007.04.14.19.26.37;	author martin;	state Exp;
branches;
next	1.7;
commitid	773d46212aea4567;

1.7
date	2007.04.14.18.38.11;	author martin;	state Exp;
branches;
next	1.6;
commitid	55a746211f8c4567;

1.6
date	2007.04.13.17.17.22;	author martin;	state Exp;
branches;
next	1.5;
commitid	43ae461fbb1e4567;

1.5
date	2006.06.15.15.59.43;	author martin;	state Exp;
branches;
next	1.4;
commitid	7f2d449183ec4567;

1.4
date	2005.12.02.20.48.54;	author martin;	state Exp;
branches;
next	1.3;
commitid	7ef34390b3304567;

1.3
date	2005.11.29.15.46.04;	author martin;	state Exp;
branches;
next	1.2;
commitid	48f4438c77b74567;

1.2
date	2005.11.28.18.41.31;	author martin;	state Exp;
branches;
next	1.1;
commitid	2891438b4f574567;

1.1
date	2005.11.24.20.51.40;	author martin;	state Exp;
branches;
next	;
commitid	2adc438627da4567;


desc
@@


1.21
log
@comment
@
text
@--
--
--  This file is a part of JOP, the Java Optimized Processor
--
--  Copyright (C) 2001-2008, Martin Schoeberl (martin@@jopdesign.com)
--
--  This program is free software: you can redistribute it and/or modify
--  it under the terms of the GNU General Public License as published by
--  the Free Software Foundation, either version 3 of the License, or
--  (at your option) any later version.
--
--  This program is distributed in the hope that it will be useful,
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--  GNU General Public License for more details.
--
--  You should have received a copy of the GNU General Public License
--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
--


--
--	mem_sc.vhd
--
--	External memory interface with SimpCon.
--	Translates between JOP/extension memory interface
--	and SimpCon memory interface.
--	Does the method cache load.
--
--
--	todo:
--
--	2005-11-22  first version adapted from mem(_wb)
--	2006-06-15	removed unnecessary state in BC load
--				len decrement in bc_rn and exit from bc_wr
--	2007-04-13	Changed memory connection to records
--	2007-04-14	xaload and xastore in hardware
--	2008-02-19	put/getfield in hardware
--	2008-04-30  copy step in hardware
--	2008-10-10	correct array access for fast (SPM) memory (+iald23 state)
--

Library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;

use work.jop_types.all;
use work.sc_pack.all;

entity mem_sc is
generic (jpc_width : integer; block_bits : integer);

port (

-- jop interface

	clk, reset	: in std_logic;

	ain		: in std_logic_vector(31 downto 0);		-- TOS
	bin		: in std_logic_vector(31 downto 0);		-- NOS

-- exceptions

	np_exc		: out std_logic;
	ab_exc		: out std_logic;

-- extension connection
	mem_in		: in mem_in_type;
	mem_out		: out mem_out_type;

-- jbc connections

	jbc_addr	: in std_logic_vector(jpc_width-1 downto 0);
	jbc_data	: out std_logic_vector(7 downto 0);

-- SimpCon interface

	sc_mem_out	: out sc_out_type;
	sc_mem_in	: in sc_in_type
);
end mem_sc;

architecture rtl of mem_sc is

component cache is
generic (jpc_width : integer; block_bits : integer);

port (

	clk, reset	: in std_logic;

	bc_len		: in std_logic_vector(METHOD_SIZE_BITS-1 downto 0);	-- length of method in words
	bc_addr		: in std_logic_vector(17 downto 0);		-- memory address of bytecode

	find		: in std_logic;					-- start lookup

	bcstart		: out std_logic_vector(jpc_width-3 downto 0); 	-- start of method in bc cache

	rdy		: out std_logic;				-- lookup finished
	in_cache	: out std_logic					-- method is in cache

);
end component;

--
--	jbc component (use technology specific vhdl-file cyc_jbc,...)
--
--	ajbc,xjbc are OLD!
--	check if ajbc.vhd can still be used (multicycle write!)
--
--	dual port ram
--	wraddr and wrena registered
--	rdaddr is registered
--	indata registered
--	outdata is unregistered
--

component jbc is
generic (jpc_width : integer);
port (
	clk		: in std_logic;
	data		: in std_logic_vector(31 downto 0);
	rd_addr		: in std_logic_vector(jpc_width-1 downto 0);
	wr_addr		: in std_logic_vector(jpc_width-3 downto 0);
	wr_en		: in std_logic;
	q		: out std_logic_vector(7 downto 0)
);
end component;


--
--	signals for mem interface
--
	type state_type		is (
							idl, rd1, wr1,
							bc_cc, bc_r1, bc_w, bc_rn, bc_wr, bc_wl,
							iald0, iald1, iald2, iald23, iald3, iald4,
							iasrd, ialrb,
							iast0, iaswb, iasrb, iasst,
							gf0, gf1, gf2, gf3,
							pf0, pf3,
							cp0, cp1, cp2, cp3, cp4, cpstop,
							last,
							npexc, abexc, excw
						);
	signal state 		: state_type;
	signal next_state	: state_type;

	-- length should be 'real' RAM size and not RAM + Flash + NAND
	-- should also be considered in the cacheable range

	-- addr_reg used to 'store' the address for wr, bc load, and array access
	signal addr_reg		: unsigned(SC_ADDR_SIZE-1 downto 0);
	signal addr_next	: unsigned(SC_ADDR_SIZE-1 downto 0);

	-- MUX for SimpCon address and write data
	signal ram_addr		: std_logic_vector(SC_ADDR_SIZE-1 downto 0);
	signal ram_wr_data	: std_logic_vector(31 downto 0);

--
--      signals for access from the state machine
--
	signal state_bsy	: std_logic;
	signal state_rd		: std_logic;
	signal state_wr		: std_logic;

--
--	signals for object and array access
--
	signal index		: std_logic_vector(SC_ADDR_SIZE-1 downto 0);	-- array or field index
	signal value		: std_logic_vector(31 downto 0);		-- store value

	signal null_pointer	: std_logic;
	signal bounds_error	: std_logic;

	signal was_a_store	: std_logic;

--
--	values for bytecode read/cache
--
--	len is in words, 10 bits range is 'hardcoded' in JOPWriter.java
--	start is address in external memory (rest of the word)
--
	signal bc_len		: unsigned(METHOD_SIZE_BITS-1 downto 0);	-- length of method in words
	signal inc_addr_reg	: std_logic;
	signal dec_len		: std_logic;
	signal bc_wr_addr	: unsigned(jpc_width-3 downto 0);	-- address for jbc (in words!)
	signal bc_wr_data	: std_logic_vector(31 downto 0);	-- write data for jbc
	signal bc_wr_ena	: std_logic;

--
--	signals for cache connection
--
	signal cache_rdy	: std_logic;
	signal cache_in_cache	: std_logic;
	signal cache_bcstart	: std_logic_vector(jpc_width-3 downto 0);

--
-- signals for copying and address translation
--
	signal base_reg		: unsigned(SC_ADDR_SIZE-1 downto 0);
	signal pos_reg		: unsigned(SC_ADDR_SIZE-1 downto 0);
    signal offset_reg	: unsigned(SC_ADDR_SIZE-1 downto 0);
	signal translate_bit : std_logic;
	signal cp_stopbit   : std_logic;

begin

process(sc_mem_in, state_bsy, state)
begin
	mem_out.bsy <= '0';
	if sc_mem_in.rdy_cnt=3 then
		mem_out.bsy <= '1';
	else
		if state/=ialrb and state/=last and state_bsy='1' then
			mem_out.bsy <= '1';
		end if;
	end if;
end process;

	mem_out.bcstart <= std_logic_vector(to_unsigned(0, 32-jpc_width)) & cache_bcstart & "00";


	np_exc <= null_pointer;
	ab_exc <= bounds_error;

	-- change byte order for jbc memory (high byte first)
	bc_wr_data <= sc_mem_in.rd_data(7 downto 0) &
				sc_mem_in.rd_data(15 downto 8) &
				sc_mem_in.rd_data(23 downto 16) &
				sc_mem_in.rd_data(31 downto 24);


	cmp_cache: cache generic map (jpc_width, block_bits) port map(
		clk, reset,
		std_logic_vector(bc_len), std_logic_vector(addr_reg(17 downto 0)),
		mem_in.bc_rd,
		cache_bcstart,
		cache_rdy, cache_in_cache
	);


	cmp_jbc: jbc generic map (jpc_width)
	port map(
		clk => clk,
		data => bc_wr_data,
		wr_en => bc_wr_ena,
		wr_addr => std_logic_vector(bc_wr_addr),
		rd_addr => jbc_addr,
		q => jbc_data
	);

--
--	SimpCon connections
--

	sc_mem_out.address <= ram_addr;
	sc_mem_out.wr_data <= ram_wr_data;
	sc_mem_out.rd <= mem_in.rd or state_rd;
	sc_mem_out.wr <= mem_in.wr or state_wr;
	mem_out.dout <= sc_mem_in.rd_data;


--
--	Store the write address
--	TODO: wouldn't it be easier to use A and B
--		for data and address with a single write
--		command?
--		- see jvm.asm...
--
--	and array access stores
--
process(clk, reset)
begin
	if reset='1' then
		addr_reg <= (others => '0');
		index <= (others => '0');
		value <= (others => '0');
		was_a_store <= '0';
		bc_len <= (others => '0');

		base_reg <= (others => '0');
		pos_reg <= (others => '0');
		offset_reg <= (others => '0');
		
	elsif rising_edge(clk) then
		if mem_in.bc_rd='1' then
			bc_len <= unsigned(ain(METHOD_SIZE_BITS-1 downto 0));
		else
			if dec_len='1' then
				bc_len <= bc_len-1;
			end if;
		end if;

		-- save array address and index
		if mem_in.iaload='1' or mem_in.getfield='1' then
			index <= ain(SC_ADDR_SIZE-1 downto 0);		-- store array index
		end if;
		-- first step of three-operand operations
		if mem_in.iastore='1' or mem_in.putfield='1' then
			value <= ain;
		end if;
		-- get reference and index for putfield and array stores
		if state=pf0 or state=iast0 then
			index <= ain(SC_ADDR_SIZE-1 downto 0);		-- store array index			
		end if;

		-- get source and index for copying
		if mem_in.copy='1' then
			base_reg <= unsigned(bin(SC_ADDR_SIZE-1 downto 0));
			pos_reg <= unsigned(ain(SC_ADDR_SIZE-1 downto 0)) + unsigned(bin(SC_ADDR_SIZE-1 downto 0));
			cp_stopbit <= ain(31);
		end if;
		-- get destination for copying
		if state=cp0 then
			offset_reg <= unsigned(bin(SC_ADDR_SIZE-1 downto 0)) - base_reg;
		end if;

		-- address and data tweaking for copying
		if state=cp3 then
			pos_reg <= pos_reg+1;
			value <= sc_mem_in.rd_data;
		end if;
		if state=cpstop then
			pos_reg <= base_reg;
		end if;

		-- precompute address translation
		if addr_next >= base_reg and addr_next < pos_reg then
			translate_bit <= '1';
		else
			translate_bit <= '0';
		end if;
		addr_reg <= addr_next;
		
		-- set flag for state sharing
		if mem_in.iaload='1' or mem_in.getfield='1' then
			was_a_store <= '0';
		elsif mem_in.iastore='1' or mem_in.putfield='1' then
			was_a_store <= '1';
		end if;		
	end if;
end process;


--
--	RAM address MUX (combinational)
--
process(ain, addr_reg, offset_reg, mem_in, base_reg, pos_reg, translate_bit)
begin
	if mem_in.rd='1' then
		if unsigned(ain(SC_ADDR_SIZE-1 downto 0)) >= base_reg and unsigned(ain(SC_ADDR_SIZE-1 downto 0)) < pos_reg then
			ram_addr <= std_logic_vector(unsigned(ain(SC_ADDR_SIZE-1 downto 0)) + offset_reg);
		else
			ram_addr <= ain(SC_ADDR_SIZE-1 downto 0);
		end if;
	else
		-- default is the registered address for wr, bc load
		if translate_bit='1' then
			ram_addr <= std_logic_vector(addr_reg(SC_ADDR_SIZE-1 downto 0) + offset_reg);
		else
			ram_addr <= std_logic_vector(addr_reg(SC_ADDR_SIZE-1 downto 0));
		end if;
	end if;
end process;

--
-- prepare RAM address registering
--
process(addr_reg, sc_mem_in, mem_in, ain, bin, state, inc_addr_reg, index, pos_reg, offset_reg)
begin

	-- default values
	addr_next <= addr_reg;	
	if inc_addr_reg='1' then
		addr_next <= addr_reg+1;
	end if;

	-- computations that depend on mem_in
	if mem_in.addr_wr='1' then
		addr_next <= unsigned(ain(SC_ADDR_SIZE-1 downto 0));
	end if;
	
	if mem_in.bc_rd='1' then
		addr_next(17 downto 0) <= unsigned(ain(27 downto 10));
		-- addr_bits is 17
		if SC_ADDR_SIZE>18 then
			addr_next(SC_ADDR_SIZE-1 downto 18) <= (others => '0');
		end if;
	end if;
	
	if mem_in.iaload='1' or mem_in.getfield='1' then
		addr_next <= unsigned(bin(SC_ADDR_SIZE-1 downto 0));
	end if;

	-- computations that depend on the state
	if state=pf0 or state=iast0 then
		addr_next <= unsigned(bin(SC_ADDR_SIZE-1 downto 0));
	end if;

	-- get/putfield could be optimized for faster memory (e.g. SPM)
	if state=iald3 or state=iald23 or state=gf2 then
		addr_next <= unsigned(sc_mem_in.rd_data(SC_ADDR_SIZE-1 downto 0))+unsigned(index);
	end if;

	if state=cp0 then
		addr_next <= pos_reg;
	end if;		

	if state=cp3 then
		addr_next <= pos_reg + offset_reg;
	end if;
	
end process;


--
--	RAM write data MUX (combinational)
--
process(ain, addr_reg, mem_in, value)
begin
	if mem_in.wr='1' then
		ram_wr_data <= ain;
	else
		-- default is the registered value
		ram_wr_data <= value;
	end if;
end process;


--
--	next state logic
--
process(state, mem_in, sc_mem_in,
	cache_rdy, cache_in_cache, bc_len, value, index, 
	addr_reg, cp_stopbit, was_a_store)
begin

	next_state <= state;

	case state is

		when idl =>
			if mem_in.rd='1' then
				next_state <= rd1;
			elsif mem_in.wr='1' then
				next_state <= wr1;
			elsif mem_in.bc_rd='1' then
				next_state <= bc_cc;
			elsif mem_in.iaload='1' then
				next_state <= iald0;
			elsif mem_in.getfield='1' then
				next_state <= gf0;
			elsif mem_in.putfield='1' then
				next_state <= pf0;
			elsif mem_in.copy='1' then
				next_state <= cp0;				
			elsif mem_in.iastore='1' then
				next_state <= iast0;
			end if;

		-- after a read the idl state is the result cycle
		-- where the data is available
		when rd1 =>
			-- either 1 or 0
			if sc_mem_in.rdy_cnt(1)='0' then
				next_state <= idl;
			end if;

		-- We could avoid the idl state after wr1 to
		-- get back to back wr/wr or wr/rd.
		-- However, it is not used in JOP (at the moment).
		when wr1 =>
			-- either 1 or 0
			if sc_mem_in.rdy_cnt(1)='0' then
				next_state <= idl;
			end if;

--
--	bytecode read
--
		-- cache lookup
		when bc_cc =>
			if cache_rdy = '1' then
				if cache_in_cache = '1' then
					next_state <= idl;
				else
					next_state <= bc_r1;
				end if;
			end if;

		-- not in cache
		-- start first read
		when bc_r1 =>
			next_state <= bc_w;
			-- even for a two cycle memory we have to go to
			-- wait for the first time as rdy_cnt is 0 in
			-- this state. Becomes valid in the next cycle

		-- wait
		when bc_w =>
			-- this works with pipeline level 1
			-- if sc_mem_in.rdy_cnt(1)='0' then
			-- we need a pipeline level of 2 in
			-- the memory interface for this to work!
			if sc_mem_in.rdy_cnt/=3 then
				next_state <= bc_rn;
			end if;

		-- start read 2 to n
		when bc_rn =>
			next_state <= bc_wr;

		when bc_wr =>
			if bc_len=to_unsigned(0, jpc_width-3) then
				next_state <= bc_wl;
			else
				-- w. pipeline level 2
				if sc_mem_in.rdy_cnt/=3 then
					next_state <= bc_rn;
				else
					next_state <= bc_w;
				end if;
			end if;

		-- wait for the last ack
		when bc_wl =>
			if sc_mem_in.rdy_cnt(1)='0' then
				next_state <= idl;
			end if;

--
--	array access
--
		when iast0 =>
			-- just one cycle wait to store the value
			next_state <= iald0;

		--
		-- iald0 to iald3 are shared with iastore
		--
		when iald0 =>
			if addr_reg=0 then
				next_state <= npexc;
			elsif index(SC_ADDR_SIZE-1)='1' then
				next_state <= abexc;
			else
				next_state <= iald1;
			end if;
			
		when iald1 =>
			-- w. pipeline level 2
			-- would waste one cycle in a single cycle memory (similar
			-- to bc load) - SimpCon rd comes from registered state_rd.
			if sc_mem_in.rdy_cnt<=1 then
				next_state <= iald23;
			elsif sc_mem_in.rdy_cnt/=3 then
				next_state <= iald2;
			end if;

		--
		-- a quick hack for faster memory: we need to read
		-- it now! TODO: get better state names
		-- it's a mix of iald2 and iald3
		--
		when iald23 =>
			next_state <= iald4;
------ that's now load specific!
-- we start loading before we know the upper bound exception!
-- is there an issue with read peripherals????
			if was_a_store='1' then
				next_state <= iaswb;
			-- w. pipeline level 2
			elsif sc_mem_in.rdy_cnt/=3 then
				next_state <= iasrd;
			end if;

		when iald2 =>
			next_state <= iald3;

		when iald3 =>
			next_state <= iald4;
------ that's now load specific!
-- we start loading before we know the upper bound exception!
-- is there an issue with read peripherals????
			if was_a_store='1' then
				next_state <= iaswb;
			-- w. pipeline level 2
			elsif sc_mem_in.rdy_cnt/=3 then
				next_state <= iasrd;
			end if;

		when iald4 =>
			if sc_mem_in.rdy_cnt/=3 then
				next_state <= iasrd;
			end if;

		-- rdy_cnt is less than 3 we can move on
		when iasrd =>
			next_state <= ialrb;

		when ialrb =>
			-- can we optimize this when we increment index at some state?
			if unsigned(index) >= unsigned(sc_mem_in.rd_data(SC_ADDR_SIZE-1 downto 0)) then
				next_state <= abexc;
			-- either 1 or 0
			elsif sc_mem_in.rdy_cnt(1)='0' then
				next_state <= idl;
			end if;

		when iaswb =>
			if sc_mem_in.rdy_cnt(1)='0' then
				next_state <= iasrb;
			end if;

		when iasrb =>
			next_state <= iasst;
			-- can we optimize this when we increment index at some state?
			if unsigned(index) >= unsigned(sc_mem_in.rd_data(SC_ADDR_SIZE-1 downto 0)) then
				next_state <= abexc;
			end if;

		when iasst =>
			next_state <= last;

		when gf0 =>
			if addr_reg=0 then
				next_state <= npexc;
			else
				next_state <= gf1;
			end if;
		when gf1 =>
			-- either 1 or 0
			if sc_mem_in.rdy_cnt(1)='0' then
				next_state <= gf2;
			end if;
		when gf2 =>
			next_state <= gf3;
			if was_a_store='1' then
				next_state <= pf3;
			end if;
		when gf3 =>
			next_state <= last;

		when pf0 =>
			-- just one cycle wait to store the value
			next_state <= gf0;
			-- states pf1 and pf2 are shared with getfield
		when pf3 =>
			next_state <= last;

		when cp0 =>
			next_state <= cp1;
			if cp_stopbit = '1' then
				next_state <= cpstop;
			end if;
		when cp1 =>
			next_state <= cp2;
		when cp2 =>
			-- either 1 or 0
			if sc_mem_in.rdy_cnt(1)='0' then
				next_state <= cp3;
			end if;
		when cp3 =>
			next_state <= cp4;
		when cp4 =>
			next_state <= last;
		when cpstop =>
			next_state <= idl;
			
		when last =>
			-- either 1 or 0
			if sc_mem_in.rdy_cnt(1)='0' then
				next_state <= idl;
			end if;

		when npexc =>
			next_state <= excw;

		when abexc =>
			next_state <= excw;

		when excw =>
			if sc_mem_in.rdy_cnt="00" then
				next_state <= idl;
			end if;

	end case;
end process;

--
--	state machine register
--	output register
--
process(clk, reset)

begin
	if (reset='1') then
		state <= idl;
		bc_wr_ena <= '0';
		inc_addr_reg <= '0';
		dec_len <= '0';
		state_rd <= '0';
		state_bsy <= '0';
		null_pointer <= '0';
		bounds_error <= '0';
		state_wr <= '0';
		sc_mem_out.atomic	<= '0';

	elsif rising_edge(clk) then

		state <= next_state;

		bc_wr_ena <= '0';
		inc_addr_reg <= '0';
		dec_len <= '0';
		state_rd <= '0';
		null_pointer <= '0';
		bounds_error <= '0';
		state_wr <= '0';
		sc_mem_out.atomic	<= '0';

		case next_state is

			when idl =>
				state_bsy <= '0';

			when rd1 =>

			when wr1 =>

			when bc_cc =>
				state_bsy <= '1';
				-- cache check

			when bc_r1 =>
				-- setup data
				bc_wr_addr <= unsigned(cache_bcstart);
				-- first memory read
				inc_addr_reg <= '1';
				state_rd <= '1';
				sc_mem_out.atomic	<= '1';

			when bc_w =>
				-- wait
				sc_mem_out.atomic	<= '1';

			when bc_rn =>
				-- following memory reads
				inc_addr_reg <= '1';
				dec_len <= '1';
				state_rd <= '1';
				sc_mem_out.atomic	<= '1';

			when bc_wr =>
				-- BC write
				bc_wr_ena <= '1';
				sc_mem_out.atomic	<= '1';
				
				if bc_len=to_unsigned(1, jpc_width-3) then
					sc_mem_out.atomic	<= '0';				
				end if;

			when bc_wl =>
				-- wait for last (unnecessary read)

			when iast0 =>
				state_bsy <= '1';

			when iald0 =>
				state_rd <= '1';
				state_bsy <= '1';
				inc_addr_reg <= '1';
				sc_mem_out.atomic <= '1';

			when iald1 =>
				sc_mem_out.atomic <= '1';

			when iald2 =>
				state_rd <= '1';
				sc_mem_out.atomic <= '1';

			when iald23 =>
				state_rd <= '1';
				sc_mem_out.atomic <= '1';

			when iald3 =>
				sc_mem_out.atomic <= '1';

			when iald4 =>
				sc_mem_out.atomic <= '1';

			when iasrd =>
				state_rd <= '1';
				sc_mem_out.atomic <= '1';

			when ialrb =>
				sc_mem_out.atomic <= '1';

			when iaswb =>
				sc_mem_out.atomic <= '1';

			when iasrb =>
				sc_mem_out.atomic <= '1';
				
			when iasst =>
				state_wr <= '1';
				sc_mem_out.atomic <= '1';

			when gf0 =>
				state_rd <= '1';
				state_bsy <= '1';
				sc_mem_out.atomic <= '1';

			when gf1 =>
				sc_mem_out.atomic <= '1';

			when gf2 =>
				sc_mem_out.atomic <= '1';

			when gf3 =>
				state_rd <= '1';
				sc_mem_out.atomic <= '1';
                          
			when pf0 =>
				state_bsy <= '1';

			when pf3 =>
				state_wr <= '1';
				sc_mem_out.atomic <= '1';
                          
			when cp0 =>
				sc_mem_out.atomic <= '1';
				state_bsy <= '1';

			when cp1 =>
				state_rd <= '1';
				sc_mem_out.atomic <= '1';
				
			when cp2 =>
				sc_mem_out.atomic <= '1';

			when cp3 =>
				sc_mem_out.atomic <= '1';

			when cp4 =>
				state_wr <= '1';
				sc_mem_out.atomic <= '1';

			when cpstop =>

			when last =>
				sc_mem_out.atomic <= '1';

			when npexc =>
				null_pointer <= '1';

			when abexc =>
				bounds_error <= '1';

			when excw =>

		end case;
					
		-- increment in state write
		if state=bc_wr then
			bc_wr_addr <= bc_wr_addr+1;		-- next jbc address
		end if;
	end if;
end process;

end rtl;
@


1.20
log
@correct array access for fast (SPM) memory (+iald23 state)
@
text
@d40 1
a40 1
--	2008-10-10	correct array access for fast (SPM) memory
@


1.19
log
@sensitivity list
@
text
@d40 1
d137 1
a137 1
							iald0, iald1, iald2, iald3, iald4,
d401 2
a402 1
	if state=iald3 or state=gf2 then
d555 3
a557 1
			if sc_mem_in.rdy_cnt/=3 then
d561 17
d783 4
@


1.18
log
@Removed size limitation of method cache.
@
text
@d348 1
a348 1
process(ain, addr_reg, offset_reg, mem_in)
@


1.17
log
@no message
@
text
@d91 1
a91 1
	bc_len		: in std_logic_vector(jpc_width-3 downto 0);	-- length of method in words
d183 1
a183 1
	signal bc_len		: unsigned(jpc_width-3 downto 0);	-- length of method in words
d287 1
a287 1
			bc_len <= unsigned(ain(jpc_width-3 downto 0));
@


1.16
log
@Making address translation more fmax-friendly.
@
text
@d369 1
a369 1
process(addr_reg, mem_in, ain, bin, state, inc_addr_reg, index, pos_reg, offset_reg)
@


1.15
log
@Added support for non-blocking copying.
@
text
@d153 1
d200 1
a200 2
	signal src_reg		: unsigned(SC_ADDR_SIZE-1 downto 0);
	signal dest_reg		: unsigned(SC_ADDR_SIZE-1 downto 0);
d202 2
a205 3
	signal src_pos		: unsigned(SC_ADDR_SIZE-1 downto 0);
	signal dest_pos		: unsigned(SC_ADDR_SIZE-1 downto 0);

d256 1
a256 13
-- address translation
src_pos <= src_reg+pos_reg;
dest_pos <= dest_reg+pos_reg;

process(pos_reg, ram_addr)
begin
	if unsigned(ram_addr) >= src_reg and unsigned(ram_addr) < src_pos then
		sc_mem_out.address <= std_logic_vector(unsigned(ram_addr) - src_reg+dest_reg);
	else
		sc_mem_out.address <= ram_addr;
	end if;
end process;
	
d281 4
a285 4
		if mem_in.addr_wr='1' then
			addr_reg <= unsigned(ain(SC_ADDR_SIZE-1 downto 0));
		end if;

a287 6
			addr_reg(17 downto 0) <= unsigned(ain(27 downto 10));

			-- addr_bits is 17
			if SC_ADDR_SIZE>18 then
				addr_reg(SC_ADDR_SIZE-1 downto 18) <= (others => '0');
			end if;
a288 3
			if inc_addr_reg='1' then
				addr_reg <= addr_reg+1;
			end if;
a295 1
			addr_reg <= unsigned(bin(SC_ADDR_SIZE-1 downto 0));	-- store address for store and np check
a303 1
			addr_reg <= unsigned(bin(SC_ADDR_SIZE-1 downto 0));	-- store address for store and np check
a306 5
		-- address calculations
		if state=iald3 or state=gf2 then
			addr_reg <= unsigned(sc_mem_in.rd_data(SC_ADDR_SIZE-1 downto 0))+unsigned(index);
		end if;

d309 2
a310 2
			src_reg <= unsigned(bin(SC_ADDR_SIZE-1 downto 0));
			pos_reg <= unsigned(ain(SC_ADDR_SIZE-1 downto 0));
d315 1
a315 1
			dest_reg <= unsigned(bin(SC_ADDR_SIZE-1 downto 0));
a318 3
		if state=cp0 then
			addr_reg <= src_pos;
		end if;		
a319 1
			addr_reg <= dest_pos;
d324 1
a324 1
			pos_reg <= (others => '0');
d327 8
d348 1
a348 1
process(ain, addr_reg, mem_in, state)
d351 5
a355 1
		ram_addr <= ain(SC_ADDR_SIZE-1 downto 0);
d358 5
a362 1
		ram_addr <= std_logic_vector(addr_reg(SC_ADDR_SIZE-1 downto 0));
d367 49
@


1.14
log
@sensitivity list correction
@
text
@d39 1
d138 5
a142 3
							iast0, iaswb, iasrb, iasst, iasw,
                                                        gf0, gf1, gf2, gf3, gf4,
                                                        pf0, pf3, pf4,
a168 1
	signal addr_calc	: unsigned(SC_ADDR_SIZE-1 downto 0);		-- adder
a173 1
	signal store_nxt	: std_logic;
d196 11
d215 1
a215 1
		if state/=ialrb and state/=iasw and state/=gf4 and state/=pf4 and state_bsy='1' then
d257 13
a269 1
	sc_mem_out.address <= ram_addr;
a290 1
		store_nxt <= '0';
a315 1
		store_nxt <= '0';
d317 1
a317 1
		if mem_in.iaload='1' or mem_in.getfield='1' or store_nxt='1' then
d321 1
a323 2
			-- get reference and index in next cycle
			store_nxt <= '1';
d325 36
a360 1
                
d365 2
a366 6
		end if;

		if state=iald3 or state=gf2 then
			addr_reg <= addr_calc;
		end if;
        end if;
a396 3
	addr_calc <= unsigned(sc_mem_in.rd_data(SC_ADDR_SIZE-1 downto 0))+unsigned(index);


d401 2
a402 2
	cache_rdy, cache_in_cache, bc_len, addr_calc, value, index, 
	addr_reg, was_a_store)
d422 2
d492 1
a492 1
		-- wait fot the last ack
d571 1
a571 8
			next_state <= iasw;

		when iasw =>
			-- either 1 or 0
			if sc_mem_in.rdy_cnt(1)='0' then
				next_state <= idl;
			end if;

d586 3
a588 3
                        if was_a_store='1' then
                          next_state <= pf3;
                        end if;
d590 17
a606 2
			next_state <= gf4;
		when gf4 =>
d609 1
a609 1
				next_state <= idl;
d611 8
a618 8

       		when pf0 =>
			-- just one cycle wait to store the value
                        next_state <= gf0;
                -- states pf1 and pf2 are shared with getfield
		when pf3 =>
			next_state <= pf4;
		when pf4 =>
a623 1
                        
a752 3
			when iasw =>
				sc_mem_out.atomic <= '1';

d768 1
a768 4
			when gf4 =>
				sc_mem_out.atomic <= '1';
				
                        when pf0 =>
d775 21
a795 1
			when pf4 =>
@


1.13
log
@JOP goes GPL
@
text
@d351 1
a351 1
process(state, mem_in, sc_mem_in.rdy_cnt,
@


1.12
log
@included atomic
@
text
@d2 21
@


1.11
log
@Cleanup of SimpCon types
@
text
@a56 1

d576 1
d589 1
d610 1
d614 1
d621 1
d626 5
d642 1
d645 1
d649 1
d652 1
d655 1
d659 1
d662 1
d665 1
d668 2
a669 1

d672 1
d675 1
d680 1
d683 1
d686 1
d690 1
d693 2
a694 1

d700 1
d703 1
@


1.10
log
@Changes for getfield/putfield in hardware.
@
text
@d17 1
d55 1
a55 1
	sc_mem_out	: out sc_mem_out_type;
d129 1
a129 1
	signal addr_reg		: unsigned(MEM_ADDR_SIZE-1 downto 0);
d132 1
a132 1
	signal ram_addr		: std_logic_vector(MEM_ADDR_SIZE-1 downto 0);
d145 2
a146 2
	signal index		: std_logic_vector(MEM_ADDR_SIZE-1 downto 0);	-- array or field index
	signal addr_calc	: unsigned(MEM_ADDR_SIZE-1 downto 0);		-- adder
d253 1
a253 1
			addr_reg <= unsigned(ain(MEM_ADDR_SIZE-1 downto 0));
d261 2
a262 2
			if MEM_ADDR_SIZE>18 then
				addr_reg(MEM_ADDR_SIZE-1 downto 18) <= (others => '0');
d276 2
a277 2
			addr_reg <= unsigned(bin(MEM_ADDR_SIZE-1 downto 0));	-- store address for store and np check
			index <= ain(MEM_ADDR_SIZE-1 downto 0);		-- store array index
d304 1
a304 1
		ram_addr <= ain(MEM_ADDR_SIZE-1 downto 0);
d307 1
a307 1
		ram_addr <= std_logic_vector(addr_reg(MEM_ADDR_SIZE-1 downto 0));
d325 1
a325 1
	addr_calc <= unsigned(sc_mem_in.rd_data(MEM_ADDR_SIZE-1 downto 0))+unsigned(index);
d440 1
a440 1
			elsif index(MEM_ADDR_SIZE-1)='1' then
d480 1
a480 1
			if unsigned(index) >= unsigned(sc_mem_in.rd_data(MEM_ADDR_SIZE-1 downto 0)) then
d495 1
a495 1
			if unsigned(index) >= unsigned(sc_mem_in.rd_data(MEM_ADDR_SIZE-1 downto 0)) then
@


1.9
log
@no message
@
text
@d35 2
a36 2
	ain			: in std_logic_vector(31 downto 0);		-- TOS
	bin			: in std_logic_vector(31 downto 0);		-- NOS
d69 1
a69 1
	bc_len		: in std_logic_vector(jpc_width-3 downto 0);		-- length of method in words
d72 1
a72 1
	find		: in std_logic;							-- start lookup
d76 2
a77 2
	rdy			: out std_logic;						-- lookup finished
	in_cache	: out std_logic							-- method is in cache
d98 1
a98 1
	clk			: in std_logic;
d103 1
a103 1
	q			: out std_logic_vector(7 downto 0)
d117 2
d134 6
a139 2
	signal bcl_arr_bsy		: std_logic;

d142 1
a142 1
--	signals for array access
d144 3
a146 7
	signal index		: std_logic_vector(MEM_ADDR_SIZE-1 downto 0);	-- array index
	signal addr_calc	: unsigned(MEM_ADDR_SIZE-1 downto 0);			-- adder
	signal value		: std_logic_vector(31 downto 0);				-- store value

	signal iastore_nxt	: std_logic;
	signal was_a_store	: std_logic;
	signal arr_wr		: std_logic;
d151 3
d160 6
a165 8
	signal bc_len			: unsigned(jpc_width-3 downto 0);	-- length of method in words
	signal inc_addr_reg		: std_logic;
	signal dec_len			: std_logic;
	signal bc_wr_addr		: unsigned(jpc_width-3 downto 0);	-- address for jbc (in words!)
	signal bc_wr_data		: std_logic_vector(31 downto 0);	-- write data for jbc
	signal bc_wr_ena		: std_logic;

	signal bc_arr_rd		: std_logic;
d170 1
a170 1
	signal cache_rdy		: std_logic;
d176 1
a176 1
process(sc_mem_in, bcl_arr_bsy, state)
d182 1
a182 1
		if state/=ialrb and state/=iasw and bcl_arr_bsy='1' then
a223 1

d226 2
a227 2
	sc_mem_out.rd <= mem_in.rd or bc_arr_rd;
	sc_mem_out.wr <= mem_in.wr or arr_wr;
d246 1
a246 1
		iastore_nxt <= '0';
d272 1
a272 1
		iastore_nxt <= '0';
d274 1
a274 1
		if mem_in.iaload='1' or iastore_nxt='1' then
d278 1
a278 1
		if mem_in.iastore='1' then
d281 1
a281 1
			iastore_nxt <= '1';
d283 2
a284 2

		if mem_in.iaload='1' then
d286 1
a286 1
		elsif mem_in.iastore='1' then
d290 1
a290 1
		if state=iald3 then
d293 1
a293 1
	end if;
d300 1
a300 1
process(ain, addr_reg, mem_in, value)
d305 1
a305 2
		-- default is the registered address
		-- for wr, bc load, and array access
d348 4
d448 1
a448 1
			-- to bc load) - SimpCon rd comes from registered bc_arr_rd.
d507 38
d571 2
a572 2
		bc_arr_rd <= '0';
		bcl_arr_bsy <= '0';
d575 1
a575 1
		arr_wr <= '0';
d584 1
a584 1
		bc_arr_rd <= '0';
d587 1
a587 1
		arr_wr <= '0';
d592 1
a592 1
				bcl_arr_bsy <= '0';
d599 1
a599 1
				bcl_arr_bsy <= '1';
d607 1
a607 1
				bc_arr_rd <= '1';
d616 1
a616 1
				bc_arr_rd <= '1';
d626 1
a626 1
				bcl_arr_bsy <= '1';
d629 2
a630 2
				bc_arr_rd <= '1';
				bcl_arr_bsy <= '1';
d636 1
a636 1
				bc_arr_rd <= '1';
d643 1
a643 1
				bc_arr_rd <= '1';
d652 1
a652 1
				arr_wr <= '1';
d656 21
@


1.8
log
@Hardware implementation of iaload and iastore
@
text
@d298 1
a298 1
process(ain, addr_reg, mem_in)
d312 1
a312 1
process(ain, addr_reg, mem_in)
d330 2
a331 1
	cache_rdy, cache_in_cache, bc_len, addr_calc)
@


1.7
log
@Hardware implementation of iaload and iastore
@
text
@d179 1
a179 2
		if state/=ialrb and state/=iasw
			and state/=iasst and bcl_arr_bsy='1' then
a493 3
			if sc_mem_in.rdy_cnt(1)='0' then
				next_state <= idl;
			end if;
a515 15
--	state machine combinatorial output
--	from next_state
--	read for single cycle memory could be
--	speed up
--
process(next_state)
begin
	arr_wr <= '0';
	if next_state=iasst then
		arr_wr <= '1';
	end if;

end process;

--
d531 1
d543 1
d608 1
@


1.6
log
@Constants for ext_addr encoding, records for extension/mem interface
@
text
@d16 1
d35 7
a41 1
	din			: in std_logic_vector(31 downto 0);
d113 5
a117 1
							bc_cc, bc_r1, bc_w, bc_rn, bc_wr, bc_wl
d122 9
a130 2
	signal mem_wr_addr		: std_logic_vector(MEM_ADDR_SIZE-1 downto 0);
	signal ram_addr			: std_logic_vector(MEM_ADDR_SIZE-1 downto 0);
d132 1
a132 1
	signal bcl_bsy			: std_logic;
d136 14
d156 1
a156 2
	signal bc_mem_start		: unsigned(17 downto 0);			-- memory address of bytecode
	signal inc_mem_start	: std_logic;
d162 1
a162 1
	signal bc_rd			: std_logic;
d173 12
a184 1
	mem_out.bsy <= '1' when sc_mem_in.rdy_cnt=3 or bcl_bsy='1' else '0';
d188 4
d201 1
a201 1
		std_logic_vector(bc_len), std_logic_vector(bc_mem_start),
d224 3
a226 3
	sc_mem_out.wr_data <= din;
	sc_mem_out.rd <= mem_in.rd or bc_rd;
	sc_mem_out.wr <= mem_in.wr;
d237 2
d242 7
a248 1
		mem_wr_addr <= (others => '0');
d251 1
a251 1
			mem_wr_addr <= din(MEM_ADDR_SIZE-1 downto 0);	-- store write address
a252 2
	end if;
end process;
a253 6
process(clk, reset)
begin
	if reset='1' then
		bc_len <= (others => '0');
		bc_mem_start <= (others => '0');
	elsif rising_edge(clk) then
d255 7
a261 2
			bc_len <= unsigned(din(jpc_width-3 downto 0));
			bc_mem_start <= unsigned(din(27 downto 10));
d263 2
a264 2
			if inc_mem_start='1' then
				bc_mem_start <= bc_mem_start+1;
d271 21
d295 1
d299 1
a299 1
process(din, mem_wr_addr, bc_mem_start, mem_in)
d302 15
a316 3
		ram_addr <= din(MEM_ADDR_SIZE-1 downto 0);
	elsif mem_in.wr='1' then
		ram_addr <= mem_wr_addr;
d318 2
a319 6
		-- default use the bc address (simpled MUX selection)
		ram_addr(17 downto 0) <= std_logic_vector(bc_mem_start);
		-- addr_bits is 17
		if MEM_ADDR_SIZE>18 then
			ram_addr(MEM_ADDR_SIZE-1 downto 18) <= (others => '0');
		end if;
d324 3
d331 1
a331 1
	cache_rdy, cache_in_cache, bc_len)
d345 4
d421 95
d520 15
d544 1
a544 1
		inc_mem_start <= '0';
d546 5
a550 2
		bc_rd <= '0';
		bcl_bsy <= '0';
d556 1
a556 1
		inc_mem_start <= '0';
d558 3
a560 1
		bc_rd <= '0';
d565 1
a565 1
				bcl_bsy <= '0';
d572 1
a572 1
				bcl_bsy <= '1';
d579 2
a580 2
				inc_mem_start <= '1';
				bc_rd <= '1';
d587 1
a587 1
				inc_mem_start <= '1';
d589 1
a589 1
				bc_rd <= '1';
d598 38
@


1.5
log
@removed unnecessary state in BC load
len decrement in bc_rn and exit from bc_wr
@
text
@d4 1
a4 1
--	External memory interface with SimpCon
d6 2
a7 1
--	and SimpCon memory interface
d15 1
d23 1
d26 1
a26 1
generic (jpc_width : integer; block_bits : integer; addr_bits : integer);
d36 3
a38 8
	mem_rd		: in std_logic;
	mem_wr		: in std_logic;
	mem_addr_wr	: in std_logic;
	mem_bc_rd	: in std_logic;
	dout		: out std_logic_vector(31 downto 0);
	bcstart		: out std_logic_vector(31 downto 0); 	-- start of method in bc cache

	bsy			: out std_logic;
d47 2
a48 5
	address		: out std_logic_vector(addr_bits-1 downto 0);
	wr_data		: out std_logic_vector(31 downto 0);
	rd, wr		: out std_logic;
	rd_data		: in std_logic_vector(31 downto 0);
	rdy_cnt		: in unsigned(1 downto 0)
d111 2
a112 2
	signal mem_wr_addr		: std_logic_vector(addr_bits-1 downto 0);
	signal ram_addr			: std_logic_vector(addr_bits-1 downto 0);
d142 1
a142 1
	bsy <= '1' when rdy_cnt=3 or bcl_bsy='1' else '0';
d144 1
a144 1
	bcstart <= std_logic_vector(to_unsigned(0, 32-jpc_width)) & cache_bcstart & "00";
d147 4
a150 4
	bc_wr_data <= rd_data(7 downto 0) &
				rd_data(15 downto 8) &
				rd_data(23 downto 16) &
				rd_data(31 downto 24);
d156 1
a156 1
		mem_bc_rd,
d177 5
a181 5
	address <= ram_addr;
	wr <= mem_wr;
	rd <= mem_rd or bc_rd;
	wr_data <= din;
	dout <= rd_data;
d196 2
a197 2
		if mem_addr_wr='1' then
			mem_wr_addr <= din(addr_bits-1 downto 0);	-- store write address
d208 1
a208 1
		if mem_bc_rd='1' then
d226 1
a226 1
process(din, mem_wr_addr, bc_mem_start, mem_rd, mem_wr)
d228 3
a230 3
	if mem_rd='1' then
		ram_addr <= din(addr_bits-1 downto 0);
	elsif mem_wr='1' then
d236 2
a237 2
		if addr_bits>18 then
			ram_addr(addr_bits-1 downto 18) <= (others => '0');
d246 1
a246 1
process(state, mem_rd, mem_wr, mem_bc_rd, rdy_cnt,
d255 1
a255 1
			if mem_rd='1' then
d257 1
a257 1
			elsif mem_wr='1' then
d259 1
a259 1
			elsif mem_bc_rd='1' then
d267 1
a267 1
			if rdy_cnt(1)='0' then
d276 1
a276 1
			if rdy_cnt(1)='0' then
d304 1
a304 1
			-- if rdy_cnt(1)='0' then
d307 1
a307 1
			if rdy_cnt/=3 then
d320 1
a320 1
				if rdy_cnt/=3 then
d329 1
a329 1
			if rdy_cnt(1)='0' then
@


1.4
log
@Added Flash interface (SimpCon) for the cycore board
@
text
@d12 2
d111 1
a111 1
							bc_cc, bc_sa, bc_r1, bc_w, bc_rn, bc_wr, bc_wl
d294 1
a294 1
					next_state <= bc_sa;
a298 3
		when bc_sa =>
			next_state <= bc_r1;

d302 3
a307 2
			if bc_len=to_unsigned(0, jpc_width-3) then
				next_state <= bc_wl;
d309 1
a309 2
			-- elsif rdy_cnt(1)='0' then

d312 1
a312 1
			elsif rdy_cnt/=3 then
d318 3
d324 6
a329 9
				next_state <= bc_wr;
			end if;

		when bc_wr =>
			-- w. pipeline level 2
			if rdy_cnt/=3 then
				next_state <= bc_rn;
			else
				next_state <= bc_w;
d377 1
a377 1
			when bc_sa =>
a379 2

			when bc_r1 =>
d390 1
a395 1
				dec_len <= '1';
@


1.3
log
@removed signal mem_bsy
@
text
@d239 3
a241 1
		-- ram_addr(addr_bits-1 downto 18) <= (others => '0');
@


1.2
log
@Changed signal names to use the names from the specification.
@
text
@a116 2

	signal mem_bsy			: std_logic;
d145 1
a145 3
	mem_bsy <= '1' when rdy_cnt=3 or bcl_bsy='1' else '0';

	bsy <= mem_bsy;
@


1.1
log
@Use mem_sc and sc_sram32 with block cache for S3. No more Spartan
specific main memory module.
@
text
@d4 3
a6 1
--	external memory interface with SimpCon
d47 1
a47 1
	addr		: out std_logic_vector(addr_bits-1 downto 0);
d51 1
a51 1
	bsy_cnt		: in unsigned(1 downto 0)
d147 1
a147 1
	mem_bsy <= '1' when bsy_cnt=3 or bcl_bsy='1' else '0';
d184 1
a184 1
	addr <= ram_addr;
d251 1
a251 1
process(state, mem_rd, mem_wr, mem_bc_rd, bsy_cnt,
d272 1
a272 1
			if bsy_cnt(1)='0' then
d281 1
a281 1
			if bsy_cnt(1)='0' then
d311 1
a311 1
			-- elsif bsy_cnt(1)='0' then
d315 1
a315 1
			elsif bsy_cnt/=3 then
d329 1
a329 1
			if bsy_cnt/=3 then
d337 1
a337 1
			if bsy_cnt(1)='0' then
@

