297 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			VHDL
		
	
	
	
	
	
			
		
		
	
	
			297 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			VHDL
		
	
	
	
	
	
 | 
						|
-- written by Robert Sanchez
 | 
						|
 | 
						|
library IEEE;
 | 
						|
use IEEE.STD_LOGIC_1164.ALL;
 | 
						|
use IEEE.NUMERIC_STD.ALL;
 | 
						|
 | 
						|
 | 
						|
entity gigatron is
 | 
						|
  Port ( 
 | 
						|
         sysclk : in std_logic;
 | 
						|
         VGA_R : out std_logic_vector(3 downto 0);
 | 
						|
         VGA_G : out std_logic_vector(3 downto 0);
 | 
						|
         VGA_B : out std_logic_vector(3 downto 0);
 | 
						|
         VGA_HS : out std_logic; 
 | 
						|
         VGA_VS : out std_logic;
 | 
						|
         
 | 
						|
         LED : out std_logic_vector(15 downto 0));
 | 
						|
end gigatron;
 | 
						|
 | 
						|
 | 
						|
--        TRUTH TABLE for A and B ALU operands (BA bit order for input)
 | 
						|
-- LD  AR 0011
 | 
						|
-- XOR AR 0110
 | 
						|
-- OR  AR 0111
 | 
						|
-- AND AR 0001
 | 
						|
-- SUB AR 1100 (using AL too, NOTE AR0 here also carry-in)
 | 
						|
--        0101 <-second side of mux
 | 
						|
-- ADD AR 0011 (using AL too)
 | 
						|
--        0101 <-second side of mux
 | 
						|
 | 
						|
 | 
						|
architecture Behavioral of gigatron is
 | 
						|
 | 
						|
component blk_mem_gen_0
 | 
						|
  PORT (
 | 
						|
    clka : IN STD_LOGIC;
 | 
						|
    ena : IN STD_LOGIC;
 | 
						|
    wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
 | 
						|
    addra : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
 | 
						|
    dina : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
 | 
						|
    douta : OUT STD_LOGIC_VECTOR(15 DOWNTO 0)
 | 
						|
  );
 | 
						|
END component;
 | 
						|
 | 
						|
component blk_mem_gen_1
 | 
						|
  PORT (
 | 
						|
    clka : IN STD_LOGIC;
 | 
						|
    ena : IN STD_LOGIC;
 | 
						|
    wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
 | 
						|
    addra : IN STD_LOGIC_VECTOR(14 DOWNTO 0);
 | 
						|
    dina : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
 | 
						|
    douta : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
 | 
						|
  );
 | 
						|
END component;
 | 
						|
 | 
						|
component clk_wiz_0
 | 
						|
    port(
 | 
						|
        clk_out1 : out std_logic;
 | 
						|
        clk_out2 : out std_logic;
 | 
						|
        clk_in1 : in std_logic
 | 
						|
    );
 | 
						|
end component;
 | 
						|
 | 
						|
 | 
						|
    signal PC : unsigned(15 downto 0) := X"0000";
 | 
						|
    signal DR : std_logic_vector(7 downto 0) := X"00";
 | 
						|
    signal IR : std_logic_vector(7 downto 0) := X"00";
 | 
						|
    
 | 
						|
    signal AC    : std_logic_vector(7 downto 0) := X"00";
 | 
						|
    signal Y     : std_logic_vector(7 downto 0) := X"00";
 | 
						|
    signal X     : std_logic_vector(7 downto 0) := X"00";
 | 
						|
    signal OUTR  : std_logic_vector(7 downto 0) := X"00";
 | 
						|
    signal INR   : std_logic_vector(7 downto 0) := X"FF";
 | 
						|
    signal XOUTR : std_logic_vector(7 downto 0) := X"00";
 | 
						|
    
 | 
						|
    signal DIN : std_logic_vector(15 downto 0);
 | 
						|
    signal DOUT : std_logic_vector(15 downto 0);
 | 
						|
    
 | 
						|
    signal RAMDIN : std_logic_vector(7 downto 0);
 | 
						|
    signal RAMDOUT : std_logic_vector(7 downto 0);
 | 
						|
    
 | 
						|
 | 
						|
    signal DBUS  : std_logic_vector(7 downto 0) := X"00";
 | 
						|
    
 | 
						|
    signal TMP : std_logic_vector(7 downto 0) := X"00";
 | 
						|
    signal MAR : std_logic_vector(15 downto 0) := "0000000000000000";
 | 
						|
    
 | 
						|
    signal RAMWE : std_logic_vector(0 downto 0) := "0";
 | 
						|
    
 | 
						|
    signal PCWE : std_logic := '0';
 | 
						|
    signal PCNEW : unsigned(15 downto 0) := X"0000";
 | 
						|
    
 | 
						|
    signal fastclk : std_logic;
 | 
						|
    signal clk : std_logic;
 | 
						|
    
 | 
						|
 | 
						|
begin
 | 
						|
 | 
						|
    ROM : blk_mem_gen_0 port map(clk, '1', "0", std_logic_vector(PC), DIN, DOUT);
 | 
						|
    RAM : blk_mem_gen_1 port map(fastclk, '1', RAMWE, MAR(14 downto 0), RAMDIN, RAMDOUT);
 | 
						|
    CLOCK : clk_wiz_0 port map(clk, fastclk, sysclk);
 | 
						|
    -- memory address process
 | 
						|
    process(DOUT, DR, X, Y)
 | 
						|
    begin
 | 
						|
            if IR(7 downto 5) = "111" then
 | 
						|
                MAR <= "00000000" & DR;
 | 
						|
            else
 | 
						|
            case (DOUT(4 downto 2)) is
 | 
						|
                when "000" =>
 | 
						|
                    MAR <= "00000000" & DR;
 | 
						|
                when "001" =>
 | 
						|
                    MAR <= "00000000" & X;
 | 
						|
                when "010" =>
 | 
						|
                    MAR <= Y & DR;
 | 
						|
                when "011" =>
 | 
						|
                    MAR <= Y & X;
 | 
						|
                when "100" =>
 | 
						|
                    MAR <= "00000000" & DR;
 | 
						|
                when "101" =>
 | 
						|
                    MAR <= "00000000" & DR;
 | 
						|
                when "110" =>
 | 
						|
                    MAR <= "00000000" & DR;
 | 
						|
                when "111" =>
 | 
						|
                    MAR <= Y & X;
 | 
						|
                when others =>
 | 
						|
            end case;
 | 
						|
            end if;
 | 
						|
    end process;
 | 
						|
    
 | 
						|
    
 | 
						|
    -- data bus value process
 | 
						|
    process(DOUT, RAMDOUT, AC, INR)
 | 
						|
    begin
 | 
						|
            case (DOUT(1 downto 0)) is
 | 
						|
                when "00" =>
 | 
						|
                    DBUS <= DOUT(15 downto 8);
 | 
						|
                when "01" =>
 | 
						|
                    DBUS <= RAMDOUT; 
 | 
						|
                when "10" => 
 | 
						|
                    DBUS <= AC;
 | 
						|
                when "11" => 
 | 
						|
                    DBUS <= INR;
 | 
						|
                when others =>
 | 
						|
            end case;
 | 
						|
    end process;
 | 
						|
 | 
						|
 | 
						|
    
 | 
						|
    -- real assignment process (write databus tmp value to destination)
 | 
						|
    process(clk)
 | 
						|
    begin
 | 
						|
        RAMDIN <= TMP;
 | 
						|
 | 
						|
        if rising_edge(clk) then
 | 
						|
        if (IR(7 downto 5) /= "111") then
 | 
						|
        case (IR(4 downto 2)) is
 | 
						|
        when "000" =>
 | 
						|
            if IR(7 downto 5) /= "110" then
 | 
						|
            AC <= TMP;
 | 
						|
            end if;
 | 
						|
        when "001" =>
 | 
						|
            if IR(7 downto 5) /= "110" then
 | 
						|
            AC <= TMP;
 | 
						|
            end if;
 | 
						|
        when "010" =>
 | 
						|
            if IR(7 downto 5) /= "110" then
 | 
						|
            AC <= TMP;
 | 
						|
            end if;
 | 
						|
        when "011" =>
 | 
						|
            if IR(7 downto 5) /= "110" then
 | 
						|
            AC <= TMP;
 | 
						|
            end if;
 | 
						|
        when "100" => --x
 | 
						|
            X <= TMP;
 | 
						|
        when "101" => --y
 | 
						|
            Y <= TMP;
 | 
						|
        when "110" => --out
 | 
						|
            if IR(7 downto 5) /= "110" then
 | 
						|
            OUTR <= TMP;
 | 
						|
            end if;
 | 
						|
        when "111" => --out
 | 
						|
            if IR(7 downto 5) /= "110" then
 | 
						|
            OUTR <= TMP;
 | 
						|
            end if;
 | 
						|
            X <= std_logic_vector(unsigned(X) + 1);
 | 
						|
        when others =>
 | 
						|
            if IR(7 downto 5) /= "110" then
 | 
						|
            AC <= TMP;
 | 
						|
            end if;
 | 
						|
        end case;
 | 
						|
        end if;
 | 
						|
        end if;
 | 
						|
    end process;
 | 
						|
 | 
						|
    -- program counter
 | 
						|
    process(clk) 
 | 
						|
    begin
 | 
						|
        if rising_edge(clk) then
 | 
						|
            if (PCWE = '1') then
 | 
						|
                PC <= PCNEW;
 | 
						|
            else
 | 
						|
                PC <= PC + 1;
 | 
						|
            end if;
 | 
						|
        end if;
 | 
						|
    end process;
 | 
						|
    
 | 
						|
    process(DOUT)
 | 
						|
    begin
 | 
						|
            RAMWE <= "0";
 | 
						|
            if (DOUT(7 downto 5) = "110") then -- STORE
 | 
						|
                RAMWE <= "1";
 | 
						|
            end if;
 | 
						|
    end process;
 | 
						|
 | 
						|
    -- select which value to write to data bus 
 | 
						|
    process(DBUS,IR) 
 | 
						|
    begin
 | 
						|
            PCWE <= '0';
 | 
						|
            
 | 
						|
            case (IR(7 downto 5)) is
 | 
						|
                when "000" =>   -- LD
 | 
						|
                    TMP <= DBUS;
 | 
						|
                when "001" =>   -- AND
 | 
						|
                    TMP <= AC and DBUS;
 | 
						|
                when "010" =>   -- OR
 | 
						|
                    TMP <= AC or DBUS;
 | 
						|
                when "011" =>   -- XOR
 | 
						|
                    TMP <= AC xor DBUS;
 | 
						|
                when "100" =>   -- ADD
 | 
						|
                    TMP <= std_logic_vector(unsigned(AC) + unsigned(DBUS));
 | 
						|
                when "101" =>   -- SUB
 | 
						|
                    TMP <= std_logic_vector(unsigned(AC) - unsigned(DBUS));
 | 
						|
                when "110" =>   -- STORE
 | 
						|
                    TMP <= DBUS; --AC; 
 | 
						|
                when "111" =>   -- JMP
 | 
						|
                    case (IR(4 downto 2)) is
 | 
						|
                        when "000" => -- far jump y, bus
 | 
						|
                            PCNEW <= unsigned(Y & DBUS);
 | 
						|
                            PCWE <= '1';
 | 
						|
                        when "001" =>
 | 
						|
                            if (signed(AC) > 0) then
 | 
						|
                                PCNEW <= PC(15 downto 8) & unsigned(DBUS);
 | 
						|
                                PCWE <= '1';
 | 
						|
                            end if;
 | 
						|
                        when "010" =>
 | 
						|
                            if (signed(AC) < 0) then
 | 
						|
                                PCNEW <= PC(15 downto 8) & unsigned(DBUS);
 | 
						|
                                PCWE <= '1';
 | 
						|
                            end if;
 | 
						|
                        when "011" =>
 | 
						|
                            if (signed(AC) /= 0) then
 | 
						|
                                PCNEW <= PC(15 downto 8) & unsigned(DBUS);
 | 
						|
                                PCWE <= '1';
 | 
						|
                            end if;
 | 
						|
                        when "100" =>
 | 
						|
                            if (signed(AC) = 0) then
 | 
						|
                                PCNEW <= PC(15 downto 8) & unsigned(DBUS);
 | 
						|
                                PCWE <= '1';
 | 
						|
                            end if;
 | 
						|
                        when "101" =>
 | 
						|
                            if (signed(AC) >= 0) then
 | 
						|
                                PCNEW <= PC(15 downto 8) & unsigned(DBUS);
 | 
						|
                                PCWE <= '1';
 | 
						|
                            end if;
 | 
						|
                        when "110" =>
 | 
						|
                            if (signed(AC) <= 0) then
 | 
						|
                                PCNEW <= PC(15 downto 8) & unsigned(DBUS);
 | 
						|
                                PCWE <= '1';
 | 
						|
                            end if;
 | 
						|
                        when "111" =>
 | 
						|
                            PCNEW <= PC(15 downto 8) & unsigned(DBUS);
 | 
						|
                            PCWE <= '1';
 | 
						|
                    when others =>
 | 
						|
                    end case;
 | 
						|
                when others =>
 | 
						|
            end case;
 | 
						|
    end process;
 | 
						|
    
 | 
						|
    process(OUTR(6))
 | 
						|
    begin
 | 
						|
        if rising_edge(OUTR(6)) then
 | 
						|
            XOUTR <= AC;
 | 
						|
        end if;
 | 
						|
    end process;
 | 
						|
    
 | 
						|
    DR <= DOUT(15 downto 8);
 | 
						|
    IR <= DOUT(7 downto 0);
 | 
						|
    VGA_R <= OUTR(1 downto 0) & "00";
 | 
						|
    VGA_G <= OUTR(3 downto 2) & "00";
 | 
						|
    VGA_B <= OUTR(5 downto 4) & "00";
 | 
						|
    VGA_HS <= OUTR(6);
 | 
						|
    VGA_VS <= OUTR(7);
 | 
						|
    LED(7 downto 0) <= XOUTR(7 downto 0);
 | 
						|
    
 | 
						|
end Behavioral;
 |