----------------------------------------------------------------------------- -- This file is a part of the ARM8/9 VHDL model with architecture ARMv4 -- Copyright (C) 2001 Escuela Superior de Ingenieros (ESI) Sevilla ----------------------------------------------------------------------------- -- Entity: pipeline -- File: pipeline.vhd -- Author: Francisco Javier Jurado Carmona -- Tutor: Jonathan Noel Tombs -- Description: five stages pipeline architecture ------------------------------------------------------------------------------ -- Version control: -- 20-10-2001: First implemetation -- 14-12-2001: First Revision -- 05-03-2002: Second Revision ------------------------------------------------------------------------------ library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use work.ARM8.all; entity pipeline is port ( clk: in std_logic; resetz: in std_logic; inst: in std_logic_vector (31 downto 0); PC: out std_logic_vector (31 downto 0); ----- EXCEPTIONS INTERFAZ ------------- exc_happens: in std_logic; exception: in std_logic_vector (2 downto 0); und_notify: out std_logic; swi_notify: out std_logic; nABORT: in std_logic; ----- MEMORY INTERFACE ---------------- Rdata: in std_logic_vector (31 downto 0); Wdata: out std_logic_vector (31 downto 0); r_enable: out std_logic; w_enable: out std_logic; Size: out std_logic_vector (1 downto 0); d_address: out std_logic_vector (31 downto 0); wait_state: in std_logic_vector (1 downto 0); Privileged: out std_logic; ----- ALU's BUSES --------------------- A: out std_logic_vector (31 downto 0); B: out std_logic_vector (31 downto 0); C: out std_logic_vector (31 downto 0); Result: in std_logic_vector (31 downto 0); alu_op: out std_logic_vector (4 downto 0); shift_type: out std_logic_vector (1 downto 0); mult_ctrl: out std_logic; Cin: out std_logic; Cout: in std_logic; Vin: out std_logic; Vout: in std_logic ); end pipeline; architecture COMP of pipeline is signal R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,R13,R14,R15: std_logic_vector (31 downto 0); signal CPSR,SPSR_fiq,SPSR_svc,SPSR_abt,SPSR_irq,SPSR_und: std_logic_vector (31 downto 0); signal R8_fiq,R9_fiq,R10_fiq,R11_fiq,R12_fiq,R13_fiq,R14_fiq: std_logic_vector (31 downto 0); signal R13_svc,R14_svc,R13_abt,R14_abt,R13_irq,R14_irq,R13_und,R14_und: std_logic_vector (31 downto 0); signal pR0,pR1,pR2,pR3,pR4,pR5,pR6,pR7,pR8,pR9,pR10,pR11,pR12,pR13,pR14,pR15:std_logic_vector (31 downto 0); signal pCPSR,pSPSR_fiq,pSPSR_svc,pSPSR_abt,pSPSR_irq,pSPSR_und: std_logic_vector (31 downto 0); signal pR8_fiq,pR9_fiq,pR10_fiq,pR11_fiq,pR12_fiq,pR13_fiq,pR14_fiq: std_logic_vector (31 downto 0); signal pR13_svc,pR14_svc,pR13_abt,pR14_abt,pR13_irq,pR14_irq,pR13_und,pR14_und: std_logic_vector (31 downto 0); signal d_inst, e_inst, m_inst, w_inst: std_logic_vector (31 downto 0); signal pd_inst, pe_inst, pm_inst, pw_inst: std_logic_vector (31 downto 0); signal m_data, w_data, m_address: std_logic_vector (31 downto 0); signal pm_data, pw_data, pm_address: std_logic_vector (31 downto 0); signal bA,bB,bC,pbA,pbB,pbC: std_logic_vector (31 downto 0); signal pAUXBUS,AUXBUS:std_logic_vector (4 downto 0); signal stop_fetch,stop_decode,stop_execute: std_logic; signal reset_fetch,reset_decode,reset_execute: std_logic; signal save_link: std_logic; signal jump: std_logic; signal jump_address: std_logic_vector (31 downto 0); signal mode: std_logic_vector (4 downto 0); signal PCplus4: std_logic_vector (31 downto 0); SIGNAL PCsub4,pPCsub4: std_logic_vector (31 downto 0); signal mult_long: std_logic; signal e_destiny, m_destiny, w_destiny: std_logic_vector (3 downto 0); signal e_nro, m_nro, w_nro: std_logic; signal e_wbReg,m_wbReg,w_wbReg: std_logic_vector (3 downto 0); signal m_temp_reg, w_temp_reg: std_logic_vector (31 downto 0); signal pm_temp_reg, pw_temp_reg: std_logic_vector (31 downto 0); signal e_wbr,m_wbr,w_wbr: std_logic; signal exc_report: std_logic; signal mcontrol, pmcontrol: std_logic; signal swp_flag: std_logic; signal enable: std_logic; signal ws: integer range 0 to 3; type ESTADO is (E0, E1, E2); signal pipeline, p_estado: ESTADO; signal pcuenta,cuenta: std_logic_vector (1 downto 0); signal mem_inst: std_logic; signal bitI, bitF: std_logic; begin mode<=CPSR(4 downto 0); bitI<=CPSR(7); bitF<=CPSR(6); exc_report<=exc_happens; ----------------------------------------------------------------------------- -- Pipeline Control ----------------------------------------------------------------------------- pipeline_ctrl : process(pipeline, ws, wait_state,mem_inst,reset_execute) variable temp: integer range 0 to 3; variable var1, var2: std_logic; begin stop_fetch<='0'; stop_decode<='0'; stop_execute<='0'; var1:='0'; var2:='0'; case pipeline is when E0 => p_estado<=E0; if ws>0 then var1:='1'; var2:='1'; if wait_state="00" then stop_execute<='0'; end if; if ws=3 then p_estado<=E2; elsif ws=2 then p_estado<=E1; elsif ws=1 then p_estado<=E0; end if; end if; when E1 => p_estado<=E0; var1:='1'; var2:='1'; when E2 => p_estado<=E1; var1:='1'; var2:='1'; end case; stop_fetch<=var1 or mem_inst; stop_decode<=var2 or mem_inst; stop_execute<=mem_inst and not reset_execute; end process; ----------------------------------------------------------------------------- -- Instruction fetch stage ----------------------------------------------------------------------------- fetch_stage: process(inst,d_inst,jump,jump_address,mult_long,reset_fetch, stop_fetch,R15,PCplus4,PCsub4,reset_execute) begin PC<=R15; pd_inst<=inst; PCplus4<=unsigned(R15)+4; pR15<=PCplus4; pPCsub4<=R15; -- PCsub4 = current PC - 4 if (stop_fetch)='1' then pR15<=R15; pPCsub4<=PCsub4; pd_inst<=d_inst; end if; if (reset_fetch)='1' then -- nop pd_inst(31 downto 28)<=NOP; end if; if mult_long='1' then pd_inst<=d_inst; pR15<=R15; pPCsub4<=PCsub4; end if; if (reset_execute)='1'then pd_inst(31 downto 28)<=NOP; end if; if (jump='1') then pR15<=jump_address; end if; end process; ----------------------------------------------------------------------------- -- Instruction decode stage ----------------------------------------------------------------------------- decode_stage : process(d_inst,bA,bB,bC,R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10, R11,R12,R13,R14,R15,R8_fiq,R9_fiq,R10_fiq,R11_fiq,R12_fiq, R13_fiq,R14_fiq,R13_svc,R14_svc,R13_abt,R14_abt,R13_irq, R14_irq,R13_und,R14_und,e_nro,w_nro,m_nro,w_destiny, m_destiny,mcontrol,e_destiny,mode,reset_decode,stop_decode, PCplus4, e_wbr, m_wbr,w_wbr,e_wbReg,m_wbReg,stop_execute, w_wbReg,AUXBUS,e_inst) variable op2: std_logic_vector (2 downto 0); variable eA,eB,eC: std_logic; variable busA,busB,busC: std_logic_vector (3 downto 0); variable temp: integer range 0 to 3; variable noper: std_logic; variable shift_reg: std_logic; begin --- Setting Inicial Values --------------------------------------------- pe_inst<=(others=>'0'); eA:='0'; eB:='0'; eC:='0'; busA:=(others=>'0'); busB:=(others=>'0'); busC:=(others=>'0'); temp:=0; shift_reg:='0'; pbA<=bA; pbB<=bB;pbC<=bC; pAUXBUS<=AUXBUS; mult_long<='0'; pmcontrol<='0'; ws<=0; ------------- DETECTING FALSE INTERLOCKING ------------------------------ noper:='0'; if d_inst(31 downto 28)=NOP then noper:='1'; end if; op2:=d_inst(27 downto 25); pe_inst(31 downto 28)<=d_inst(31 downto 28); case op2 is when "000" => -- Arithmetic Operation (op2 is a register) if d_inst(4)='0' or (d_inst(4)='1' and d_inst(7)='0') then pe_inst(27 downto 24)<=DATA_PSR; pe_inst(15 downto 12)<=d_inst(15 downto 12); pe_inst(21)<=d_inst(20); pe_inst(23 downto 22)<=d_inst(6 downto 5); pe_inst(20)<='0'; pe_inst(19 downto 16)<=d_inst(24 downto 21); eA:='1'; if d_inst(24 downto 21)="1101" or d_inst(24 downto 21)="1111" then eA:='0'; end if; eB:='1'; busA:=d_inst(19 downto 16); busB:=d_inst(3 downto 0); if d_inst(4)='0' then -- shift amount is an inmediate value pbC(4 downto 0)<=d_inst(11 downto 7); pbC(8 downto 5)<=x"0"; elsif d_inst(4)='1' and d_inst(7)='0' then -- s.a. is a register eC:='1'; busC:=d_inst(11 downto 8); shift_reg:='1'; end if; end if; -- multiply if d_inst(24 downto 22)="000" and d_inst(7 downto 4)="1001" then pe_inst(27 downto 24)<=MULTIPLY; pe_inst(23)<='0'; pe_inst(21)<=d_inst(20); pe_inst(15 downto 12)<=d_inst(19 downto 16); eA:='1'; eB:='1'; busA:=d_inst(3 downto 0); busB:=d_inst(11 downto 8); pe_inst(20 downto 17)<="1000"; pe_inst(16)<=d_inst(21); if d_inst(21)='1' then eC:='1'; busC:=d_inst(15 downto 12); end if; end if; -- multiply long if d_inst(24 downto 23)="01" and d_inst(7 downto 4)="1001" then pe_inst(27 downto 24)<=MULTIPLY; pe_inst(23)<='1'; pe_inst(22)<=mcontrol; pe_inst(21)<=d_inst(20); pe_inst(15 downto 12)<=d_inst(15 downto 12); pe_inst(11 downto 8) <=d_inst(19 downto 16); eA:='1'; eB:='1'; busA:=d_inst(3 downto 0); busB:=d_inst(11 downto 8); pe_inst(20 downto 18)<="101"; pe_inst(17 downto 16)<=d_inst(22 downto 21); if mcontrol='0' and stop_decode='0' and noper='0' then mult_long<='1'; -- for a extra-cycle pmcontrol<='1'; end if; if d_inst(21)='1' and mcontrol='0' then eC:='1'; busC:=d_inst(15 downto 12); elsif d_inst(21)='1' and mcontrol='1' then eC:='1'; busC:=d_inst(19 downto 16); end if; end if; -- MRS Instruction if d_inst (24 downto 23)="10" and d_inst (21 downto 16)="001111" and d_inst (11 downto 0)<=X"000" then pe_inst(27 downto 24)<=DATA_PSR; pe_inst(11)<='1'; pe_inst(10)<='0'; pe_inst(9)<=d_inst(22); pe_inst(8)<='0'; pe_inst(15 downto 12)<=d_inst(15 downto 12); pe_inst(20 downto 16)<=ALU_NOP; end if; -- MSR I=0 (PSR Transfer Instruction) if d_inst (24 downto 23)="10" and d_inst (21 downto 20)="10" and d_inst (15 downto 12)<=X"F" and d_inst (11 downto 4)=X"00" then pe_inst(27 downto 24)<=DATA_PSR; pe_inst(11)<='0'; pe_inst(10)<='1'; pe_inst(9)<=d_inst(22); pe_inst(8)<='0'; pe_inst(7 downto 4)<=d_inst(19 downto 16); eA:='1'; busA:=d_inst(3 downto 0); pe_inst(20 downto 16)<=ALU_A; pe_inst(15 downto 12)<=(others=>'1'); end if; -- Halfword and signed data transfer with register offset if d_inst(27 downto 25)="000" and d_inst(22)='0' and d_inst(7)='1' and d_inst(11 downto 8)=x"0" and d_inst(4)='1' and (d_inst(6 downto 5)="01" or d_inst(6 downto 5)="10" or d_inst(6 downto 5)="11") then pe_inst(27 downto 24)<=HALFWORD; pe_inst(23 downto 22)<="00"; pe_inst(21)<=d_inst(24); pe_inst(20 downto 16)<=ALU_MSUB; if d_inst(23)='1' then pe_inst(20 downto 16)<=ALU_MADD; end if; pe_inst(15 downto 12)<=d_inst(15 downto 12); pe_inst(11 downto 8) <=d_inst(19 downto 16); pe_inst(7)<=d_inst(22); pe_inst(6)<=d_inst(21); pe_inst(5)<=d_inst(20); pe_inst(4 downto 3)<=d_inst(6 downto 5); eA:='1'; busA:=d_inst(19 downto 16); eB:='1'; busB:=d_inst(3 downto 0); if d_inst(20)='0' then eC:='1'; busC:=d_inst(15 downto 12); end if; end if; -- Halfword and signed data transfer with immediate offset if d_inst(27 downto 25)="000" and d_inst(22)='1' and d_inst(7)='1' and d_inst(4)='1' and (d_inst(6 downto 5)="01" or d_inst(6 downto 5)="10" or d_inst(6 downto 5)="11") then pe_inst(27 downto 24)<=HALFWORD; pe_inst(23 downto 22)<="00"; pe_inst(21)<=d_inst(24); pe_inst(20 downto 16)<=ALU_MSUB; if d_inst(23)='1' then pe_inst(20 downto 16)<=ALU_MADD; end if; pe_inst(15 downto 12)<=d_inst(15 downto 12); pe_inst(11 downto 8) <=d_inst(19 downto 16); pe_inst(7)<=d_inst(22); pe_inst(6)<=d_inst(21); pe_inst(5)<=d_inst(20); pe_inst(4 downto 3)<=d_inst(6 downto 5); eA:='1'; busA:=d_inst(19 downto 16); pbB(31 downto 8)<=(others=>'0'); pbB(7 downto 4)<=d_inst(11 downto 8); pbB(3 downto 0)<=d_inst(3 downto 0); if d_inst(20)='0' then eC:='1'; busC:=d_inst(15 downto 12); end if; end if; -- Single Data Swap (SWP) if d_inst(24 downto 23)="10" and d_inst(11 downto 4)="00001001" and d_inst(21 downto 20)="00" then pe_inst(27 downto 24)<=SWP; pe_inst(20 downto 16)<=ALU_A; pe_inst(7)<=d_inst(22); pe_inst(5)<=not mcontrol; pe_inst(15 downto 12)<=d_inst(15 downto 12); pe_inst(11 downto 8)<=d_inst(19 downto 16); eA:='1'; busA:=d_inst(19 downto 16); eC:='1'; busC:=d_inst(3 downto 0); if mcontrol='0' and stop_decode='0' and noper='0' then mult_long<='1'; pmcontrol<='1'; end if; end if; when "001" => -- Arithmetic Operation (op2 is an inmediate value) pe_inst(27 downto 24)<=DATA_PSR; pe_inst(15 downto 12)<=d_inst(15 downto 12); pe_inst(21)<=d_inst(20); pe_inst(23 downto 22)<="11"; pbC(4 downto 1)<=d_inst(11 downto 8); pbC(0)<='0'; pbC(8 downto 5)<=x"0"; if d_inst (11 downto 8)="0000" then pe_inst (23 downto 22)<="00"; pbC<=(others=>'0'); end if; pe_inst(20)<='0'; pe_inst(19 downto 16)<=d_inst(24 downto 21); eA:='1'; if d_inst(24 downto 21)="1101" or d_inst(24 downto 21)="1111" then eA:='0'; end if; busA:=d_inst(19 downto 16); pbB(7 downto 0)<=d_inst(7 downto 0); pbB(31 downto 8)<=(others=>'0'); -- MSR I=1 (PSR Transfer Instruction) if d_inst (24 downto 23)="10" and d_inst (21 downto 20)="10" and d_inst (15 downto 12)<="1111" then pe_inst(27 downto 24)<=DATA_PSR; pe_inst(11)<='0'; pe_inst(10)<='1'; pe_inst(7 downto 4)<=d_inst(19 downto 16); pe_inst(9)<=d_inst(22); pe_inst(8)<='0'; eA:='0'; pbA<=(others=>'0'); eB:='0'; pbB(7 downto 0)<=d_inst(7 downto 0); pbB(31 downto 8)<=(others=>'0'); eC:='0'; pbC(4 downto 1)<=d_inst(11 downto 8); pbC(0)<='0'; -- rotate twice the value of d_inst[11:8] pbC(8 downto 5)<=x"0"; pe_inst(20 downto 16)<=ALU_ADD; pe_inst(23 downto 22)<="11"; pe_inst(15 downto 12)<=(others=>'1'); end if; when "101" => -- Branch and Branch with Link pe_inst(27 downto 24)<=BRANCH; pe_inst(20 downto 16)<=ALU_MADD; pe_inst(23)<=d_inst(24); pbA<=PCplus4; ---- 2 bytes ahead PC pbB(25 downto 2)<=d_inst(23 downto 0); pbB(1 downto 0)<=(others=>'0'); pbB(31 downto 26)<=(others=>d_inst(23)); when "010" => -- Single Data Transfer with I=0 pe_inst(27 downto 24)<=LDR_STR; pe_inst(23 downto 22)<="00"; pe_inst(21)<=d_inst(24); pe_inst(20 downto 16)<=ALU_MSUB; if d_inst(23)='1' then pe_inst(20 downto 16)<=ALU_MADD; end if; pe_inst(15 downto 12)<=d_inst(15 downto 12); pe_inst(11 downto 8) <=d_inst(19 downto 16); pe_inst(7)<=d_inst(22); pe_inst(6)<=d_inst(21); pe_inst(5)<=d_inst(20); pe_inst(1)<='0'; eA:='1'; busA:=d_inst(19 downto 16); pbB(11 downto 0)<=d_inst(11 downto 0); pbB(31 downto 12)<=(others=>'0'); if d_inst(20)='0' then eC:='1'; busC:=d_inst(15 downto 12); end if; when "011" => if d_inst(4)='1' then -- Undefined Instruction pe_inst(27 downto 24)<=UNDEFINED; pe_inst(20 downto 16)<=ALU_NOP; elsif d_inst(4)='0' then -- Single Data Transfer with I=1 pe_inst(27 downto 24)<=LDR_STR; pe_inst(23 downto 22)<=d_inst(6 downto 5); pe_inst(21)<=d_inst(24); pe_inst(20 downto 16)<=ALU_SUB; if d_inst(23)='1' then pe_inst(20 downto 16)<=ALU_ADD; end if; pe_inst(15 downto 12)<=d_inst(15 downto 12); pe_inst(11 downto 8) <=d_inst(19 downto 16); pe_inst(7)<=d_inst(22); pe_inst(6)<=d_inst(21); pe_inst(5)<=d_inst(20); pe_inst(1)<='1'; eA:='1'; busA:=d_inst(19 downto 16); eB:='1'; busB:=d_inst(3 downto 0); pAUXBUS(4 downto 0)<=d_inst(11 downto 7); if d_inst(20)='0' then eC:='1'; busC:=d_inst(15 downto 12); end if; end if; when "110" => -- Coprocessor Data Transfer pe_inst(27 downto 24)<=LDC_STC; pe_inst(20 downto 16)<=ALU_NOP; when "111" => if d_inst(24)='0' then if d_inst(4)='0' then -- Coprocessor Data Operation pe_inst(27 downto 24)<=CPD; pe_inst(20 downto 16)<=ALU_NOP; else -- Coprocessor Register Transfer pe_inst(27 downto 24)<=MRC_MCR; pe_inst(20 downto 16)<=ALU_NOP; end if; else -- Software Interrupt pe_inst(27 downto 24)<=SWI; pe_inst(20 downto 16)<=ALU_NOP; end if; when others => pe_inst(27 downto 24)<=UNRECOGNIZED; pe_inst(20 downto 16)<=ALU_NOP; end case; ---------- CHOSING OPERANDS & DETECTOMG REGISTER INTERLOCKING ------------- if eA='1' then if busA=w_destiny and w_nro='0' and mcontrol='0' then temp:=1; end if; if busA=w_wbReg and w_wbr='1' and mcontrol='0' then temp:=1; end if; if busA=m_destiny and m_nro='0' and mcontrol='0' then temp:=2; end if; if busA=m_wbReg and m_wbr='1' and mcontrol='0' then temp:=2; end if; if busA=e_destiny and e_nro='0' and mcontrol='0' then temp:=3; end if; if busA=e_wbReg and e_wbr='1' and mcontrol='0' then temp:=3; end if; case busA is when Reg0 => pbA<=R0; when Reg1 => pbA<=R1; when Reg2 => pbA<=R2; when Reg3 => pbA<=R3; when Reg4 => pbA<=R4; when Reg5 => pbA<=R5; when Reg6 => pbA<=R6; when Reg7 => pbA<=R7; when Reg8 => pbA<=R8; if mode=FIQ then pbA<=R8_fiq; end if; when Reg9 => pbA<=R9; if mode=FIQ then pbA<=R9_fiq; end if; when Reg10 => pbA<=R10; if mode=FIQ then pbA<=R10_fiq; end if; when Reg11 => pbA<=R11; if mode=FIQ then pbA<=R11_fiq; end if; when Reg12 => pbA<=R12; if mode=FIQ then pbA<=R12_fiq; end if; when Reg13 => pbA<=R13; if mode=FIQ then pbA<=R13_fiq; elsif mode=IRQ then pbA<=R13_irq; elsif mode=SUPERVISOR then pbA<=R13_svc; elsif mode=ABORT then pbA<=R13_abt; elsif mode=UND then pbA<=R13_und; end if; when Reg14 => pbA<=R14; if mode=FIQ then pbA<=R14_fiq; elsif mode=IRQ then pbA<=R14_irq; elsif mode=SUPERVISOR then pbA<=R14_svc; elsif mode=ABORT then pbA<=R14_abt; elsif mode=UND then pbA<=R14_und; end if; when others => pbA<=PCplus4; end case; end if; if eB='1' then if busB=w_destiny and w_nro='0' and mcontrol='0' then temp:=1; end if; if busB=w_wbReg and w_wbr='1' and mcontrol='0' then temp:=1; end if; if busB=m_destiny and m_nro='0' and mcontrol='0' then temp:=2; end if; if busB=m_wbReg and m_wbr='1' and mcontrol='0' then temp:=2; end if; if busB=e_destiny and e_nro='0' and mcontrol='0' then temp:=3; end if; if busB=e_wbReg and e_wbr='1' and mcontrol='0' then temp:=3; end if; case busB is when Reg0 => pbB<=R0; when Reg1 => pbB<=R1; when Reg2 => pbB<=R2; when Reg3 => pbB<=R3; when Reg4 => pbB<=R4; when Reg5 => pbB<=R5; when Reg6 => pbB<=R6; when Reg7 => pbB<=R7; when Reg8 => pbB<=R8; if mode=FIQ then pbB<=R8_fiq; end if; when Reg9 => pbB<=R9; if mode=FIQ then pbB<=R9_fiq; end if; when Reg10 => pbB<=R10; if mode=FIQ then pbB<=R10_fiq; end if; when Reg11 => pbB<=R11; if mode=FIQ then pbB<=R11_fiq; end if; when Reg12 => pbB<=R12; if mode=FIQ then pbB<=R12_fiq; end if; when Reg13 => pbB<=R13; if mode=FIQ then pbB<=R13_fiq; elsif mode=IRQ then pbB<=R13_irq; elsif mode=SUPERVISOR then pbB<=R13_svc; elsif mode=ABORT then pbB<=R13_abt; elsif mode=UND then pbB<=R13_und; end if; when Reg14 => pbB<=R14; if mode=FIQ then pbB<=R14_fiq; elsif mode=IRQ then pbB<=R14_irq; elsif mode=SUPERVISOR then pbB<=R14_svc; elsif mode=ABORT then pbB<=R14_abt; elsif mode=UND then pbB<=R14_und; end if; when others => pbB<=PCplus4; end case; end if; if eC='1' then if busC=w_destiny and w_nro='0' and mcontrol='0' then temp:=1; end if; if busC=w_wbReg and w_wbr='1' and mcontrol='0' then temp:=1; end if; if busC=m_destiny and m_nro='0' and mcontrol='0' then temp:=2; end if; if busC=m_wbReg and m_wbr='1' and mcontrol='0' then temp:=2; end if; if busC=e_destiny and e_nro='0' and mcontrol='0' then temp:=3; end if; if busC=e_wbReg and e_wbr='1' and mcontrol='0' then temp:=3; end if; case busC is when Reg0 => pbC<=R0; when Reg1 => pbC<=R1; when Reg2 => pbC<=R2; when Reg3 => pbC<=R3; when Reg4 => pbC<=R4; when Reg5 => pbC<=R5; when Reg6 => pbC<=R6; when Reg7 => pbC<=R7; when Reg8 => pbC<=R8; if mode=FIQ then pbC<=R8_fiq; end if; when Reg9 => pbC<=R9; if mode=FIQ then pbC<=R9_fiq; end if; when Reg10 => pbC<=R10; if mode=FIQ then pbC<=R10_fiq; end if; when Reg11 => pbC<=R11; if mode=FIQ then pbC<=R11_fiq; end if; when Reg12 => pbC<=R12; if mode=FIQ then pbC<=R12_fiq; end if; when Reg13 => pbC<=R13; if mode=FIQ then pbC<=R13_fiq; elsif mode=IRQ then pbC<=R13_irq; elsif mode=SUPERVISOR then pbC<=R13_svc; elsif mode=ABORT then pbC<=R13_abt; elsif mode=UND then pbC<=R13_und; end if; when Reg14 => pbC<=R14; if mode=FIQ then pbC<=R14_fiq; elsif mode=IRQ then pbC<=R14_irq; elsif mode=SUPERVISOR then pbC<=R14_svc; elsif mode=ABORT then pbC<=R14_abt; elsif mode=UND then pbC<=R14_und; end if; when others => pbC<=PCplus4; end case; if shift_reg='1' then pbC(8)<='1'; end if; end if; --------- MCONTROL DISABLED WHEN NOP INSTRUCTION ------------------------- if stop_execute='1' and mcontrol='1' then pmcontrol<=mcontrol; mult_long<='1'; end if; --------- CHOOSING NUMBER OF WAIT STATES --------------------------------- if noper='0' then ws<=temp; end if; --------- RESETTING PIPELINE --------------------------------------------- if reset_decode='1' and mcontrol='0' then pe_inst(27 downto 24)<=NOP; end if; --------- STOPPING PIPELINE --------------------------------------------- if stop_decode='1' then pe_inst(27 downto 24)<=NOP; end if; if stop_execute='1' then pbA<=ba; pbB<=bB; pbC<=bC; pe_inst<=e_inst; end if; --------- INCLUDING TEST VECTOR FOR SIMULATION -------------------------- DEBUG_BUSA<=busA; DEBUG_BUSB<=busB; DEBUG_BUSC<=busC; DEBUG_EA<=EA; DEBUG_EB<=EB; DEBUG_EC<=EC; -------------------------------------------------------------------------- end process; ----------------------------------------------------------------------------- -- Instruction Execute Stage ----------------------------------------------------------------------------- A<=bA; B<=bB; Cin<=CPSR(29); Vin<=CPSR(28); execute_stage : process(e_inst,bA,bC,m_data,m_inst,Vout,stop_execute,bitI,bitF, mode,CPSR,SPSR_fiq,SPSR_irq,SPSR_svc,SPSR_und,Cout, SPSR_abt,Result,m_address,m_temp_reg,exc_report, exception,AUXBUS,mcontrol) variable cond_field: std_logic_vector (3 downto 0); variable N,Z,Cf,V: std_logic; variable execute: std_logic; variable resetexecute: std_logic; begin N:=CPSR(31); Z:=CPSR(30); Cf:=CPSR(29); V:=CPSR(28); cond_field:=e_inst (31 downto 28); e_nro<='0'; e_destiny<=(others=>'0'); e_wbr<='0'; e_wbReg<=(others=>'0'); save_link<='0'; reset_fetch<='0'; reset_decode<='0'; resetexecute:='0'; jump<='0'; jump_address<=(others=>'0'); und_notify<='0'; swi_notify<='0'; mult_ctrl<='0'; alu_op<=ALU_NOP; shift_type<="00"; pCPSR<=CPSR; pSPSR_fiq<=SPSR_fiq; pSPSR_irq<=SPSR_irq; pSPSR_svc<=SPSR_svc; pSPSR_und<=SPSR_und; pSPSR_abt<=SPSR_abt; pm_data<=m_data; pm_address<=m_address; pm_temp_reg<=m_temp_reg; C<=bC; IF e_inst (27 downto 24)=LDR_STR and e_inst(1)='1' THEN C(4 DOWNTO 0)<=AUXBUS; C(31 DOWNTO 5)<=(OTHERS=>'0'); END IF; ------- Decoding condition codes ------------------------------------ execute:='0'; case cond_field is when EQ => if Z='1' then execute:='1'; end if; when NE => if Z='0' then execute:='1'; end if; when CS => if Cf='1' then execute:='1'; end if; when CC => if Cf='0' then execute:='1'; end if; when MI => if N='1' then execute:='1'; end if; when PL => if N='0' then execute:='1'; end if; when VS => if V='1' then execute:='1'; end if; when VC => if V='0' then execute:='1'; end if; when HI => if Cf='1' and Z='0' then execute:='1'; end if; when LS => if Cf='0' and Z='1' then execute:='1'; end if; when GE => if ((N='1' and V='1') or (N='0' and V='0')) then execute:='1'; end if; when LT => if ((N='1' and V='0') or (N='0' and V='1')) then execute:='1'; end if; when GT => if (Z='0' and ((N='1' and V='1')or(N='0' and V='0'))) then execute:='1'; end if; when LE => if (Z='1' and ((N='1' and V='0')or(N='0' and V='1'))) then execute:='1'; end if; when AL => execute:='1'; when others => execute:='0'; end case; if exc_report='1' and exception=ABORT_EXC then resetexecute:='1'; end if; if resetexecute='1' or stop_execute='1' then execute:='0'; end if; --------------------------------------------------------------------- ----------------- ONLY FOR SIMULATION PURPUSES ---------------------- DEBUG_EX<=EXECUTE; --------------------------------------------------------------------- pm_inst<=e_inst; alu_op<=e_inst(20 downto 16); e_destiny<=e_inst(15 downto 12); case e_inst (27 downto 24) is when DATA_PSR => if e_inst(11)='0' and e_inst(10)='0' and execute='1' then shift_type<=e_inst(23 downto 22); pm_data<=Result; if e_inst(20 downto 18)="010" then e_nro<='1'; end if; if e_inst(21)='1' then pCPSR(31)<=Result(31); pCPSR(30)<='0'; if result=conv_std_logic_vector(0,32) then pCPSR(30)<='1'; end if; PCPSR(29)<=Cout; pCPSR(28)<=Vout; end if; if e_inst(15 downto 12)=Reg15 then jump<='1'; jump_address<=Result; reset_fetch<='1'; reset_decode<='1'; if e_inst(21)='1' then case mode is when FIQ => pCPSR<=SPSR_fiq; when IRQ => pCPSR<=SPSR_irq; when UND => pCPSR<=SPSR_und; when ABORT => pCPSR<=SPSR_abt; when SUPERVISOR => pCPSR<=SPSR_svc; when OTHERS => pCPSR<=CPSR; end case; end if; end if; elsif e_inst(11)='1' and execute='1' then pm_data<=CPSR; if e_inst(9)='1' then case mode is when FIQ => pm_data<=SPSR_fiq; when IRQ => pm_data<=SPSR_irq; when SUPERVISOR => pm_data<=SPSR_svc; when ABORT => pm_data<=SPSR_ABT; when UND => pm_data<=SPSR_und; when others => pm_data<=CPSR; end case; end if; elsif e_inst(10)='1' and execute ='1' then e_nro<='1'; if e_inst(7 downto 4)="0001" or e_inst(7 downto 4)="1001" then if e_inst(9)='0' then pCPSR(7 downto 0)<=Result(7 downto 0); elsif e_inst(9)='1' then case mode is when FIQ => pSPSR_fiq(7 downto 0)<=Result(7 downto 0); when IRQ => pSPSR_irq(7 downto 0)<=Result(7 downto 0); when SUPERVISOR => pSPSR_svc(7 downto 0)<=Result(7 downto 0); when ABORT => pSPSR_ABT(7 downto 0)<=Result(7 downto 0); when UND => pSPSR_und(7 downto 0)<=Result(7 downto 0); when others => pCPSR<=CPSR; end case; end if; end if; if e_inst(7 downto 4)="1000" or e_inst(7 downto 4)="1001" then if e_inst(9)='0' then pCPSR(31 downto 24)<=Result(31 downto 24); elsif e_inst(9)='1' then case mode is when FIQ => pSPSR_fiq(31 downto 24)<=Result(31 downto 24); when IRQ => pSPSR_irq(31 downto 24)<=Result(31 downto 24); when SUPERVISOR => pSPSR_svc(31 downto 24)<=Result(31 downto 24); when ABORT => pSPSR_ABT(31 downto 24)<=Result(31 downto 24); when UND => pSPSR_und(31 downto 24)<=Result(31 downto 24); when others => pCPSR<=CPSR; end case; end if; end if; if mode=USER then pCPSR(27 downto 0)<=CPSR(27 downto 0); end if; end if; when MULTIPLY => pm_data<=Result; if e_inst(22)='1' then e_destiny<=e_inst(11 downto 8); pm_inst(15 downto 12)<=e_inst(11 downto 8); end if; mult_ctrl<=e_inst(22); if e_inst(21)='1' and execute='1' then pCPSR(31)<=Result(31); pCPSR(30)<='0'; if result=conv_std_logic_vector(0,32) then pCPSR(30)<='1'; end if; pCPSR(29)<='0'; -- A MEANINGLESS VALUE pCPSR(28)<=Vout; end if; when LDR_STR => shift_type<=e_inst(23 downto 22); if e_inst(6)='1' or e_inst(21)='0' then -- bit W='1' o P='0' e_wbr<='1'; e_wbReg<=e_inst(11 downto 8); pm_temp_reg<=Result; end if; if e_inst(21)='1' then -- bit P pm_address<=Result; elsif e_inst(21)='0' then pm_address<=bA; end if; if e_inst(5)='0' then -- bit L (store) pm_data<=bC; e_nro<='1'; end if; when HALFWORD => shift_type<=e_inst(23 downto 22); if e_inst(6)='1' or e_inst(21)='0' then -- bit W e_wbr<='1'; e_wbReg<=e_inst(11 downto 8); pm_temp_reg<=Result; end if; if e_inst(21)='1' then -- bit P pm_address<=Result; elsif e_inst(21)='0' then pm_address<=bA; end if; if e_inst(5)='0' then -- bit L (store) pm_data<=bC; e_nro<='1'; end if; when SWP => shift_type<=e_inst(23 downto 22); pm_address<=Result; pm_data<=bC; when BRANCH => if execute='1' then e_nro<='1'; reset_fetch<='1'; reset_decode<='1'; jump<='1'; jump_address<=Result; save_link<='0'; if e_inst(23)='1' then save_link<='1'; end if; end if; when UNRECOGNIZED => e_nro<='1'; und_notify<='1'; when SWI=> e_nro<='1'; if execute='1' then swi_notify<='1'; end if; when UNDEFINED => e_nro<='1'; und_notify<='1'; when CPD => e_nro<='1'; -- if ARM executes a coprocesor und_notify<='1'; -- instruction, and no coprocessor when LDC_STC => e_nro<='1'; -- responds,an undefined instruction und_notify<='1'; -- exception occurs. when MRC_MCR => e_nro<='1'; -- The undefined instruction trap und_notify<='1'; -- may be used for software emulation -- when NOP => e_nro<='1'; -- of the copro, in this system, that when others => e_nro<='1'; -- does not have physican coprocessor. end case; ------ EXECUTE CONDITION IS FALSE----------------------------------- if execute='0' then pm_inst(27 downto 24)<=NOP; e_nro<='1'; end if; ------ STOPING PIPELINE -------------------------------------------- if stop_execute='1' then pCPSR<=CPSR; pm_inst<=m_inst; pm_data<=m_data; pm_address<=m_address; pm_temp_reg<=m_temp_reg; end if; ------ RESETTING PIPELINE ------------------------------------------- if resetexecute='1' then pm_inst(27 downto 24)<=NOP; end if; ----- EXCEPTIONS CONTROL ------------------------------------------- if exc_report='1' then if exception=SWI_EXC then reset_fetch<='1'; reset_decode<='1'; jump<='1'; jump_address<=SWI_VECTOR; pSPSR_svc<=CPSR; pCPSR(4 downto 0)<=SUPERVISOR; pCPSR(7)<='1'; pCPSR(6)<=CPSR(6); elsif exception=UND_EXC then reset_fetch<='1'; reset_decode<='1'; jump<='1'; jump_address<=UND_VECTOR; pSPSR_und<=CPSR; pCPSR(4 downto 0)<=UND; pCPSR(7)<='1'; pCPSR(6)<=CPSR(6); elsif exception=IRQ_EXC and bitI='0' then reset_fetch<='1'; reset_decode<=not mcontrol; jump<='1'; jump_address<=IRQ_VECTOR; pSPSR_irq<=CPSR; pCPSR(4 downto 0)<=IRQ; pCPSR(7)<='1'; pCPSR(6)<=CPSR(6); elsif exception=FIQ_EXC and bitF='0' then reset_fetch<='1'; reset_decode<=not mcontrol; jump<='1'; jump_address<=FIQ_VECTOR; pSPSR_fiq<=CPSR; pCPSR(4 downto 0)<=FIQ; pCPSR(7)<='1'; pCPSR(6)<='1'; elsif exception=ABORT_EXC then reset_fetch<='1'; reset_decode<='1'; -- resetexecute:='1'; jump<='1'; jump_address<=ABORT_VECTOR; pSPSR_abt<=CPSR; pCPSR<=CPSR; pCPSR(4 downto 0)<=ABORT; pCPSR(7)<='1'; pCPSR(6)<=CPSR(6); end if; end if; reset_execute<=resetexecute; end process; ----------------------------------------------------------------------------- -- Instruction Memory Stage ----------------------------------------------------------------------------- d_address<=m_address; memory_stage : process(m_inst,m_data,m_temp_reg,w_temp_reg,m_address,RData, cuenta,wait_state,nABORT, mode,w_inst,w_data) variable offset: std_logic_vector (1 downto 0); variable half_case: std_logic_vector (2 downto 0); variable mload, mstore: std_logic; variable meminst: std_logic; variable nopriv: std_logic; variable act_abort: std_logic; begin m_nro<='0'; swp_flag<='0'; pw_inst<=m_inst; pw_data<=m_data; pw_temp_reg<=w_temp_reg; m_wbr<='0'; m_wbReg<=(others=>'0'); Wdata<=(others=>'0'); r_enable<='0'; w_enable<='0'; size<="00"; act_abort:='0'; mload:='0'; mstore:='0'; nopriv:='0'; meminst:='0'; offset:=m_address(1 downto 0); half_case(2 downto 1):=m_inst(4 downto 3); half_case(0):=m_inst(5); m_destiny<=m_inst(15 downto 12); case m_inst (27 downto 24) is when DATA_PSR => if m_inst(20 downto 18)="010" or m_inst(10)='1'then m_nro<='1'; end if; when MULTIPLY => m_nro<='0'; -- when BRANCH => m_nro<='1'; -- when UNDEFINED => m_nro<='1'; when LDR_STR => if not(cuenta=wait_state) then meminst:='1'; end if; if nABORT='0' then pw_inst(0)<='1'; else pw_inst(0)<='0'; end if; pw_data<=(others=>'0'); if m_inst(5)='0' then -- STORE m_nro<='1'; w_enable<='1'; r_enable<='0'; mstore:='1'; elsif m_inst(5)='1' then -- LOAD r_enable<='1'; w_enable<='0'; mload:='1'; end if; size<="11"; if m_inst(7)='1' then size<="01"; end if; if m_inst(6)='1' or m_inst(21)='0' then -- bit W or not P m_wbr<='1'; m_wbReg<=m_inst(11 downto 8); pw_temp_reg<=m_temp_reg; end if; if m_inst(6)='1' and m_inst(21)='0' then nopriv:='1'; end if; when HALFWORD => if not(cuenta=wait_state) then meminst:='1'; end if; if nABORT='0' then pw_inst(0)<='1'; else pw_inst(0)<='0'; end if; pw_data<=(others=>'0'); if m_inst(6)='1' or m_inst(21)='0' then -- bit W or not P m_wbr<='1'; m_wbReg<=m_inst(11 downto 8); pw_temp_reg<=m_temp_reg; end if; if m_inst(6)='1' and m_inst(21)='0' then nopriv:='1'; end if; if m_inst(5)='0' then m_nro<='1'; w_enable<='1'; mstore:='1'; elsif m_inst(5)='1' then mload:='1'; r_enable<='1'; end if; size<="10"; if m_inst(3)='0' then size<="01"; end if; when SWP => if not(cuenta=wait_state) then meminst:='1'; end if; pw_data<=(others=>'0'); if nABORT='0' then pw_inst(0)<='1'; act_abort:='1'; else pw_inst(0)<='0'; end if; if m_inst(5)='0' then -- STORE m_nro<='1'; w_enable<='1'; r_enable<='0'; mstore:='1'; elsif m_inst(5)='1' then -- LOAD swp_flag<='1'; r_enable<='1'; w_enable<='0'; mload:='1'; end if; size<="11"; if m_inst(7)='1' then size<="01"; end if; -- when SWI => m_nro<='1'; -- when UNRECOGNIZED => m_nro<='1'; -- when CPD => m_nro<='1'; -- when LDC_STC => m_nro<='1'; -- when MRC_MCR => m_nro<='1'; -- when NOP => m_nro<='1'; when others => m_nro<='1'; end case; -- Privileged Access to Memory privileged<='1'; if mode=USER or nopriv='1' then privileged<='0'; end if; if mstore='1' then Wdata<=m_data; if m_inst(7)='1' or m_inst(3)='1' then WData(15 downto 8)<=m_data(7 downto 0); WData(23 downto 16)<=m_data(7 downto 0); WData(31 downto 24)<=m_data(7 downto 0); if m_inst(3)='1' then WData(15 downto 8)<=m_data(15 downto 8); WData(31 downto 24)<=m_data(15 downto 8); end if; end if; end if; if mload='1' then pw_data<=(others=>'0'); if m_inst(7)='1' or m_inst(4 downto 3)="10" then -- byte load if offset="00" then pw_data(7 downto 0)<=RData(7 downto 0); if m_inst(4)='1' then pw_data(31 downto 8)<=(others=>RData(7)); end if; elsif offset="01" then pw_data(7 downto 0)<=RData(15 downto 8); if m_inst(4)='1' then pw_data(31 downto 8)<=(others=>RData(15)); end if; elsif offset="10" then pw_data(7 downto 0)<=RData(23 downto 16); if m_inst(4)='1' then pw_data(31 downto 8)<=(others=>RData(23)); end if; elsif offset="11" then pw_data(7 downto 0)<=RData(31 downto 24); if m_inst(4)='1' then pw_data(31 downto 8)<=(others=>RData(31)); end if; end if; elsif m_inst(7)='0' and m_inst(4 downto 3)="00" then -- (Rotated) Word Load case offset is when "01" => pw_data(7 downto 0)<=RData(15 downto 8); pw_data(15 downto 8)<=RData(23 downto 16); pw_data(23 downto 16)<=RData(31 downto 24); pw_data(31 downto 24)<=RData(7 downto 0); when "10" => pw_data(7 downto 0)<=RData(23 downto 16); pw_data(15 downto 8)<=RData(31 downto 24); pw_data(23 downto 16)<=RData(7 downto 0); pw_data(31 downto 24)<=RData(15 downto 8); when "11" => pw_data(7 downto 0)<=RData(31 downto 24); pw_data(15 downto 8)<=RData(7 downto 0); pw_data(23 downto 16)<=RData(15 downto 8); pw_data(31 downto 24)<=RData(23 downto 16); when others => pw_data<=RData; end case; elsif m_inst(3)='1' then pw_data(15 downto 0)<=RData(15 downto 0); if m_inst(4)='1' then pw_data(31 downto 16)<=(others=>RData(15)); end if; if offset(1)='1' then pw_data(15 downto 0)<=RData(31 downto 16); if m_inst(4)='1' then pw_data(31 downto 16)<=(others=>RData(31)); end if; end if; end if; end if; pcuenta<="00"; if meminst='1' then pcuenta<=unsigned(cuenta)+1; pw_inst(27 downto 24)<=NOP; pw_inst<=w_inst; pw_data<=w_data; pw_temp_reg<=w_temp_reg; end if; if cuenta=wait_state then meminst:='0'; pcuenta<="00"; end if; if act_abort='1' then pw_inst(0)<='1'; end if; mem_inst<=meminst; end process; ----------------------------------------------------------------------------- -- Instruction Write Stage ----------------------------------------------------------------------------- w_destiny<=w_inst(15 downto 12); w_wbReg<=w_inst(11 downto 8); write_stage : process(w_inst, w_data, save_link, mode, w_destiny,bitI, R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,R13,R14,R15,bitF, R8_fiq,R9_fiq,R10_fiq,R11_fiq,R12_fiq,R13_fiq,R14_fiq, R13_svc,R14_svc,R13_abt,R14_abt,R13_irq,R14_irq,R13_und, R14_und,w_temp_reg,w_wbReg,exc_report,exception, PCsub4, mcontrol, PCplus4, WS, mem_inst, swp_flag) variable wnro, wwbr: std_logic; variable swp_abort: std_logic; begin pR0<=R0; pR1<=R1; pR2<=R2; pR3<=R3; pR4<=R4; pR5<=R5; pR6<=R6; pR7<=R7; pR8<=R8; pR9<=R9; pR10<=R10; pR11<=R11; pR12<=R12; pR13<=R13; pR14<=R14; pR8_fiq<=R8_fiq; pR9_fiq<=R9_fiq; pR10_fiq<=R10_fiq; pR11_fiq<=R11_fiq; pR12_fiq<=R12_fiq; pR13_fiq<=R13_fiq; pR14_fiq<=R14_fiq; pR13_svc<=R13_svc; pR14_svc<=R14_svc; pR13_abt<=R13_abt; pR14_abt<=R14_abt; pR13_irq<=R13_irq; pR14_irq<=R14_irq; pR13_und<=R13_und; pR14_und<=R14_und; wnro:='0'; wwbr:='0'; swp_abort:='0'; case w_inst(27 downto 24) is when DATA_PSR => if w_inst(20 downto 18)="010" or w_inst(10)='1' then wnro:='1'; end if; when MULTIPLY => wwbr:='0'; when BRANCH => wnro:='1'; when UNDEFINED => wnro:='1'; when LDR_STR => if w_inst(5)='0' then wnro:='1'; end if; if w_inst(6)='1' or w_inst(21)='0' then wwbr:='1'; end if; if w_inst(0)='1' then wwbr:='0'; wnro:='1'; end if; when HALFWORD => if w_inst(5)='0' then wnro:='1'; end if; if w_inst(6)='1' or w_inst(21)='0' then wwbr:='1'; end if; if w_inst(0)='1' then wwbr:='0'; wnro:='1'; end if; when SWP => if w_inst(5)='0' then wnro:='1'; end if; if w_inst(0)='1' or swp_abort='1' then wwbr:='0'; wnro:='1'; end if; -- when SWI => wnro:='1'; -- when UNRECOGNIZED => wnro:='1'; -- when CPD => wnro:='1'; -- when LDC_STC => wnro:='1'; -- when MRC_MCR => wnro:='1'; -- when NOP => wnro:='1'; when others => wnro:='1'; end case; if wnro='0' and mem_inst='0' then if w_destiny=Reg0 then pR0<=w_data; elsif w_destiny=Reg1 then pR1<=w_data; elsif w_destiny=Reg2 then pR2<=w_data; elsif w_destiny=Reg3 then pR3<=w_data; elsif w_destiny=Reg4 then pR4<=w_data; elsif w_destiny=Reg5 then pR5<=w_data; elsif w_destiny=Reg6 then pR6<=w_data; elsif w_destiny=Reg7 then pR7<=w_data; elsif w_destiny=Reg8 then if mode=FIQ then pR8_fiq<=w_data; else pR8<=w_data; end if; elsif w_destiny=Reg9 then if mode=FIQ then pR9_fiq<=w_data; else pR9<=w_data; end if; elsif w_destiny=Reg10 then if mode=FIQ then pR10_fiq<=w_data; else pR10<=w_data; end if; elsif w_destiny=Reg11 then if mode=FIQ then pR11_fiq<=w_data; else pR11<=w_data; end if; elsif w_destiny=Reg12 then if mode=FIQ then pR12_fiq<=w_data; else pR12<=w_data; end if; elsif w_destiny=Reg13 then if mode=FIQ then pR13_fiq<=w_data; elsif mode=IRQ then pR13_irq<=w_data; elsif mode=SUPERVISOR then pR13_svc<=w_data; elsif mode=ABORT then pR13_abt<=w_data; elsif mode=UND then pR13_und<=w_data; else pR13<=w_data; end if; elsif w_destiny=Reg14 then if mode=FIQ then pR14_fiq<=w_data; elsif mode=IRQ then pR14_irq<=w_data; elsif mode=SUPERVISOR then pR14_svc<=w_data; elsif mode=ABORT then pR14_abt<=w_data; elsif mode=UND then pR14_und<=w_data; else pR14<=w_data; end if; end if; end if; if wwbr='1' and mem_inst='0' then if w_wbReg=Reg0 then pR0<=w_temp_reg; elsif w_wbReg=Reg1 then pR1<=w_temp_reg; elsif w_wbReg=Reg2 then pR2<=w_temp_reg; elsif w_wbReg=Reg3 then pR3<=w_temp_reg; elsif w_wbReg=Reg4 then pR4<=w_temp_reg; elsif w_wbReg=Reg5 then pR5<=w_temp_reg; elsif w_wbReg=Reg6 then pR6<=w_temp_reg; elsif w_wbReg=Reg7 then pR7<=w_temp_reg; elsif w_wbReg=Reg8 then if mode=FIQ then pR8_fiq<=w_temp_reg; else pR8<=w_temp_reg; end if; elsif w_wbReg=Reg9 then if mode=FIQ then pR9_fiq<=w_temp_reg; else pR9<=w_temp_reg; end if; elsif w_wbReg=Reg10 then if mode=FIQ then pR10_fiq<=w_temp_reg; else pR10<=w_temp_reg; end if; elsif w_wbReg=Reg11 then if mode=FIQ then pR11_fiq<=w_temp_reg; else pR11<=w_temp_reg; end if; elsif w_wbReg=Reg12 then if mode=FIQ then pR12_fiq<=w_temp_reg; else pR12<=w_temp_reg; end if; elsif w_wbReg=Reg13 then if mode=FIQ then pR13_fiq<=w_temp_reg; elsif mode=IRQ then pR13_irq<=w_temp_reg; elsif mode=SUPERVISOR then pR13_svc<=w_temp_reg; elsif mode=ABORT then pR13_abt<=w_temp_reg; elsif mode=UND then pR13_und<=w_temp_reg; else pR13<=w_temp_reg; end if; elsif w_wbReg=Reg14 then if mode=FIQ then pR14_fiq<=w_temp_reg; elsif mode=IRQ then pR14_irq<=w_temp_reg; elsif mode=SUPERVISOR then pR14_svc<=w_temp_reg; elsif mode=ABORT then pR14_abt<=w_temp_reg; elsif mode=UND then pR14_und<=w_temp_reg; else pR14<=w_temp_reg; end if; end if; end if; if save_link='1' then if mode=FIQ then pR14_fiq<=PCsub4; elsif mode=IRQ then pR14_irq<=PCsub4; elsif mode=SUPERVISOR then pR14_svc<=PCsub4; elsif mode=ABORT then pR14_abt<=PCsub4; elsif mode=UND then pR14_und<=PCsub4; else pR14<=PCsub4; end if; end if; if exc_report='1' then if exception=FIQ_EXC and bitF='0' then pR14_fiq<=R15; if mcontrol='1' then pR14_fiq<=PCplus4; end if; elsif exception=IRQ_EXC and bitI='0' then pR14_irq<=R15; if mcontrol='1' then pR14_irq<=PCplus4; end if; elsif exception=UND_EXC then pR14_und<=R15; elsif exception=ABORT_EXC then ---- PENSAR swp_abort:='1'; pR14_abt<=PCsub4; if mcontrol='1' or ws > 0 or swp_flag='1' then pR14_abt<=R15; end if; elsif exception=SWI_EXC then pR14_svc<=PCsub4; end if; end if; w_nro<=wnro; w_wbr<=wwbr; end process; ----------------------------------------------------------------------------- -- Syncronize Process ----------------------------------------------------------------------------- synch: process (clk,resetz) begin if (resetz='0') then -- REGISTER BANCK R15<=(others=>'0'); R0<=(others=>'0');R1<=(others=>'0');R2<=(others=>'0');R3<=(others=>'0'); R4<=(others=>'0');R5<=(others=>'0');R6<=(others=>'0');R7<=(others=>'0'); R8<=(others=>'0');R9<=(others=>'0');R10<=(others=>'0');R11<=(others=>'0'); R12<=(others=>'0');R13<=(others=>'0');R14<=(others=>'0'); R8_fiq<=(others=>'0'); R9_fiq<=(others=>'0'); R10_fiq<=(others=>'0'); R11_fiq<=(others=>'0'); R12_fiq<=(others=>'0'); R13_fiq<=(others=>'0'); R14_fiq<=(others=>'0'); R13_svc<=(others=>'0'); R14_svc<=(others=>'0'); R13_abt<=(others=>'0'); R14_abt<=(others=>'0'); R13_irq<=(others=>'0'); R14_irq<=(others=>'0'); R13_und<=(others=>'0'); R14_und<=(others=>'0'); CPSR<=(others=>'0'); CPSR(4 downto 0)<=SUPERVISOR; CPSR(7 downto 6)<="11"; SPSR_fiq<=(others=>'0'); SPSR_svc<=(others=>'0'); SPSR_abt<=(others=>'0'); SPSR_irq<=(others=>'0'); SPSR_und<=(others=>'0'); -- BUESES REGISTERS bA<=(others=>'0'); bB<=(others=>'0'); bC<=(others=>'0'); -- CONTROL REGISTERS AND FLIP-FLOPS mcontrol<='0'; cuenta<="00"; pipeline<=E0; -- DATA AND AUXILIAR REGISTERS m_data<=(others=>'0'); w_data<=(others=>'0'); m_address<=(others=>'0'); m_temp_reg<=(others=>'0'); w_temp_reg<=(others=>'0'); AUXBUS<=(others=>'0'); PCsub4<=(others=>'0'); -- PIPELINE CONROL REGISTERS d_inst(27 downto 0)<=(others=>'0'); d_inst(31 downto 28)<=(others=>'1'); e_inst<=(others=>'0'); e_inst(27 downto 24)<=NOP; m_inst<=(others=>'0'); m_inst(27 downto 24)<=NOP; w_inst<=(others=>'0'); w_inst(27 downto 24)<=NOP; elsif ((clk'event)and(clk='1')) then -- REGISTER BANK R0<=pR0;R1<=pR1;R2<=pR2;R3<=pR3;R4<=pR4;R5<=pR5;R6<=pR6;R7<=pR7;R8<=pR8; R9<=pR9;R10<=pR10;R11<=pR11;R12<=pR12;R13<=pR13;R14<=pR14;R15<=pR15; CPSR<=pCPSR;SPSR_fiq<=pSPSR_fiq;SPSR_svc<=pSPSR_svc;SPSR_abt<=pSPSR_abt; SPSR_irq<=pSPSR_irq;SPSR_und<=pSPSR_und;R8_fiq<=pR8_fiq;R9_fiq<=R9_fiq; R10_fiq<=pR10_fiq;R11_fiq<=pR11_fiq;R12_fiq<=pR12_fiq;R13_fiq<=pR13_fiq; R14_fiq<=pR14_fiq; R13_svc<=pR13_svc;R14_svc<=pR14_svc;R13_abt<=pR13_abt; R14_abt<=pR14_abt;R13_irq<=pR13_irq;R14_irq<=pR14_irq;R13_und<=pR13_und; R14_und<=pR14_und; -- BUSES REGISTERS bA<=pbA; bB<=pbB; bC<=pbC; -- PIPELINE'S WAIT STATE MACHINE pipeline<=p_estado; -- CONTROL BIESTABLES mcontrol<=pmcontrol; cuenta<=pcuenta; -- DATA AND AUXILIARS REGISTERS m_data<=pm_data; w_data<=pw_data; m_address<=pm_address; m_temp_reg<=pm_temp_reg; w_temp_reg<=pw_temp_reg; AUXBUS<=pAUXBUS; PCsub4<=pPCsub4; -- PIPELINE CONTROL REGISTERS d_inst<=pd_inst; e_inst<=pe_inst; m_inst<=pm_inst; w_inst<=pw_inst; end if; end process; DEBUG_0<=R0; DEBUG_1<=R1; DEBUG_2<=R2; DEBUG_3<=R3; DEBUG_4<=R4; DEBUG_5<=R5; DEBUG_6<=R6; DEBUG_7<=R7; DEBUG_8<=R8; DEBUG_9<=R9; DEBUG_10<=R10; DEBUG_11<=R11; DEBUG_12<=R12; DEBUG_13<=R13; DEBUG_14<=R14; DEBUG_15<=R15; DEBUG_8FIQ<=R8_FIQ; DEBUG_9FIQ<=R9_FIQ; DEBUG_10FIQ<=R10_FIQ; DEBUG_11FIQ<=R11_FIQ; DEBUG_12FIQ<=R12_FIQ; DEBUG_13FIQ<=R13_FIQ; DEBUG_14FIQ<=R14_FIQ; DEBUG_13IRQ<=R13_IRQ; DEBUG_14IRQ<=R14_IRQ; DEBUG_13SVC<=R13_SVC; DEBUG_14SVC<=R14_SVC; DEBUG_13ABT<=R13_ABT; DEBUG_14ABT<=R14_ABT; DEBUG_13UND<=R13_UND; DEBUG_14UND<=R14_UND; DEBUG_A<=bA; DEBUG_B<=bB; DEBUG_C<=bC; DEBUG_RESULT<=RESULT; DEBUG_CPSR<=CPSR; DEBUG_FIQ<=SPSR_FIQ; DEBUG_IRQ<=SPSR_IRQ; DEBUG_SVC<=SPSR_SVC; DEBUG_ABT<=SPSR_ABT; DEBUG_UND<=SPSR_UND; DEBUG_MCONTROL<=MCONTROL; DEBUG_WS<=WS; DEBUG_JUMP<=JUMP; DEBUG_JADDRESS<=jump_address; DEBUG_INST<=INST; DEBUG_DINST<=D_INST; DEBUG_EINST<=E_INST; DEBUG_MINST<=M_INST; DEBUG_WINST<=W_INST; DEBUG_MDATA<=M_DATA; DEBUG_WDATA<=W_DATA; DEBUG_NRO(2)<=e_nro; DEBUG_NRO(1)<=m_nro; DEBUG_NRO(0)<=w_nro; DEBUG_MADDRESS<=m_address; DEBUG_MWBR<=m_temp_reg; DEBUG_WWBR<=w_temp_reg; DEBUG_WBR(2)<=e_wbr; DEBUG_WBR(1)<=m_wbr; DEBUG_WBR(0)<=w_wbr; DEBUG_F1<=exc_happens; DEBUG_F2<=exc_report; DEBUG_F3<=exception; DEBUG_AUXBUS<=AUXBUS; end COMP; e-REdING. Biblioteca de la Escuela Superior de Ingenieros de Sevilla.


IMPLEMENTACIÓN EN VHDL DEL MICROPROCESADOR ARM9

: Jurado Carmona, Francisco Javier
: Ingeniería Telecomunicación