CPU部をVHDLで記述する

内部信号を適当に設けて内部モジュール同士、および内外の配線をする。

library ieee;
use ieee.std_logic_1164.all;

entity td4 is
    generic(
        NUM_BITS: natural := 4
    );
    port(
        clk   : in std_logic;
        aclr_n: in std_logic;
        inp   : in std_logic_vector(NUM_BITS-1 downto 0);
        data  : in std_logic_vector(7 downto 0);
        
        a_reg  : out std_logic_vector(NUM_BITS-1 downto 0);
        b_reg  : out std_logic_vector(NUM_BITS-1 downto 0);
        outp   : out std_logic_vector(NUM_BITS-1 downto 0);
        address: out std_logic_vector(NUM_BITS-1 downto 0)
    );
end entity;

architecture rtl of td4 is
    signal load_n      : std_logic_vector(NUM_BITS-1 downto 0);
    signal adder_reg   : std_logic_vector(NUM_BITS-1 downto 0);
    signal a_reg_inside: std_logic_vector(NUM_BITS-1 downto 0);
    signal b_reg_inside: std_logic_vector(NUM_BITS-1 downto 0);
    signal mux_adder_a : std_logic_vector(NUM_BITS-1 downto 0);
    signal cout        : std_logic;
    signal sel         : std_logic_vector(1 downto 0);
    signal c_flag_n    : std_logic;
begin

    module_registers: entity work.registers
        port map(
            clk        => clk,
            aclr_n     => aclr_n,
            sload_n    => load_n,
            from_74283 => adder_reg,
            a_reg      => a_reg_inside,
            b_reg      => b_reg_inside,
            out_reg    => outp,
            pc         => address
        );
        
    module_adder: entity work.generic_74283
        port map(
            cin  => '0',
            a    => mux_adder_a,
            b    => data(3 downto 0),
            sum  => adder_reg,
            cout => cout   
        );
        
    module_id: entity work.instruction_decoder
        port map(
            c_flag_n => c_flag_n,
            op_code  => data(7 downto 4),
            sel      => sel,
            load_n   => load_n
        );
        
    module_mux: entity work.generic_multiplexer
        port map(
            sel => sel,
            inp(0) => a_reg_inside,
            inp(1) => b_reg_inside,
            inp(2) => inp,
            strobe => '0',
            outp => mux_adder_a
        );
        
   -- 加算器のキャリーアウトはDFFに1回通してから命令デコーダーへ渡す。
    process(clk)
    begin
        if rising_edge(clk) then
            c_flag_n <= not cout;
        end if;
    end process;
    
   -- 確認のためA、Bレジスタも外へ出しておく。
    a_reg <= a_reg_inside;
    b_reg <= b_reg_inside;
    
end architecture;