URL
https://opencores.org/ocsvn/c16/c16/trunk
Subversion Repositories c16
[/] [c16/] [trunk/] [vhdl/] [data_core.vhd] - Rev 26
Compare with Previous | Blame | View Log
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; -- Uncomment the following lines to use the declarations that are -- provided for instantiating Xilinx primitive components. --library UNISIM; --use UNISIM.VComponents.all; use work.cpu_pack.ALL; entity data_core is PORT( CLK_I : in std_logic; T2 : in std_logic; CLR : in std_logic; CE : in std_logic; -- select signals SX : in std_logic_vector( 1 downto 0); SY : in std_logic_vector( 3 downto 0); OP : in std_logic_vector( 4 downto 0); -- alu op PC : in std_logic_vector(15 downto 0); -- PC QU : in std_logic_vector( 3 downto 0); -- quick operand SA : in std_logic_vector(4 downto 0); -- select address SMQ : in std_logic; -- select MQ (H/L) -- write enable/select signal WE_RR : in std_logic; WE_LL : in std_logic; WE_SP : in SP_OP; -- data in signals IMM : in std_logic_vector(15 downto 0); -- immediate data RDAT : in std_logic_vector( 7 downto 0); -- memory/IO data -- memory control signals ADR : out std_logic_vector(15 downto 0); MQ : out std_logic_vector( 7 downto 0); Q_RR : out std_logic_vector(15 downto 0); Q_LL : out std_logic_vector(15 downto 0); Q_SP : out std_logic_vector(15 downto 0) ); end data_core; architecture Behavioral of data_core is function b8(A : std_logic) return std_logic_vector is begin return A & A & A & A & A & A & A & A; end; COMPONENT alu8 PORT( CLK_I : in std_logic; T2 : in std_logic; CE : in std_logic; CLR : in std_logic; ALU_OP : IN std_logic_vector( 4 downto 0); XX : IN std_logic_vector(15 downto 0); YY : IN std_logic_vector(15 downto 0); ZZ : OUT std_logic_vector(15 downto 0) ); END COMPONENT; COMPONENT select_yy PORT( SY : IN std_logic_vector( 3 downto 0); IMM : IN std_logic_vector(15 downto 0); QUICK : IN std_logic_vector( 3 downto 0); RDAT : IN std_logic_vector( 7 downto 0); RR : IN std_logic_vector(15 downto 0); YY : OUT std_logic_vector(15 downto 0) ); END COMPONENT; -- cpu registers -- signal RR : std_logic_vector(15 downto 0); signal LL : std_logic_vector(15 downto 0); signal SP : std_logic_vector(15 downto 0); -- internal buses -- signal XX : std_logic_vector(15 downto 0); signal YY : std_logic_vector(15 downto 0); signal ZZ : std_logic_vector(15 downto 0); signal ADR_X : std_logic_vector(15 downto 0); signal ADR_Z : std_logic_vector(15 downto 0); signal ADR_YZ : std_logic_vector(15 downto 0); signal ADR_XYZ : std_logic_vector(15 downto 0); begin alu_8: alu8 PORT MAP( CLK_I => CLK_I, T2 => T2, CE => CE, CLR => CLR, ALU_OP => OP, XX => XX, YY => YY, ZZ => ZZ ); selyy: select_yy PORT MAP( SY => SY, IMM => IMM, QUICK => QU, RDAT => RDAT, RR => RR, YY => YY ); ADR <= ADR_XYZ; MQ <= ZZ(15 downto 8) when SMQ = '1' else ZZ(7 downto 0); Q_RR <= RR; Q_LL <= LL; Q_SP <= SP; -- memory address -- sel_ax: process(SA(4 downto 3), IMM) variable SAX : std_logic_vector(4 downto 3); begin SAX := SA(4 downto 3); case SAX is when SA_43_I16 => ADR_X <= IMM; when SA_43_I8S => ADR_X <= b8(IMM(7)) & IMM(7 downto 0); when others => ADR_X <= b8(SA(3)) & b8(SA(3)); end case; end process; sel_az: process(SA(2 downto 1), LL, RR, SP) variable SAZ : std_logic_vector(2 downto 1); begin SAZ := SA(2 downto 1); case SAZ is when SA_21_0 => ADR_Z <= X"0000"; when SA_21_LL => ADR_Z <= LL; when SA_21_RR => ADR_Z <= RR; when others => ADR_Z <= SP; end case; end process; sel_ayz: process(SA(0), ADR_Z) begin ADR_YZ <= ADR_Z + (X"000" & "000" & SA(0)); end process; sel_axyz: process(ADR_X, ADR_YZ) begin ADR_XYZ <= ADR_X + ADR_YZ; end process; sel_xx: process(SX, LL, RR, SP, PC) begin case SX is when SX_LL => XX <= LL; when SX_RR => XX <= RR; when SX_SP => XX <= SP; when others => XX <= PC; end case; end process; regs: process(CLK_I) begin if (rising_edge(CLK_I)) then if (CLR = '1') then RR <= X"0000"; LL <= X"0000"; SP <= X"0000"; elsif (CE = '1' and T2 = '1') then if (WE_RR = '1') then RR <= ZZ; end if; if (WE_LL = '1') then LL <= ZZ; end if; case WE_SP is when SP_INC => SP <= ADR_YZ; when SP_LOAD => SP <= ADR_XYZ; when SP_NOP => null; end case; end if; end if; end process; end Behavioral;