OpenCores
URL https://opencores.org/ocsvn/hicovec/hicovec/trunk

Subversion Repositories hicovec

[/] [hicovec/] [trunk/] [cpu/] [units/] [controlunit.vhd] - Rev 4

Go to most recent revision | Compare with Previous | Blame | View Log

------------------------------------------------------------------
-- PROJECT:      HiCoVec (highly configurable vector processor)
--
-- ENTITY:      controlunit
--
-- PURPOSE:     controlunit of scalar unit
--
-- AUTHOR:      harald manske, haraldmanske@gmx.de
--
-- VERSION:     1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
 
entity controlunit is
    port(   
        -- clock
        clk:            in std_logic;                       -- clock signal
 
        -- instruction in
        ir:             in std_logic_vector(31 downto 0);   -- instruction
 
        -- control signals in
        reset_cpu:      in std_logic;                       -- reset signal
        zero:           in std_logic;                       -- zero flag
        carry:          in std_logic;                       -- carry flag
        ready:          in std_logic;                       -- memory interface ready signal
 
        -- control signals out
        access_type:    out std_logic_vector(2 downto 0);   -- memory interface access type (we, oe, cs)
        c0:             out std_logic;                      -- c0 signal
        c1:             out std_logic;                      -- c1 signal
        cc2:            out std_logic_vector(1 downto 0);   -- cc2 signal
        --c3:             out std_logic;                    -- c3 signal => obsolete
        cc4:            out std_logic_vector(1 downto 0);   -- cc4 signal
        cc5:            out std_logic_vector(1 downto 0);   -- cc5 signal
        c6:             out std_logic;                      -- c6 signal
        c7:             out std_logic;                      -- c7 signal
        c8:             out std_logic;                      -- c7 signal
        load_ir:        out std_logic;                      -- instruction register load signal
        inc_ic:         out std_logic;                      -- instruction counter increment signal
        load_ic:        out std_logic;                      -- instruction counter load signal
        load_c:         out std_logic;                      -- carry flag load signal
        load_z:         out std_logic;                      -- zero flag load signal
 
        -- communication with vecor unit
        ir_ready:       out std_logic;                      -- next instruction has been loaded into ir
        s_ready:        out std_logic;                      -- data from scalar unit or mi is ready
        s_fetched:      out std_logic;                      -- signal for vector unit to continue
 
        v_ready:        in std_logic;                       -- data for scalar unit or mi is ready
        v_fetched:      in std_logic;                       -- signal for scalar unit to continue
        v_done:         in std_logic;                       -- vector unit completed command
 
        halted:         out std_logic                       -- enabled when cpu is in halt state
    );
end controlunit;
 
architecture rtl of controlunit is   
    type statetype is (if1, if2, decode_wait, ld1, ld2, vld1, vld2, vld3, vld4,
        st1, st2, vst1, vst2, vst3, smv1, smv2, vms1, vms2, nop, jal, jcc, alu, flag, sync, halt,
        mova1, mova2, reset);
 
    signal state : statetype := halt;
    signal nextstate : statetype := halt;
 
begin
 
    -- state register
    process
    begin
        wait until clk='1' and clk'event;
        state <= nextstate;
 
    end process;
 
    -- state transitions
    process (state, ready, reset_cpu, ir, carry, zero, v_ready, v_fetched, v_done)
    begin
        -- avoid latches
        access_type <= "000";
        c0          <= '0';
        c1          <= '0';
        cc2         <= "00";
        cc4         <= "00";
        cc5         <= "00";
        c6          <= '0';
        c7          <= '0';
        c8          <= '0';
        load_ir     <= '0';
        inc_ic      <= '0';
        load_ic     <= '0';
        load_c      <= '0';
        load_z      <= '0';
        ir_ready    <= '0';
        s_ready     <= '0';
        s_fetched   <= '0';
        nextstate   <= reset;
        halted <= '0';
 
        if reset_cpu = '1' then
            nextstate <= reset;
        else    
            case state is
                -- RESET STATE --
                when reset => 
                    cc4 <= "10";
                    cc5 <= "10";
                    load_c <= '1';
                    load_z <= '1';
                    nextstate <= if1;                                               
 
                -- INSTRUCTION FETCH STATE 1 --
                when if1 =>
                    access_type <= "010";
                    nextstate <= if2;
 
                -- INSTRUCTION FETCH STATE 2 --
                when if2 =>
                    access_type <= "010";
                    ir_ready <= '1';
                    load_ir <= '1';
 
                    if ready = '0' then
                        nextstate <= if2;
                    else
                        nextstate <= decode_wait;
                    end if;
 
                -- DECODE AND WAIT STATE --
                when decode_wait =>
                    if ir(31 downto 28) = "1000" then       -- ld
                        if ready = '1' then
                            nextstate <= ld1;
                        else
                            nextstate <= decode_wait;
                        end if;
 
                    elsif ir(31 downto 28) = "1001" then    -- vld
                        if ready = '1' then
                            nextstate <= vld1;
                        else
                            nextstate <= decode_wait;
                        end if;
 
                    elsif ir(31 downto 28) = "1010" then    -- store
                        if ready = '1' then
                            nextstate <= st1;
                        else
                            nextstate <= decode_wait;
                        end if;
 
                    elsif ir(31 downto 26) = "101100" then   -- vst
                        if ready = '1' and v_ready = '1' then
                            nextstate <= vst1;
                        else
                            nextstate <= decode_wait;
                        end if;
 
                    elsif ir(31 downto 26) = "101101" then   -- mova
                        nextstate <= mova1;
 
                    elsif ir(31 downto 26) = "101110" then   -- mov r(t), s
                        nextstate <= smv1;
 
                    elsif ir(31 downto 26) = "101111" then   -- mov d, v(t)
                        nextstate <= vms1;
 
                    else
                        case ir(31 downto 30) is
                            when "00" =>
                                if ir(29) = '0' then                    -- nop
                                    nextstate <= nop;
 
                                elsif ir(29 downto 27) = "101" then     -- halt
                                    report "HALT";
                                    nextstate <= halt;
 
                                elsif ir(29 downto 26) = "1000" then    -- jmp, jal
                                    nextstate <= jal;
 
                                elsif ir(29 downto 28) = "11" then      -- jcc
                                    nextstate <= jcc;
                                end if;
 
                            when "01" =>                                -- alu cmd
                                nextstate <= alu;
 
                            when "11" =>                                -- set/clear flags
                                nextstate <= flag;
 
                            when others =>                              -- error
                                nextstate <= halt;
                        end case;
                    end if;
 
 
                -- LOAD STATE 1 --
                when ld1 =>
                    access_type <= "010";
                    c1 <= '1';
                    c7 <= '1';
                    nextstate <= ld2;
 
                -- LOAD STATE 2 --
                when ld2 =>
                    access_type <= "010";
                    report "LD";
                    c0 <= '1';
                    c6 <= '1';
                    c7 <= '1';
                    c8 <= '1';
                    load_z <= '1';
                    inc_ic <= '1';
 
                    if ready = '0' then
                        nextstate <= ld2;
                    else
                        nextstate <= sync;
                    end if;
 
 
                -- VECTOR LOAD STATE 1 --
                when vld1 =>
                    access_type <= "011";
                    c1 <= '1';
                    c7 <= '1';
 
                    if ready = '1' then
                        nextstate <= vld1;
                    else
                        nextstate <= vld2;
                    end if;
 
                -- VECTOR LOAD STATE 2 --
                when vld2 =>
                    access_type <= "011";
                    c1 <= '1';
                    c7 <= '1';
 
                    if ready = '1' then
                        nextstate <= vld3;
                    else
                        nextstate <= vld2;
                    end if;
 
                -- VECTOR LOAD STATE 3 --
                when vld3 =>
                    access_type <= "011";
                    c1 <= '1';
                    c7 <= '1';
                    s_ready <= '1';
 
                    if v_fetched = '1' then
                        nextstate <= vld4;
                    else
                        nextstate <= vld3;
                    end if;
 
                -- VECTOR LOAD STATE 4 --
                when vld4 =>
                    report "VLD";
                    inc_ic <= '1';
                    nextstate <= sync;
 
                -- STORE STATE 1 --
                when  st1 =>
                    access_type <= "100";
                    c1 <= '1';
                    c7 <= '1';
                    inc_ic <= '1';
 
                    nextstate <= st2;
 
                -- STORE STATE 2 --
                when  st2 =>
                    access_type <= "100";
                    c1 <= '1';
                    c7 <= '1';
 
                    if ready = '0' then
                        nextstate <= st2;
                    else
                        nextstate <= sync;
                    end if;
 
 
                -- VECTOR STORE STATE 1 --
                when vst1 =>
                    access_type <= "101";
                    c1 <= '1';
                    c7 <= '1';
 
                    if ready = '1' then
                        nextstate <= vst1;
                    else
                        nextstate <= vst2;
                    end if;
 
                -- VECTOR STORE STATE 2 --
                when vst2 =>
                    access_type <= "101";
                    c1 <= '1';
                    c7 <= '1';
 
                    if ready = '1' then
                        nextstate <= vst3;
                    else
                        nextstate <= vst2;
                    end if;
 
                 -- VECTOR STORE STATE 3 --
                when vst3 =>
                    report "VST";
                    s_fetched <= '1';
                    inc_ic <= '1';
                    nextstate <= sync;
 
                -- SCALAR MOVE TO VECTOR STATE 1 --    
                when smv1 =>
                    s_ready <= '1';
 
                    if v_fetched = '1' then
                        nextstate <= smv2;
                    else
                        nextstate <= smv1;
                    end if;
 
                -- SCALAR MOVE TO VECTOR STATE 2 --    
                when smv2 =>
                    report "MOV R(T), S";
                    inc_ic <= '1';
                    nextstate <= sync;
 
               -- MOVA STATE 1 --    
                when mova1 =>
                    s_ready <= '1';
 
                    if v_fetched = '1' then
                        nextstate <= mova2;
                    else
                        nextstate <= mova1;
                    end if;
 
                -- MOVA STATE 2 --    
                when mova2 =>
                    report "MOVA";
                    inc_ic <= '1';
                    nextstate <= sync;
 
                -- VECTOR MOVE TO SCALAR STATE  --
                when vms1 =>
                    if v_ready = '1' then
                        nextstate <= vms2;
                    else
                        nextstate <= vms1;
                    end if;
 
                -- VECTOR MOVE TO SCALAR STATE 2 --
                when vms2 =>
                    report "MOV D, V(T)";
                    cc2 <= "10";
                    c6 <= '1';
                    s_fetched <= '1';
                    inc_ic <= '1';
                    nextstate <= sync;
 
                -- NOP STATE --
                when nop =>
                    report "NOP";
                    inc_ic <= '1';
                    nextstate <= sync;
 
                -- JUMP AND LINK STATE
                when jal =>
                    report "JMP, JAL";
                    c7 <= '1';
                    load_ic <= '1';
                    cc2 <= "01";
                    c6 <= '1';
                    nextstate <= sync;
 
                -- JUMP CONDITIONAL STATE
                when jcc =>
                    report "JCC";
                    if (ir(27) = '0' and ir(26) = carry) 
                      or (ir(27) = '1' and ir(26) = zero) then
                        c7 <= '1';
                        load_ic <= '1';
                    else
                        inc_ic <= '1';
                    end if;
 
                    nextstate <= sync;
 
                -- ALU COMMAND STATE --
                when alu =>
                    report "ALU COMMANDS";
                    load_c <= '1';
                    load_z <= '1';
                    c6 <= '1';
                    inc_ic <= '1';
                    nextstate <= sync;
 
                -- SET/CLEAR FLAGS STATE --
                when flag =>
                    report "SET/RESET FLAGS";
                    load_z <= ir(23);
                    load_c <= ir(22);
                    cc4 <= '1' & ir(21);
                    cc5 <= '1' & ir(20);
                    inc_ic <= '1';
                    nextstate <= sync;
 
                -- SYNC STATE --
                when  sync =>
                    if v_done = '1' then
                        nextstate <= if1;
                    else
                        nextstate <= sync;
                    end if;
 
                -- HALT STATE --
                when  halt =>
                    report "halted";
                    halted <= '1';
                    nextstate <= halt;
 
            end case;
        end if;
	end process;
end rtl;
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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