head	1.3;
access;
symbols
	bg2_23:1.1
	bg2_22:1.1
	bg2_21:1.1
	bg2_20:1.1;
locks; strict;
comment	@# @;


1.3
date	2008.09.03.21.08.36;	author jwhitham;	state Exp;
branches;
next	1.2;
commitid	13ed48befca64567;

1.2
date	2008.08.09.12.06.50;	author jwhitham;	state Exp;
branches;
next	1.1;
commitid	35e2489d88224567;

1.1
date	2008.07.22.12.11.33;	author jwhitham;	state Exp;
branches;
next	;
commitid	41a4885ce744567;


desc
@@


1.3
log
@
Added changes to control channel protocol as suggested in
meeting with Andy and Neil.

Updated virtual lab code.
@
text
@--
--
--  This file is a part of JOP, the Java Optimized Processor
--
--  Copyright (C) 2008, Jack Whitham
--
--  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/>.
--


--
--	sc_control_channel.vhd
--
--  32 bit parallel interface for the control channel;
--  mimics a serial port UART device. Data is sent in a packet
--  form (with a header word and zero or more payload words).
--


library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned."+";
use ieee.numeric_std.all;

entity sc_control_channel is
generic (addr_bits : integer);
port (
	clk		: in std_logic;
	reset	: in std_logic;

-- SimpCon interface

	address		: in std_logic_vector(addr_bits-1 downto 0);
	wr_data		: in std_logic_vector(31 downto 0);
	rd, wr		: in std_logic;
	rd_data		: out std_logic_vector(31 downto 0);
	rdy_cnt		: out unsigned(1 downto 0);

    cc_out_data : out std_logic_vector(31 downto 0);
    cc_out_wr   : out std_logic;
    cc_out_rdy  : in std_logic;

    cc_in_data  : in std_logic_vector(31 downto 0);
    cc_in_wr    : in std_logic;
    cc_in_rdy   : out std_logic
);
end sc_control_channel;

architecture rtl of sc_control_channel is

	signal incoming_message     : std_logic_vector(31 downto 0);
	signal outgoing_message     : std_logic_vector(31 downto 0);
	signal send_ack, send_flag  : std_logic;

    type StateType is ( IDLE, RELAY, SEND, AWAIT_REPLY, AWAIT_REPLY_RELAY );

    signal state                : StateType;

begin

    process ( clk , reset ) is
    begin
        if ( reset = '1' ) 
        then
            send_flag <= '0';

        elsif ( clk = '1' )
        and ( clk'event )
        then
            if ( send_ack = '1' )
            then
                send_flag <= '0';
            end if;

            if ( rd = '1' ) 
            then
                null;
            elsif ( wr = '1' ) 
            then
                outgoing_message <= wr_data;
                send_flag <= '1';
            end if;
        end if;
    end process;

    rdy_cnt <= "00" when (( state = IDLE ) and ( send_flag = '0' )) else "11";
    rd_data <= incoming_message;

    process ( clk , reset ) is
    begin
        if ( reset = '1' ) 
        then
            state <= IDLE;
            cc_in_rdy <= '0';
            cc_out_wr <= '0';
            send_ack <= '0';

        elsif ( clk = '1' )
        and ( clk'event )
        then
            cc_in_rdy <= '0';
            cc_out_wr <= '0';
            send_ack <= '0';

            case state is
            when IDLE =>
                if ( send_flag = '1' )
                then
                    -- A message to be sent
                    cc_out_data <= outgoing_message;
                    send_ack <= '1';
                    state <= SEND;
                elsif ( cc_in_wr = '1' )
                then
                    -- Relay incoming message since we are not
                    -- waiting for a message
                    cc_out_data <= cc_in_data;
                    state <= RELAY;
                else
                    -- Ready for CC data 
                    cc_in_rdy <= '1';
                end if;

            when RELAY =>
                if ( cc_out_rdy = '1' )
                then
                    cc_out_wr <= '1';
                    state <= IDLE;
                end if;

            when SEND =>
                if ( cc_out_rdy = '1' )
                then
                    cc_out_wr <= '1';
                    state <= AWAIT_REPLY;
                end if;

            when AWAIT_REPLY =>
                if ( cc_in_wr = '1' )
                then
                    -- Examine incoming message
                    if ( cc_in_data ( 30 downto 16 ) = outgoing_message ( 30 downto 16 ) )
                    then
                        -- Correct message
                        incoming_message <= cc_in_data;
                        state <= IDLE;
                    else
                        -- Wrong message (for someone else)
                        cc_out_data <= cc_in_data;
                        state <= AWAIT_REPLY_RELAY;
                    end if;
                else
                    -- Ready for CC data 
                    cc_in_rdy <= '1';
                end if;
                
            when AWAIT_REPLY_RELAY =>
                if ( cc_out_rdy = '1' )
                then
                    cc_out_wr <= '1';
                    state <= AWAIT_REPLY;
                end if;
            end case;
        end if;
    end process;

end rtl;

@


1.2
log
@Add locking support - see new file
jop/java/target/src/common/com/jopdesign/io/ControlChannel.java
@
text
@d62 3
a64 6
	signal tdre		        : std_logic;
	signal rdrf		        : std_logic;
	signal cc_in_full       : std_logic;
	signal cc_in_reg        : std_logic_vector(31 downto 0);
	signal cc_out_wr_d      : std_logic;
	signal unlocked         : std_logic;
d66 1
d68 1
a68 5
    constant TDRE_BIT       : Natural := 0;
    constant RDRF_BIT       : Natural := 1;
    constant LOCK_BIT       : Natural := 2;
    constant RELEASE_BIT    : Natural := 3;
    constant ADVANCE_BIT    : Natural := 4;
d70 26
d97 2
a98 2
begin
	rdy_cnt <= "00";	-- no wait states
d100 1
a100 1
    process(clk, reset)
d102 4
a105 4
        if (reset='1') then
            rd_data <= ( others => '0' ) ;
            cc_in_full <= '0';
            cc_in_reg <= ( others => '0' ) ;
d107 1
a107 2
            cc_out_wr_d <= '0';
            unlocked <= '1';
d109 6
a114 1
        elsif rising_edge(clk) then
d116 25
a140 4
            if cc_in_wr = '1' then
                cc_in_reg <= cc_in_data;
                cc_in_full <= '1';
            end if;
d142 5
a146 16
            cc_out_wr <= cc_out_wr_d;
            cc_out_wr_d <= '0';
            if rd='1' then
                rd_data <= ( others => '0' ) ;
                -- UART-style address decoder:
                -- 0: control/status
                -- 1: data
                if address(0)='0' then
                    -- control/status (read)
                    rd_data ( LOCK_BIT ) <= unlocked;
                    rd_data ( TDRE_BIT ) <= tdre;
                    rd_data ( RDRF_BIT ) <= rdrf;
                    unlocked <= '0'; -- now it is locked.
                else
                    -- data (read data)
                    rd_data <= cc_in_reg;
d148 14
a161 8
            elsif wr = '1' then
                if address(0)='0' then
                    -- control/status (write)
                    if ( wr_data ( RELEASE_BIT ) = '1' ) then
                        unlocked <= '1';
                    end if;
                    if ( wr_data ( ADVANCE_BIT ) = '1' ) then
                        cc_in_full <= '0';
d164 2
a165 3
                    -- data (write data)
                    cc_out_data <= wr_data;
                    cc_out_wr_d <= '1';
d167 8
a174 1
            end if;
a177 6

    tdre <= cc_out_rdy;
    rdrf <= cc_in_full;
    cc_in_rdy <= not cc_in_full ;


@


1.1
log
@Initial Revision
@
text
@a49 1
    inhibit     : in std_logic;
d62 1
a62 1
	signal ua_wr, tdre		: std_logic;
d67 9
a75 1
    signal read_counter     : std_logic_vector(7 downto 0);
d88 1
a88 1
            read_counter <= ( others => '0' ) ;
d102 1
a102 1
                -- 0: control
d105 5
a109 2
                    rd_data(1 downto 0) <= rdrf & tdre;
                    read_counter <= read_counter + 1 ;
d111 1
a112 1
                    cc_in_full <= '0';
d114 14
a127 3
            elsif ua_wr = '1' then
                cc_out_data <= wr_data;
                cc_out_wr_d <= '1';
d132 3
a134 4
	-- write is on address offest 1
	ua_wr <= wr and address(0);
    tdre <= cc_out_rdy and not inhibit;
    rdrf <= cc_in_full or inhibit;
@

