--************************************************--
--**     Vlastni procesorova architektura       **--
--**   Autor: Leos Marsalek    (c) 2002-2003    **--
--**     E-mail: Leos.Marsalek@tiscali.cz       **--
--**      Spolupracovali : Lukas Vaculík,       **--
--**              Miroslav Copian               **--
--************************************************--

library IEEE;                                   -- Zviditelneni knihovny
use IEEE.std_logic_1164.all;                           -- Vyuziti knihovny
entity hazard is 
    
port (power:in STD_logic:='0');
end;

Architecture CPU_HAZARD of hazard is

component 
registr16 is                  
-- entita pro register
Port(Ain STD_LOGIC_vector (15 downto 0);bout STD_LOGIC_vector (15 downto 0):="0000000000000000";
clk,Enable:in STD_LOGIC);
end component;

component clock is                                  --entita hodin
generic (Tpw Time:=25 ns;                        --íøka pulsu
Tps Time:=25 nS);                              --fazove posunuti
port (reset:in std_logic:='1';clk1clk2clk3,notclk1,notclk2,notclk3 out std_logic:='1');
end component;

component dekoder_instr is 
    
port (A:in STD_LOGIC_vector(15 downto 0);C_bit:in STD_logic;
  B:out STD_logic_vector(downto 0);C_out:out Std_logic);
end component;    

component dekoder_NZVC is 
    
port(D,A,B,IR:in STD_logic_vector15 downto 0);Carry:in STD_logic;PSW:out STD_LOGIC_vector(15 downto 0));
end component;

component mux_vs2_s4 is 
    
port (A,B:in STD_LOGIC_vector(downto 0);c:out STD_logic_vector(downto 0); x:in std_logic);
end component ;

component mux_vs2_s6 is 
    
port (A,B:in STD_LOGIC_vector(downto 0);c:out STD_logic_vector(downto 0); x:in std_logic);
end component;  

component mux_vs2_s16 is 
    
port (A,B:in STD_LOGIC_vector(15 downto 0);c:out STD_logic_vector(15 downto 0); x:in std_logic);
end component;           


component mux_vs4_s1 is 
    
port (A,B,C,D:in STD_LOGICE:out STD_logicxx:in std_logic_vector(downto 0));
end component;   


component memory is                                                       --pamìt pro CPU Hazard
Port(datainin STD_LOGIC_vector (15 downto 0);                            -- Vstupní 16 bitové slovo
     dataoutout STD_LOGIC_vector (15 downto 0);                          -- Výstupní 16 bitové slovo pamìti
     adrin STD_LOGIC_vector (15 downto 0);                               -- adresa pamìti
rw,Enable,clk:in STD_LOGIC);                                             -- øídící signály pamìti
end component memory;   

component mux_vs3_s6 is 
    
port (A,B,C:in STD_LOGIC_vector(downto 0);D:out STD_logic_vector(downto 0);
          
xx:in std_logic_vector(downto 0));
end component;  

component banka_registru is 
    
port (A:in STD_LOGIC_vector(15 downto 0);
          
Src_out,dst_out:out STD_logic_vector(15 downto 0); 
          
Adr_src,Adr_dst:in std_logic_vector(downto 0);
          
clk,enable,rw_dst,rw_srcSTD_logic);
end component;  

component ALU is 
    
port (SRC,DSTin STD_Logic_vector (15 downto 0);
          
resultout STD_Logic_vector (15 downto 0);
          
carryout STD_LogicCinin STD_logic;
          
codein STD_logic_vector(downto 0);
          
clk,enablein STD_logic);
end component alu;

-- komponenta øízení se musi dotáhnout do finalniho stavu.
component rizeni is 
    
port (clk3,resetin std_logic:='0';
       IR_ZA_REG,PSW:in std_logic_vector(15 downto 0);
         
ridici_slovo:inout STD_logic_vector(70 downto 0));         
end component rizeni;   
-- komponenta øízení se musi dotáhnout do finalniho stavu.


--definovane prenosove signaly
signal ridici_slovo:STD_logic_vector(70 downto 0);
alias souc_stav:STD_LOGIC_vector(downto 0is ridici_slovo (downto 0);      -- soucasny stav sekvencniho obvodu
alias vetveni:STD_LOGIC_vector(downto 0is ridici_slovo (13 downto 9);       -- Oznaceni vetveni
alias r_rw_memory:Std_logic is  ridici_slovo(14);                               -- Signal z rizeni cteni/zapis v pameti
alias r_e_alu:Std_logic is  ridici_slovo(15);                                   -- povoleni zapisu do registru D v alu
alias r_e_adr_reg_mem:Std_logic is  ridici_slovo(16);                           -- Povoleni zapisu do adresniho registru pameti
alias r_e_dataout_reg_mem:Std_logic is ridici_slovo(17);                        -- Povoleni z rizeni do DATAOUT registru
alias r_e_mem:Std_logic is ridici_slovo(18);                                    -- povoleni operaci s pameti
alias r_e_datain_reg_mem:Std_logic is ridici_slovo(19);                         -- Umozneni zapisu do DATAIN registru
alias r_e_registry:Std_logic is ridici_slovo(20);                               -- Umozneni zapisu do sady registru DST a SRC;
alias r_mux_adr_reg:Std_logic is ridici_slovo(21);                              -- nastaveni muxu u adr registru
alias r_mux_dataout:Std_logic is ridici_slovo(22);                              -- nastaveni cesty pro odchod dat
alias r_e_Ir_reg:Std_logic is ridici_slovo(23);                                 -- povoleni zapisu do IR registru
alias r_rw_dst:Std_logic is ridici_slovo(24);                                   -- vyber mezi ctenim/zapisem dst registru
alias r_rw_src:Std_logic is ridici_slovo(25);                                   -- zapis/cteni registru src
alias r_cin:STD_LOGIC_vector(downto 0is ridici_slovo(27 downto 26);         --
alias r_alu_code:STD_logic_vector(downto 0is ridici_slovo(31 downto 28);    -- kod pro operace alu
alias r_alu_code_muxSTD_logic is ridici_slovo (32);                           -- nastaveni muxu pred ALU
alias r_src_r_adrSTD_logic_vector(downto 0is ridici_slovo(38 downto 33);  -- adresa cteni SRC registru
alias r_src_w_adrSTD_logic_vector(downto 0is ridici_slovo(44 downto 39);  -- adresa zapisu SRC registru
alias r_dst_r_adrSTD_logic_vector(downto 0is ridici_slovo(50 downto 45);  -- adresa cteni DST registru
alias r_dst_w_adrSTD_logic_vector(downto 0is ridici_slovo(56 downto 51);  -- adresa zapisu dst registru
alias r_m1:STD_logic_vector(downto 0is ridici_slovo(58 downto 57);          -- nastaveni Muxu m1 pro adresaci banky registru
alias r_m2:STD_logic_vector(downto 0is ridici_slovo(60 downto 59);          -- nastaveni Muxu m2 pro adresaci banky registru
alias r_m3:STD_logic_vector(downto 0is ridici_slovo(62 downto 61);          -- nastaveni Muxu m3 pro adresaci banky registru
alias r_m4:STD_logic_vector(downto 0is ridici_slovo(64 downto 63);   

signal clock1,clock2,clock3,notclock1,notclock2,notclock3,clock_reset,
       
z_dek_cin,alu_cin,alu_carry
        
std_logic:='0';
signal sbernice,data_mem_out,data_mem_in,adr_mem,
        
adr_z_muxu,data_z_muxu,ir,PSW,data_src,data_dst
        
STD_logic_vector(15 downto 0):="0000000000000000";
alias psw_cin:STD_logic is psw (15) ;

signal alu_code,alu_operaceSTD_logic_vector (downto 0):="0000";

signal pom_src_r,pom_src_w,pom_DST_r,pom_dst_w,ADR_SRC,ADR_dst:STD_logic_vector (downto 0):="000000";

alias ir_dst_reg:STD_logic_vector(downto 0is IR (downto 0);     -- pro 5 bitu neni postaveno adresovani, proto
alias ir_src_reg:STD_logic_vector(downto 0is IR (11 downto 6);    -- jsem to tady zmenil na 6 bitu
------------------------------------------------------------------------------------------------
begin            
            
hodiny
:clock port map(clock_reset,clock1,clock2,clock3,notclock1,notclock2,notclock3);                                               --hodiny
            
pamet:memory Port map (data_mem_out,data_mem_in,adr_mem,r_rw_memory,'1',clock2);  --pamet
            
            
Adr_reg:registr16 port map(adr_z_muxu,adr_mem,notclock1,r_e_adr_reg_mem);            --adresni registr
            
ADR_MUX:mux_vs2_s16 port map(DATA_src,DATA_dst,adr_z_muxu,r_mux_adr_reg);                 -- mux pro nastaveni zdroje adr.
            
DATAin_REG:registr16 port map(data_mem_out,sbernice,notclock2,r_e_datain_reg_mem); --Datain registr
            
DATAout_REG:registr16 port map(Data_z_muxu,Data_mem_in,clock2,r_e_dataout_reg_mem);  --Dataout registr
            
DATAOUT_MUX:mux_vs2_s16 port map(DATA_src,DATA_dst,DATA_z_muxu,r_mux_dataout);           -- Mux pro nastaveni odchodu dat
            
IR_REG:registr16 port map(data_mem_out,IR,notclock2,r_e_Ir_reg); 
            
IR_DEKODER:dekoder_instr port map(IR,psw_cin,ALU_CODE,z_dek_cin);                              --dekoduje z instrukce operaci pro ALU


            
ALUCIN_MUX:mux_vs4_s1 port map(psw_cin,z_dek_cin,'1','0',Alu_cin,r_cin); 
            
ALU_MUX_CODEmux_vs2_s4 port map(Alu_code,R_alu_code,Alu_operace,R_ALU_code_mux );              --mux nastavujici zdroj kodu pro ALU
            
BLOK_ALU:ALU port map(DATA_src,DATA_dst,Sbernice,alu_carry,Alu_cin,ALU_operace,notclock2,r_e_alu);  -- aritmetickologick8 jednotka
            
            
BANK_REGISTRU:banka_registru port map(Sbernice,DATA_src,DATA_DST,ADR_SRC,ADR_dst,Clock3,'1',r_rw_dst,r_rw_src); -- Banka registru
 
             
M1:mux_vs3_s6 port map (r_src_r_adr,ir_src_reg,ir_dst_reg,pom_src_r,r_m1);
           M2:mux_vs3_s6 port map (r_src_w_adr,ir_src_reg,ir_dst_reg,pom_src_w,r_m2);
           M3:mux_vs3_s6 port map (r_dst_r_adr,ir_src_reg,ir_dst_reg,pom_dst_r,r_m3); 
             
M4:mux_vs3_s6 port map (r_dst_w_adr,ir_src_reg,ir_dst_reg,pom_dst_w,r_m4);
           
             MUX_BANK_REGISTER_SRC
:mux_vs2_s6 port map(pom_src_r,pom_src_w,adr_src,clock3);
              
MUX_BANK_REGISTER_DST:mux_vs2_s6 port map(pom_DST_r,pom_dst_w,adr_dst,clock3);
--- prekopano

             
bohove:rizeni port map(clock3,clock_reset,IR,psw,ridici_slovo);
             
BLOK_NZVC:dekoder_NZVC port map(Sbernice,Data_src,DATA_dst,IR,ALU_carry,PSW); 
end CPU_HAZARD;