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

Subversion Repositories raytrac

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /raytrac/branches/fp
    from Rev 144 to Rev 145
    Reverse comparison

Rev 144 → Rev 145

/sm.vhd
32,24 → 32,37
width : integer := 32;
widthadmemblock : integer := 9
--!external_readable_widthad :
)
);
port (
clk,rst:in std_logic;
--! Señales normales de secuencia.
clk,rst: in std_logic;
adda,addb:out std_logic_vector (widthadmemblock-1 downto 0);
sync_chain_d:out std_logic;
--! ENTRADAS DE CONTROL DE SINCRONIZACION.
--! 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.
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.
dpc_uca : out std_logic_vector (2 downto 0);
dpc_uca : out std_logic_vector (2 downto 0)
);
57,82 → 70,205
 
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;
constant rstMasterValue : std_logic:='0';
component customCounter
generic (
width : integer
EOBFLAG : string ;
ZEROFLAG : string ;
BACKWARDS : string ;
EQUALFLAG : string ;
subwidth : integer;
width : integer
);
port (
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)
)
);
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
--! 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_b <= instrQq(width-14 downto width-18);
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
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
port map (clk,rst,add_condition_b,set_b,instrQq(width-9 downto width-12)&x"0",addt0_blockb);
adda <= addt0_blocka;
addb <= addt0_blockb;
generic map ("YES","NO","NO","YES",4,9)
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);
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&ntilde;al de play/pause del contador de direcciones para el par&aacute;metro B/D.
s_go_b <= not(full_r and s_eb_b);
--!Se&ntilde;al de play/pause del contador de direcciones para el par&aacute;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&ntilde;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:
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
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
case state is
when FLUSH_TO_NEXT_INSTRUCTION =>
--! Chequear si hay una instruccion en la salida de la cola de instruccioens.
if instrQempty='0' then
--! Cargar la siguiente instrucción.
when LOAD_INSTRUCTION =>
if instrQ_empty='0' and full_r='0' then
--! Chequear si la cola de resultados tiene espacio.
if resultQfull='0' then
--! Siguiente estado: Ejecutar la instrucción.
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
state <= LOAD_INSTRUCTION;
s_set_dly <= '1';
--! 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.
else
state <= FLUSH_ARITH_PIPELINE;
s_set_dly <= '0';
--! Now check that arithmetic pipline is not busy
if arithPbusy='0' then
when EXECUTE_INSTRUCTION =>
if addt1_blockb(4 downto 0)=x"1f" and addt1_blocka=x"1f" then
if addt1_blockb(8 downto )
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
end if;
state <= LOAD_INSTRUCTION;
s_set_dly <= '1';
end if;
when others => null;
end case;
end if;
end process;
nxtadda_proc:
process ()
end architecture;
/dpc.vhd
37,7 → 37,7
fifo32x23_q : in std_logic_vector (03*width-1 downto 0); --! Salida de la cola intermedia.
fifo32x09_q : in std_logic_vector (02*width-1 downto 0); --! Salida de las colas de producto punto.
unary,crossprod,addsub : in std_logic; --! Bit con el identificador del bloque AB vs CD e identificador del sub bloque (A/B) o (C/D).
sync_chain_d : in std_logic; --! Señal de dato valido que se va por toda la cadena de sincronizacion.
sync_chain_0 : in std_logic; --! Señal de dato valido que se va por toda la cadena de sincronizacion.
sqr32blki,inv32blki : out std_logic_vector (width-1 downto 0); --! Salidas de las 2 raices cuadradas y los 2 inversores.
fifo32x26_d : out std_logic_vector (03*width-1 downto 0); --! Entrada a la cola intermedia para la normalizaci&oacute;n.
fifo32x09_d : out std_logic_vector (02*width-1 downto 0); --! Entrada a las colas intermedias del producto punto.
95,14 → 95,13
begin
--! Cadena de sincronizaci&oacute;n: 29 posiciones.
ssync_chain_d <= sync_chain_d;
ssync_chain(0) <= sync_chain_0;
sync_chain_proc:
process(clk,rst)
begin
if rst=rstMasterValue then
ssync_chain <= (others => '0');
ssync_chain(28 downto 1) <= (others => '0');
elsif clk'event and clk='1' then
ssync_chain(0) <= ssync_chain_d;
for i in 28 downto 1 loop
ssync_chain(i) <= ssync_chain(i-1);
end loop;
/customCounter.vhd
28,11 → 28,17
 
entity customCounter is
generic (
width : integer := 9
)
EOBFLAG : string := "NO";
ZEROFLAG : string := "YES";
BACKWARDS : string := "YES";
EQUALFLAG : string := "NO";
subwidth : integer := 0;
width : integer := 5
);
port (
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); --! Los 5 bits de arriba.
zero_flag,eob_flag, eq_flag : out std_logic;
count : out std_logic_vector (width - 1 downto 0)
);
end entity;
42,17 → 48,111
architecture customCounter_arch of customCounter is
 
constant rstMasterValue : std_logic := '0';
signal scount_d, scount_q : std_logic_vector(width-1 downto 0);
signal scount_d, scount_q, sgo : std_logic_vector(width-1 downto 0);
signal seob_flag : std_logic;
 
begin
 
--!Compara los bits superiores solamente, si subwidth es 4 y width es 9 comparara los 9-4=5 bits superiores.
steadyEqualFlag:
if EQUALFLAG/="YES" generate
eq_flag <= '0';
end generate steadyEqualFlag;
equalFlagsProcess:
if EQUALFLAG="YES" generate
process (scount_d(width-1 downto subwidth),cmpBlockValue,clk,rst)
begin
if rst=rstMasterValue then
eq_flag <= '0';
elsif clk'event and clk='1' then
if scount_d(width-1 downto subwidth)=cmpBlockValue then
eq_flag <= '1';
else
eq_flag <= '0';
end if;
end if;
end process;
end generate equalFlagsProcess;
 
--Backwards or Forwards.
forwardGenerator:
if BACKWARDS="NO" generate
sgo(width-1 downto 1) <= (others => '0');
sgo(0) <= go;
end generate forwardGenerator;
 
backwardGenerator:
if BACKWARDS="YES" generate
sgo(width-1 downto 0) <= (others => go);
end generate backwardGenerator;
 
--! Si en los par&aacute;metros no se encuentra especificado que detecte el zero entonces la salida zero_flag estar&aacute; en cero siempre.
steadyZeroFlag:
if ZEROFLAG/="YES" generate
zero_flag <= '0';
end generate steadyZeroFlag;
--! Si el par&aacute;metro para la bandera de cero se especifica, entonces se instancia un proceso que depende del valor del conteo.
zeroFlagProcess:
if ZEROFLAG="YES" generate
--! Proceso para calcular la bandera de cero, en el conteo.
process (scount_d,clk,rst)
begin
if rst=rstMasterValue then
zero_flag <= '0';
elsif clk'event and clk='1' then
zero_flag <= '1';
for i in width-1 downto 0 loop
if scount_d(i) = '1' then
zero_flag <= '0';
exit;--the loop;
end if;
end loop;
end if;
end process;
end generate zeroFlagProcess;
--! Proceso para controlar la salida de la bandera de fin de bloque. Se colocar&aacute; en uno l&oacute;gico cuando el conteo vaya en multiplo de 32 menos 1.
steadyEobFlag:
if EOBFLAG/="YES" generate
eob_flag <= '0';
end generate steadyEobFlag;
eobFlagProcess:
if EOBFLAG="YES" generate
process (scount_d(subwidth-1 downto 0),clk,rst)
begin
if rst=rstMasterValue then
eob_flag <= '0';
elsif clk'event and clk='1' then
eob_flag <= '1';
for i in subwidth-1 downto 0 loop
if scount_d(i) /= '1' then
eob_flag <= '0';
exit;--the loop
end if;
end loop;
end if;
end process;
end generate eobFlagProcess;
--! Salida combinatoria del contador.
count <= scount_d;
--! Proceso de control del conteo.
add_proc:
process (scount_q,go,set,setValue)
process (scount_q,sgo,set,setValue)
begin
case set is
when '1' => scount_d <= setValue;
when others => scount_d <= scount_q+go;
case set is
--! Si subwidth es cero, p.ej. cuando se quiere hacer un contador simple y no detectar el final de bloques de 4 bits de ancho, el compilador ignora el statement con la expresi&oacute;n por fuera del rango.
when '1' => scount_d(subwidth-1 downto 0) <= (others => '0');scount_d(width-1 downto subwidth) <= setValue;
--! Strange, but yet true. Esto se puede hacer, es practicamente una compilacion condicional pero posiblemente coste una cuantas celdas logicas.
-- if subwidth>0 then
-- scount_d(subwidth-1 downto 0) <= (others => '0');
-- end if;
when others => scount_d <= scount_q+sgo;
end case;
end process;

powered by: WebSVN 2.1.0

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