URL
https://opencores.org/ocsvn/raytrac/raytrac/trunk
Subversion Repositories raytrac
[/] [raytrac/] [branches/] [fp/] [sm.vhd] - Rev 159
Go to most recent revision | Compare with Previous | Blame | View Log
--! @file sm.vhd --! @brief Maquina de Estados. Controla la operación interna y genera los mecanismos de sincronización con el exterior (interrupciones). --! @author Julián Andrés Guarín Reyes -------------------------------------------------------------- -- RAYTRAC -- Author Julian Andres Guarin -- sm.vhd -- This file is part of raytrac. -- -- raytrac 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. -- -- raytrac 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 raytrac. If not, see <http://www.gnu.org/licenses/>. library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use work.arithpack.all; entity sm is port ( --! Señales normales de secuencia. clk,rst: in std_logic; --! Vector con las instrucción codficada instrQq:in std_logic_vector(floatwidth-1 downto 0); --! Señal de cola vacia. instrQ_empty:in std_logic; adda,addb:out std_logic_vector (widthadmemblock-1 downto 0); sync_chain_0,instrRdAckd:out std_logic; full_r: in std_logic; --! Indica que la cola de resultados no puede aceptar mas de 32 elementos. --! End Of Instruction Event eoi : out std_logic; --! State Exposed for testbench purposes. state : out macState; --! DataPath Control uca code. dpc_uca : out std_logic_vector (2 downto 0) ); end entity; architecture sm_arch of sm is --! LOAD_INSTRUCTION: Estado en el que se espera que en la cola de instrucciones haya una instrucción para ejecutar. --! EXECUTE_INSTRUCTION: Estado en el que se ejecuta la instrucción de la cola de instrucciones. --! FLUSH_ARITH_PIPELINE: Estado en el que se espera un número específico de ciclos de reloj, para que se desocupe el pipeline aritmético. signal s_state : macState; signal s_instr_uca: std_logic_vector(2 downto 0); signal s_dpc_uca: std_logic_vector(2 downto 0); signal s_block_start_a: std_logic_vector(4 downto 0); signal s_block_start_b: std_logic_vector(4 downto 0); signal s_block_end_a: std_logic_vector(4 downto 0); signal s_block_end_b: std_logic_vector(4 downto 0); signal s_combinatory: std_logic; signal s_delay_field: std_logic_vector(7 downto 0); signal s_set_b: std_logic; --! Señal para colocar un valor arbitrario en el contador B. signal s_set_a: std_logic; signal s_set_dly: std_logic; signal s_go_b: std_logic; --! Salida para controlar la pausa(0) o marcha(1) del contador de direcciones del operando B/D. signal s_go_a: std_logic; --! Salida para controlar la pausa(0) o marcha(1) del contador de direcciones del operando A/C. signal s_go_delay: std_logic; --! Salida para controlar la pausa(0) o marcha(1) del contador de delay, para el flush del pipeline aritmético. signal s_zeroFlag_delay:std_logic; --! Bandera de cero del contador delay. signal s_eq_b,s_eq_a: std_logic; --! Indica cuando se está leyendo el último bloque de memoria con operandos de entrada de a y de b respectivamente. signal s_eb_b,s_eb_a: std_logic; --! Indica que se está leyendo en memoria el último operando del bloque actual, b o a, respectivamente. begin state <= s_state; --! Código UCA, pero en la etapa DPC: La diferencia es que UCA en la etapa DPC, decodifica el datapath dentro del pipeline aritmético. dpc_uca <= s_dpc_uca; --! Bloques asignados en la instrucci´øn s_block_start_a <= instrQq(floatwidth-4 downto floatwidth-8); s_block_end_a <= instrQq(floatwidth-9 downto floatwidth-13); s_block_start_b <= instrQq(floatwidth-14 downto floatwidth-18); s_block_end_b <= instrQq(floatwidth-19 downto floatwidth-23); --! Campo que define si la instrucción es combinatoria s_combinatory <= instrQq(floatwidth-24); --! Campo que define cuantos clocks debe esperar el sistema, despues de que se ejecuta una instrucción, para que el pipeline aritmético quede vacio. s_delay_field <= instrQq(floatwidth-25 downto floatwidth-32); --! UCA code, código con la instrucción a ejecutar. s_instr_uca <= instrQq(31 downto 29); --! Address Counters --!TBXINSTANCESTART counterA:customCounter generic map ( EOBFLAG => "YES", ZEROFLAG => "NO", BACKWARDS => "NO", EQUALFLAG => "YES", subwidth => 4, width => 9 ) port map ( clk => clk, rst => rst, go => s_go_a, set => s_set_a, setValue => s_block_start_a, cmpBlockValue => s_block_end_a, zero_flag => open, eob_flag => s_eb_a, eq_flag => s_eq_a, count => adda ); --!TBXINSTANCEEND --!TBXINSTANCESTART counterB:customCounter generic map ( EOBFLAG => "YES", ZEROFLAG => "NO", BACKWARDS => "NO", EQUALFLAG => "YES", subwidth => 4, width => 9 ) port map ( clk => clk, rst => rst, go => s_go_b, set => s_set_b, setValue => s_block_start_b, cmpBlockValue => s_block_end_b, zero_flag => open, eob_flag => s_eb_b, eq_flag => s_eq_b, count => addb ); --!TBXINSTANCEEND --!TBXINSTANCESTART counterDly:customCounter generic map( EOBFLAG => "NO", ZEROFLAG => "YES", BACKWARDS => "YES", EQUALFLAG => "NO", width => 5, subwidth => 0 ) port map ( clk => clk, rst => rst, go => s_go_delay, set => s_set_dly, setValue => s_delay_field(4 downto 0), cmpBlockValue => "00000", zero_flag => s_zeroFlag_delay, eob_flag => open, eq_flag => open, count => open ); --!TBXINSTANCEEND sm_comb: process (s_state, full_r,s_eb_b,s_combinatory,s_zeroFlag_delay,s_eq_b,s_eb_a,s_eq_a,instrQ_empty) begin --!Señal de play/pause del contador de direcciones para el parámetro B/D. s_go_b <= not(full_r and s_eb_b); --!Señal de play/pause del contador de direcciones para el parámetro A/C. if s_combinatory='0' then s_go_a <= not(full_r and s_eb_b); else s_go_a <= not(full_r) and s_eb_b and s_eq_b; end if; --!Señal de play/pause del contador del arithmetic pipeline flush counter. s_go_delay <= not(s_zeroFlag_delay); --! Si estamos en el final de la instrucción, "descargamos" esta de la máquina de estados con acknowledge read. if s_eb_b='1' and s_eq_b='1' and s_eb_a='1' and s_eq_a='1' and s_state=EXECUTE_INSTRUCTION then instrRdAckd <= '1'; else instrRdAckd <= '0'; end if; if (s_eb_a='1' and s_eq_a='1') or s_state=LOAD_INSTRUCTION or s_state=FLUSH_ARITH_PIPELINE then s_set_a <= '1'; else s_set_a <= '0'; end if; if (s_eb_b='1' and s_eq_b='1') or s_state=LOAD_INSTRUCTION or s_state=FLUSH_ARITH_PIPELINE then s_set_b <= '1'; else s_set_b <= '0'; end if; end process; sm_proc: process (clk,rst,s_state, full_r,s_eb_b,s_combinatory,s_zeroFlag_delay,s_eq_b,s_eb_a,s_eq_a,instrQ_empty) begin if rst=rstMasterValue then s_state <= LOAD_INSTRUCTION; s_set_dly <= '1'; sync_chain_0 <= '0'; eoi<='0'; s_dpc_uca <= (others => '0'); elsif clk='1' and clk'event then case s_state is --! Cargar la siguiente instrucción. when LOAD_INSTRUCTION => eoi <= '0'; if instrQ_empty='0' and full_r='0' then --! Siguiente estado: Ejecutar la instrucción. s_state <= EXECUTE_INSTRUCTION; --! Asignar el código UCA para que comience la decodificación. s_dpc_uca <= s_instr_uca; --! Validar el siguiente dato dentro del pipeline aritmético. sync_chain_0 <= '1'; --! En el estado EXECUTE, el valor del contador de delay se debe mantener fijo, y puesto en el valor de delay que contiene la instruccion. s_set_dly <= '1'; end if; --! Ejecución de la instruccion when EXECUTE_INSTRUCTION => if s_eb_b='1'and s_eq_b='1' and s_eb_a='1' and s_eq_a='1' then --! Revisar si es el fin de la instruccion --!Ya no ingresaran mas datos al pipeline aritmético, invalidar. sync_chain_0 <= '0'; if s_zeroFlag_delay='1' then --! Notificar fin de procesamiento de la instruccion (End Of Instruction) eoi <= '1'; s_state <= LOAD_INSTRUCTION; s_set_dly <= '1'; else s_state <= FLUSH_ARITH_PIPELINE; s_set_dly <= '0'; end if; --! Invalidar/validar datos dentro del pipeline aritmético. elsif s_eb_b='1' and full_r='1' then --! Invalidar el siguiente dato dentro del pipeline aritmético. sync_chain_0 <= '0'; else sync_chain_0 <= '1'; end if; --! Ejecución de la instrucción when FLUSH_ARITH_PIPELINE => --! Este estado permanece así hasta que, haya una instrucción if s_zeroFlag_delay='1' then --! Notificar fin de procesamiento de la instruccion (End Of Instruction) eoi <= '1'; s_state <= LOAD_INSTRUCTION; s_set_dly <= '1'; end if; when others => null; end case; end if; end process; end architecture;
Go to most recent revision | Compare with Previous | Blame | View Log