Untitled

 avatar
unknown
plain_text
2 years ago
11 kB
3
Indexable

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

use work.Virgule_pkg.all;
use work.Computer_pkg.all;

entity Computer is
    port(
        clk_i        : in  std_logic;
        btn_center_i : in  std_logic;
        switches_i   : in  std_logic_vector(15 downto 0);
        leds_o       : out std_logic_vector(15 downto 0);
        uart_rx_i    : in  std_logic;
        uart_tx_o    : out std_logic;
        pmod_b1      : out std_logic;
        pmod_b2      : out std_logic;
        pmod_b3      : in  std_logic;
        pmod_b4      : out std_logic;
        pmod_c7      : out std_logic;
        pmod_c8      : out std_logic;
        pmod_c9      : out std_logic;
        pmod_c10     : out std_logic;
        pmod_c1      : out std_logic;
        pmod_c2      : out std_logic;
        pmod_c3      : in  std_logic;
        pmod_c4      : out std_logic
    );
end Computer;

architecture Structural of Computer is
    signal sync_reset    : std_logic;
    signal sync_uart_rx  : std_logic;

    signal core_valid    : std_logic;
    signal core_ready    : std_logic;
    signal core_address  : word_t;
    signal core_rdata    : word_t;
    signal core_wdata    : word_t;
    signal core_write    : std_logic_vector(3 downto 0);
    signal core_irq      : std_logic;

    alias dev_address    : byte_t is core_address(31 downto 24);

    signal mem_valid     : std_logic;
    signal mem_ready     : std_logic;
    signal mem_rdata     : word_t;

    signal io_valid      : std_logic;
    signal io_ready      : std_logic;
    signal io_rdata      : word_t;
    
    signal uart_valid    : std_logic;
    signal uart_ready    : std_logic;
    signal uart_rdata    : word_t;
    signal uart_rx_evt   : std_logic;
    signal uart_tx_evt   : std_logic;
    
    signal intc_valid    : std_logic;
    signal intc_ready    : std_logic;
    signal intc_rdata    : word_t;
    signal intc_events   : std_logic_vector(31 downto 0);
    
    signal timer_valid   : std_logic;
    signal timer_ready   : std_logic;
    signal timer_rdata   : word_t;
    signal timer_events  : std_logic;
    
    signal timer_spi_valid   : std_logic;
    signal timer_spi_ready   : std_logic;
    signal timer_spi_rdata   : word_t;
    signal timer_spi_events  : std_logic;
    
    signal spi_valid         : std_logic;
    signal spi_ready         : std_logic;
    signal spi_rdata         : word_t;
    signal spi_events        : std_logic;
    signal sync_spi_miso     : std_logic;
    
    signal timer_spi_screen_valid   : std_logic;
    signal timer_spi_screen_ready   : std_logic;
    signal timer_spi_screen_rdata   : word_t;
    signal timer_spi_screen_events  : std_logic;
    
    signal spi_screen_valid         : std_logic;
    signal spi_screen_ready         : std_logic;
    signal spi_screen_rdata         : word_t;
    signal spi_screen_events        : std_logic;
    signal sync_spi_screen_miso   : std_logic;
    
begin
    -- Concurrent statements
    core_inst : entity work.Virgule(rtl)
        port map(
            clk_i => clk_i,
            reset_i => sync_reset,
            valid_o => core_valid,
            ready_i => core_ready,
            address_o => core_address,
            write_o => core_write,
            rdata_i => core_rdata,
            wdata_o => core_wdata,
            irq_i => core_irq
        );
    mem_inst : entity work.VMemory(Behavioral)
        generic map(
            CONTENT => MEM_CONTENT
        )
        port map(
            clk_i => clk_i,
            reset_i => sync_reset,
            valid_i => mem_valid,
            ready_o => mem_ready,
            address_i => core_address(31 downto 2),
            rdata_o => mem_rdata,
            wdata_i => core_wdata,
            write_i => core_write
        );
    sync_inst : entity work.InputSynchronizer(Behavioral)
        generic map(
            WIDTH => 20
        )
        port map(
            clk_i => clk_i,
            data_i(0) => btn_center_i,
            data_i(16 downto 1) => switches_i,
            data_i(17) => uart_rx_i,
            data_i(18) => pmod_b3,
            data_i(19) => pmod_b3,
            data_o(0) => sync_reset,
            data_o(16 downto 1) => io_rdata(15 downto 0),
            data_o(17) => sync_uart_rx,
            data_o(18) => sync_spi_miso,
            data_o(19) => sync_spi_screen_miso
        );
    uart_inst : entity work.UART(Structural)
        generic map(
            CLK_FREQUENCY_HZ => CLK_FREQUENCY_HZ,
            BIT_RATE_HZ => UART_BIT_RATE_HZ
        )
        port map(
            clk_i => clk_i,
            reset_i => sync_reset,
            valid_i => uart_valid,
            ready_o => uart_ready,
            rdata_o => uart_rdata(7 downto 0),
            wdata_i => core_wdata(7 downto 0),
            write_i => core_write(0),
            rx_evt_o => uart_rx_evt,
            tx_evt_o => uart_tx_evt,
            rx_i => sync_uart_rx,
            tx_o => uart_tx_o
        );
    intc_inst : entity work.VInterruptController(Behavioral)
        port map(
            clk_i => clk_i,
            reset_i => sync_reset,
            valid_i => intc_valid,
            ready_o => intc_ready,
            address_i => core_address(2),
            rdata_o => intc_rdata,
            wdata_i => core_wdata,
            write_i => core_write,
            irq_o => core_irq,
            events_i => intc_events
        );
    timer_inst : entity work.Timer(Behavioral)
        port map(
            clk_i => clk_i,
            reset_i => sync_reset,
            valid_i => timer_valid,
            ready_o => timer_ready,
            address_i => core_address(2),
            rdata_o => timer_rdata,
            wdata_i => core_wdata,
            write_i => core_write,
            evt_o => timer_events
        );
    timer_spi_inst : entity work.Timer(Behavioral)
        port map(
            clk_i => clk_i,
            reset_i => sync_reset,
            valid_i => timer_spi_valid,
            ready_o => timer_spi_ready,
            address_i => core_address(2),
            rdata_o => timer_spi_rdata,
            wdata_i => core_wdata,
            write_i => core_write,
            evt_o => timer_spi_events
        );    
    spi_inst : entity work.SPIMaster(rtl)
        port map(
            clk_i => clk_i,
            reset_i => sync_reset,
            valid_i => spi_valid,
            ready_o => spi_ready,
            address_i => core_address(3 downto 2),
            rdata_o => spi_rdata(7 downto 0),
            wdata_i => core_wdata(7 downto 0),
            write_i => core_write(0),
            evt_o => spi_events,
            miso_i => pmod_b3,
            mosi_o => pmod_b2,
            sclk_o => pmod_b4,
            cs_n_o => pmod_b1
        );
    timer_spi_screen_inst : entity work.Timer(Behavioral)
        port map(
            clk_i => clk_i,
            reset_i => sync_reset,
            valid_i => timer_spi_screen_valid,
            ready_o => timer_spi_screen_ready,
            address_i => core_address(2),
            rdata_o => timer_spi_screen_rdata,
            wdata_i => core_wdata,
            write_i => core_write,
            evt_o => timer_spi_screen_events
        );  
    spi_screen_inst : entity work.SPIMaster(rtl)
        port map(
            clk_i => clk_i,
            reset_i => sync_reset,
            valid_i => spi_screen_valid,
            ready_o => spi_screen_ready,
            address_i => core_address(3 downto 2),
            rdata_o => spi_screen_rdata(7 downto 0),
            wdata_i => core_wdata(7 downto 0),
            write_i => core_write(0),
            evt_o => spi_screen_events,
            miso_i => pmod_c3,
            mosi_o => pmod_c2,
            sclk_o => pmod_c4,
            cs_n_o => pmod_c1
        );
    
    io_rdata(31 downto 16) <= (others => '0');
    mem_valid <= core_valid when dev_address = MEM_ADDRESS else '0';
    io_valid <= core_valid when dev_address = IO_ADDRESS else '0';
    core_rdata <= mem_rdata when dev_address = MEM_ADDRESS else
                  io_rdata when dev_address = IO_ADDRESS else
                  uart_rdata when dev_address = UART_ADDRESS else
                  intc_rdata when dev_address = INTC_ADDRESS else 
                  timer_rdata when dev_address = TIMER_ADDRESS else
                  spi_rdata when  dev_address = SPI_MASTER_ADDRESS else
                  timer_spi_rdata when dev_address = SPI_TIMER_ADDRESS else
                  spi_screen_rdata when dev_address = SPI_SCREEN_MASTER_ADDRESS else
                  timer_spi_screen_rdata when dev_address = SPI_SCREEN_TIMER_ADDRESS else
                  (others => '0');
                   
    process(clk_i, sync_reset)
    begin 
        if sync_reset = '1' then
            leds_o(15 downto 0) <= (others => '0');
            pmod_c10 <= '1';
            pmod_c9 <= '1';
            pmod_c8 <= '1';
            pmod_c7 <= '1';
        elsif rising_edge(clk_i) then
            if io_valid = '1' and core_write(1) = '1' then
                leds_o(15 downto 8) <= core_wdata(15 downto 8);
            end if;
            if io_valid = '1' and core_write(0) = '1' then
                leds_o(7 downto 0) <= core_wdata(7 downto 0);
            end if;
            if io_valid = '1' and core_write(2) = '1' then
                pmod_c10 <= core_wdata(19);
                pmod_c9 <= core_wdata(18);
                pmod_c8 <= core_wdata(17);
                pmod_c7 <= core_wdata(16);
            end if;
        end if;
    end process;
    
    core_ready <= mem_ready when dev_address = MEM_ADDRESS else core_valid;
    uart_rdata(31 downto 8) <= (others => '0');
    spi_rdata(31 downto 8) <= (others => '0');
    spi_screen_rdata(31 downto 8) <= (others => '0');
    intc_events(INTC_EVENTS_UART_RX) <= uart_rx_evt;
    intc_events(INTC_EVENTS_UART_TX) <= uart_tx_evt;
    intc_events(INTC_EVENTS_TIMER) <= timer_events;
    intc_events(INTC_EVENTS_SPI_TIMER) <= timer_spi_events;
    intc_events(INTC_EVENTS_SPI_MASTER) <= spi_events;
    intc_events(INTC_EVENTS_SPI_SCREEN_MASTER) <= spi_screen_events;
    intc_events(INTC_EVENTS_SPI_SCREEN_TIMER) <= timer_spi_screen_events;
    uart_valid <= core_valid when dev_address = UART_ADDRESS else '0';
    intc_valid <= core_valid when dev_address = INTC_ADDRESS else '0';            
    uart_ready <= uart_ready when dev_address = UART_ADDRESS else core_valid;
    
    intc_ready <= intc_ready when dev_address = INTC_ADDRESS else core_valid;
    timer_valid <= core_valid when dev_address = TIMER_ADDRESS else '0';            
    timer_ready <= timer_ready when dev_address = TIMER_ADDRESS else core_valid;
    spi_valid <= core_valid when dev_address = SPI_MASTER_ADDRESS else '0';
    spi_ready <= spi_ready when dev_address = SPI_MASTER_ADDRESS else core_valid;
    timer_spi_valid <= core_valid when dev_address = SPI_TIMER_ADDRESS else '0';
    timer_spi_ready <= timer_spi_ready when dev_address = SPI_TIMER_ADDRESS else core_valid;
    spi_screen_valid <= core_valid when dev_address = SPI_SCREEN_MASTER_ADDRESS else '0';
    spi_screen_ready <= spi_screen_ready when dev_address = SPI_SCREEN_MASTER_ADDRESS else core_valid;
    timer_spi_screen_valid <= core_valid when dev_address = SPI_SCREEN_TIMER_ADDRESS else '0';
    timer_spi_screen_ready <= timer_spi_screen_ready when dev_address = SPI_SCREEN_TIMER_ADDRESS else core_valid;
    
end Structural;