Line 30... |
Line 30... |
entity sm is
|
entity sm is
|
generic (
|
generic (
|
width : integer := 32;
|
width : integer := 32;
|
widthadmemblock : integer := 9
|
widthadmemblock : integer := 9
|
--!external_readable_widthad :
|
--!external_readable_widthad :
|
)
|
);
|
port (
|
port (
|
|
|
|
--! Señales normales de secuencia.
|
clk,rst:in std_logic;
|
clk,rst:in std_logic;
|
|
|
adda,addb:out std_logic_vector (widthadmemblock-1 downto 0);
|
--! ENTRADAS DE CONTROL DE SINCRONIZACION.
|
sync_chain_d:out std_logic;
|
--! Señales de sincronización de recursos.
|
|
--! Las siguientes entradas tienen relevancia y son sensibles en los estados EXECUTE_INSTRUCTION y VERMEER_EXECUTE.
|
|
|
|
|
|
|
|
--! ENTRADAS
|
|
|
|
|
|
|
--! Instruction Q, instruction.
|
--! Instruction Q, instruction.
|
instrQq:in std_logic_vector(width-1 downto 0);
|
instrQq:in std_logic_vector(width-1 downto 0);
|
|
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.
|
|
|
|
|
|
|
--! apempty, arithmetical pipeline empty.
|
|
arithPbusy, instrQempty ,resultQfull: in std_logic;
|
|
|
|
--! DataPath Control uca code.
|
--! DataPath Control uca code.
|
dpc_uca : out std_logic_vector (2 downto 0);
|
dpc_uca : out std_logic_vector (2 downto 0)
|
|
|
|
|
);
|
);
|
end entity;
|
end entity;
|
|
|
architecture sm_arch of sm is
|
architecture sm_arch of sm is
|
|
|
type macState is (FLUSH_TO_NEXT_INSTRUCTION,EXECUTE_INSTRUCTION);
|
type macState is (LOAD_INSTRUCTION,FLUSH_ARITH_PIPELINE,EXECUTE_INSTRUCTION);
|
|
--! 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 state : macState;
|
signal state : macState;
|
constant rstMasterValue : std_logic:='0';
|
constant rstMasterValue : std_logic:='0';
|
|
|
component customCounter
|
component customCounter
|
generic (
|
generic (
|
|
EOBFLAG : string ;
|
|
ZEROFLAG : string ;
|
|
BACKWARDS : string ;
|
|
EQUALFLAG : string ;
|
|
subwidth : integer;
|
width : integer
|
width : integer
|
|
|
);
|
);
|
port (
|
port (
|
clk,rst,go,set : in std_logic;
|
clk,rst,go,set : in std_logic;
|
setValue : in std_Logic_vector(width-1 downto 0);
|
setValue,cmpBlockValue : in std_Logic_vector(width-1 downto subwidth);
|
|
zero_flag,eob_flag,eq_flag : out std_logic;
|
count : out std_logic_vector(width-1 downto 0)
|
count : out std_logic_vector(width-1 downto 0)
|
)
|
);
|
|
end component;
|
signal addt0_blocka,addt0_blockb,set_Value_A,set_Value_B : std_logic_vector(widthadmemblock-1 downto 0);
|
|
signal add_condition_a, add_condition_b,set_a,set_b : std_logic;
|
|
signal s_dpc_uca, s_instrQ_uca : std_logic_vector(2 downto 0);
|
|
signal s_block_start_a, s_block_start_b, s_block_end_a, s_block_end_b : std_logic_vector(4 downto 0);
|
|
|
|
|
|
|
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
|
begin
|
|
--! 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
|
|
|
--! Bloques asignados en la instrucci´øn
|
s_block_start_a <= instrQq(width-4 downto width-8);
|
s_block_start_a <= instrQq(width-4 downto width-8);
|
s_block_start_b <= instrQq(width-14 downto width-18);
|
|
s_block_end_a <= instrQq(width-9 downto width-13);
|
s_block_end_a <= instrQq(width-9 downto width-13);
|
s_block_end_b <= instrQq(width-19 downto width-)
|
|
|
s_block_start_b <= instrQq(width-14 downto width-18);
|
|
s_block_end_b <= instrQq(width-19 downto width-23);
|
|
|
|
--! Campo que define si la instrucción es combinatoria
|
|
s_combinatory <= instrQq(width-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(width-25 downto width-32);
|
|
|
|
--! UCA code, código con la instrucción a ejecutar.
|
|
s_instr_uca <= instrQq(31 downto 29);
|
|
|
--! Address Counters
|
--! Address Counters
|
counterA:customCounter
|
counterA:customCounter
|
port map (clk,rst,add_condition_a,set_a,instrQq(width-4 downto width-8)&x"0",addt0_blocka);
|
generic map ("YES","NO","NO","YES",4,9)
|
|
port map (clk,rst,s_go_a,s_set_a,s_block_start_a,s_block_end_a,open,s_eb_a,s_eq_a,adda);
|
counterB:customCounter
|
counterB:customCounter
|
port map (clk,rst,add_condition_b,set_b,instrQq(width-9 downto width-12)&x"0",addt0_blockb);
|
generic map ("YES","NO","NO","YES",4,9)
|
adda <= addt0_blocka;
|
port map (clk,rst,s_go_b,s_set_b,s_block_start_b,s_block_end_b,open,s_eb_b,s_eq_b,addb);
|
addb <= addt0_blockb;
|
counterDly:customCounter
|
|
generic map("NO","YES","YES","NO",0,5)
|
|
port map (clk,rst,s_go_delay,s_set_dly,s_delay_field(4 downto 0),"00000",s_zeroFlag_delay,open,open,open);
|
|
|
--! uca code
|
|
s_instrQ_uca <= instrQq(31 downto 29);
|
|
|
|
|
sm_comb:
|
|
process (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 state=EXECUTE_INSTRUCTION then
|
|
instrRdAckd <= '1';
|
|
else
|
|
instrRdAckd <= '0';
|
|
end if;
|
|
|
|
if (s_eb_a='1' and s_eq_a='1') or state=LOAD_INSTRUCTION or 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 state=LOAD_INSTRUCTION or state=FLUSH_ARITH_PIPELINE then
|
|
s_set_b <= '1';
|
|
else
|
|
s_set_b <= '0';
|
|
end if;
|
|
|
|
end process;
|
|
|
sm_proc:
|
sm_proc:
|
process (clk,rst)
|
process (clk,rst,state, full_r,s_eb_b,s_combinatory,s_zeroFlag_delay,s_eq_b,s_eb_a,s_eq_a,instrQ_empty)
|
begin
|
begin
|
|
|
if rst=rstMasterValue then
|
if rst=rstMasterValue then
|
state <= IDLE;
|
|
ird_ack <= '0';
|
state <= LOAD_INSTRUCTION;
|
|
s_set_dly <= '1';
|
|
sync_chain_0 <= '0';
|
|
s_dpc_uca <= (others => '0');
|
|
|
|
|
elsif clk='1' and clk'event then
|
elsif clk='1' and clk'event then
|
|
|
case state is
|
case state is
|
when FLUSH_TO_NEXT_INSTRUCTION =>
|
|
|
|
--! Chequear si hay una instruccion en la salida de la cola de instruccioens.
|
--! Cargar la siguiente instrucción.
|
if instrQempty='0' then
|
when LOAD_INSTRUCTION =>
|
|
|
|
if instrQ_empty='0' and full_r='0' then
|
|
|
|
--! Siguiente estado: Ejecutar la instrucción.
|
|
state <= EXECUTE_INSTRUCTION;
|
|
|
--! Chequear si la cola de resultados tiene espacio.
|
--! Asignar el código UCA para que comience la decodificación.
|
if resultQfull='0' then
|
s_dpc_uca <= s_instr_uca;
|
|
|
--! Si el codigo de instruccion (uca) que se encuentra en el DPC es igual al que se encuentra en la instruccion de la salida de la cola de instrucciones, entonces no hay mas validaciones que hacer.
|
--! 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';
|
|
|
--! Now check that arithmetic pipline is not busy
|
|
if arithPbusy='0' then
|
|
|
|
|
|
|
end if;
|
|
|
|
--! Ejecución de la instruccion
|
when EXECUTE_INSTRUCTION =>
|
when EXECUTE_INSTRUCTION =>
|
if addt1_blockb(4 downto 0)=x"1f" and addt1_blocka=x"1f" then
|
|
if addt1_blockb(8 downto )
|
|
|
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
|
|
|
|
state <= LOAD_INSTRUCTION;
|
|
s_set_dly <= '1';
|
|
|
|
|
|
else
|
|
|
|
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
|
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
|
|
|
|
state <= LOAD_INSTRUCTION;
|
|
s_set_dly <= '1';
|
|
|
|
|
end if;
|
end if;
|
|
|
|
when others => null;
|
|
|
end case;
|
end case;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
nxtadda_proc:
|
|
process ()
|
|
end architecture;
|
end architecture;
|
|
|
No newline at end of file
|
No newline at end of file
|