OpenCores
URL https://opencores.org/ocsvn/potato/potato/trunk

Subversion Repositories potato

[/] [potato/] [trunk/] [testbenches/] [tb_soc.vhd] - Diff between revs 3 and 58

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 3 Rev 58
-- The Potato Processor - A simple processor for FPGAs
-- The Potato Processor - A simple processor for FPGAs
-- (c) Kristian Klomsten Skordal 2014 <kristian.skordal@wafflemail.net>
-- (c) Kristian Klomsten Skordal 2014 <kristian.skordal@wafflemail.net>
-- Report bugs and issues on <http://opencores.org/project,potato,bugtracker>
-- Report bugs and issues on <http://opencores.org/project,potato,bugtracker>
 
 
library ieee;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
use ieee.std_logic_textio.all;
use std.textio.all;
use std.textio.all;
 
 
use work.pp_constants.all;
use work.pp_constants.all;
use work.pp_utilities.all;
use work.pp_utilities.all;
 
 
--! @brief Testbench providing a full SoC architecture connected with a Wishbone bus.
--! @brief Testbench providing a full SoC architecture connected with a Wishbone bus.
entity tb_soc is
entity tb_soc is
        generic(
        generic(
                IMEM_SIZE : natural := 2048; --! Size of the instruction memory in bytes.
                IMEM_SIZE : natural := 4096; --! Size of the instruction memory in bytes.
                DMEM_SIZE : natural := 2048; --! Size of the data memory in bytes.
                DMEM_SIZE : natural := 4096; --! Size of the data memory in bytes.
 
                RESET_ADDRESS   : std_logic_vector := x"00000200"; --! Processor reset address
 
                IMEM_START_ADDR : std_logic_vector := x"00000100"; --! Instruction memory start address
                IMEM_FILENAME : string := "imem_testfile.hex"; --! File containing the contents of instruction memory.
                IMEM_FILENAME : string := "imem_testfile.hex"; --! File containing the contents of instruction memory.
                DMEM_FILENAME : string := "dmem_testfile.hex"  --! File containing the contents of data memory.
                DMEM_FILENAME   : string := "dmem_testfile.hex"  --! File containing the contents of data memory.
        );
        );
end entity tb_soc;
end entity tb_soc;
 
 
architecture testbench of tb_soc is
architecture testbench of tb_soc is
 
 
        -- Clock signals:
        -- Clock signals:
        signal clk : std_logic;
        signal clk : std_logic;
        constant clk_period : time := 10 ns;
        constant clk_period : time := 10 ns;
 
 
 
        signal timer_clk : std_logic;
 
        constant timer_clk_period : time := 100 ns;
 
 
        -- Reset:
        -- Reset:
        signal reset : std_logic := '1';
        signal reset : std_logic := '1';
 
 
        -- Interrupts:
        -- Interrupts:
        signal irq : std_logic_vector(7 downto 0) := (others => '0');
        signal irq : std_logic_vector(7 downto 0) := (others => '0');
 
 
        -- HTIF:
        -- HTIF:
        signal fromhost_data, tohost_data : std_logic_vector(31 downto 0);
        signal fromhost_data, tohost_data : std_logic_vector(31 downto 0);
        signal fromhost_updated : std_logic := '0';
        signal fromhost_updated : std_logic := '0';
        signal tohost_updated : std_logic;
        signal tohost_updated : std_logic;
 
 
        -- Instruction memory signals:
        -- Instruction memory signals:
        signal imem_adr_in : std_logic_vector(log2(IMEM_SIZE) - 1 downto 0);
        signal imem_adr_in : std_logic_vector(log2(IMEM_SIZE) - 1 downto 0);
        signal imem_dat_in : std_logic_vector(31 downto 0);
        signal imem_dat_in : std_logic_vector(31 downto 0);
        signal imem_dat_out : std_logic_vector(31 downto 0);
        signal imem_dat_out : std_logic_vector(31 downto 0);
        signal imem_cyc_in : std_logic;
        signal imem_cyc_in : std_logic;
        signal imem_stb_in : std_logic;
        signal imem_stb_in : std_logic;
        signal imem_sel_in : std_logic_vector(3 downto 0);
        signal imem_sel_in : std_logic_vector(3 downto 0);
        signal imem_we_in : std_logic;
        signal imem_we_in : std_logic;
        signal imem_ack_out : std_logic;
        signal imem_ack_out : std_logic;
 
 
        -- Data memory signals:
        -- Data memory signals:
        signal dmem_adr_in  : std_logic_vector(log2(DMEM_SIZE) - 1 downto 0);
        signal dmem_adr_in  : std_logic_vector(log2(DMEM_SIZE) - 1 downto 0);
        signal dmem_dat_in  : std_logic_vector(31 downto 0);
        signal dmem_dat_in  : std_logic_vector(31 downto 0);
        signal dmem_dat_out : std_logic_vector(31 downto 0);
        signal dmem_dat_out : std_logic_vector(31 downto 0);
        signal dmem_cyc_in  : std_logic;
        signal dmem_cyc_in  : std_logic;
        signal dmem_stb_in  : std_logic;
        signal dmem_stb_in  : std_logic;
        signal dmem_sel_in  : std_logic_vector(3 downto 0);
        signal dmem_sel_in  : std_logic_vector(3 downto 0);
        signal dmem_we_in   : std_logic;
        signal dmem_we_in   : std_logic;
        signal dmem_ack_out : std_logic;
        signal dmem_ack_out : std_logic;
 
 
        -- Processor signals:
        -- Processor signals:
        signal p_adr_out : std_logic_vector(31 downto 0);
        signal p_adr_out : std_logic_vector(31 downto 0);
        signal p_dat_out : std_logic_vector(31 downto 0);
        signal p_dat_out : std_logic_vector(31 downto 0);
        signal p_dat_in  : std_logic_vector(31 downto 0);
        signal p_dat_in  : std_logic_vector(31 downto 0);
        signal p_cyc_out : std_logic;
        signal p_cyc_out : std_logic;
        signal p_stb_out : std_logic;
        signal p_stb_out : std_logic;
        signal p_sel_out : std_logic_vector(3 downto 0);
        signal p_sel_out : std_logic_vector(3 downto 0);
        signal p_we_out  : std_logic;
        signal p_we_out  : std_logic;
        signal p_ack_in  : std_logic;
        signal p_ack_in  : std_logic;
 
 
        -- Arbitrated wishbone signals:
        -- Arbitrated wishbone signals:
        signal wb_adr : std_logic_vector(31 downto 0);
        signal wb_adr : std_logic_vector(31 downto 0);
        signal wb_dat : std_logic_vector(31 downto 0);
        signal wb_dat : std_logic_vector(31 downto 0);
        signal wb_sel : std_logic_vector( 3 downto 0);
        signal wb_sel : std_logic_vector( 3 downto 0);
        signal wb_cyc : std_logic;
        signal wb_cyc : std_logic;
        signal wb_stb : std_logic;
        signal wb_stb : std_logic;
        signal wb_we  : std_logic;
        signal wb_we  : std_logic;
 
 
        -- Initialization "module" signals:
        -- Initialization "module" signals:
        signal init_adr_out : std_logic_vector(31 downto 0) := (others => '0');
        signal init_adr_out : std_logic_vector(31 downto 0) := (others => '0');
        signal init_dat_out : std_logic_vector(31 downto 0) := (others => '0');
        signal init_dat_out : std_logic_vector(31 downto 0) := (others => '0');
        signal init_cyc_out : std_logic := '0';
        signal init_cyc_out : std_logic := '0';
        signal init_stb_out : std_logic := '0';
        signal init_stb_out : std_logic := '0';
        signal init_we_out  : std_logic := '1';
        signal init_we_out  : std_logic := '1';
 
 
        -- Processor reset signals:
        -- Processor reset signals:
        signal processor_reset : std_logic := '1';
        signal processor_reset : std_logic := '1';
 
 
        -- Simulation control:
        -- Simulation control:
        signal initialized  : boolean := false;
        signal initialized  : boolean := false;
        signal simulation_finished : boolean := false;
        signal simulation_finished : boolean := false;
 
 
begin
begin
 
 
        processor: entity work.pp_potato
        processor: entity work.pp_potato
                port map(
                generic map(
 
                        RESET_ADDRESS => RESET_ADDRESS
 
                ) port map(
                        clk => clk,
                        clk => clk,
                        reset => processor_reset,
                        reset => processor_reset,
 
                        timer_clk => timer_clk,
                        irq => irq,
                        irq => irq,
                        fromhost_data => fromhost_data,
                        fromhost_data => fromhost_data,
                        fromhost_updated => fromhost_updated,
                        fromhost_updated => fromhost_updated,
                        tohost_data => tohost_data,
                        tohost_data => tohost_data,
                        tohost_updated => tohost_updated,
                        tohost_updated => tohost_updated,
                        wb_adr_out => p_adr_out,
                        wb_adr_out => p_adr_out,
                        wb_sel_out => p_sel_out,
                        wb_sel_out => p_sel_out,
                        wb_cyc_out => p_cyc_out,
                        wb_cyc_out => p_cyc_out,
                        wb_stb_out => p_stb_out,
                        wb_stb_out => p_stb_out,
                        wb_we_out => p_we_out,
                        wb_we_out => p_we_out,
                        wb_dat_out => p_dat_out,
                        wb_dat_out => p_dat_out,
                        wb_dat_in => p_dat_in,
                        wb_dat_in => p_dat_in,
                        wb_ack_in => p_ack_in
                        wb_ack_in => p_ack_in
                );
                );
 
 
        imem: entity work.pp_soc_memory
        imem: entity work.pp_soc_memory
                generic map(
                generic map(
                        MEMORY_SIZE => IMEM_SIZE
                        MEMORY_SIZE => IMEM_SIZE
                ) port map(
                ) port map(
                        clk => clk,
                        clk => clk,
                        reset => reset,
                        reset => reset,
                        wb_adr_in => imem_adr_in,
                        wb_adr_in => imem_adr_in,
                        wb_dat_in => imem_dat_in,
                        wb_dat_in => imem_dat_in,
                        wb_dat_out => imem_dat_out,
                        wb_dat_out => imem_dat_out,
                        wb_cyc_in => imem_cyc_in,
                        wb_cyc_in => imem_cyc_in,
                        wb_stb_in => imem_stb_in,
                        wb_stb_in => imem_stb_in,
                        wb_sel_in => imem_sel_in,
                        wb_sel_in => imem_sel_in,
                        wb_we_in => imem_we_in,
                        wb_we_in => imem_we_in,
                        wb_ack_out => imem_ack_out
                        wb_ack_out => imem_ack_out
                );
                );
 
 
        dmem: entity work.pp_soc_memory
        dmem: entity work.pp_soc_memory
                generic map(
                generic map(
                        MEMORY_SIZE => DMEM_SIZE
                        MEMORY_SIZE => DMEM_SIZE
                ) port map(
                ) port map(
                        clk => clk,
                        clk => clk,
                        reset => reset,
                        reset => reset,
                        wb_adr_in => dmem_adr_in,
                        wb_adr_in => dmem_adr_in,
                        wb_dat_in => dmem_dat_in,
                        wb_dat_in => dmem_dat_in,
                        wb_dat_out => dmem_dat_out,
                        wb_dat_out => dmem_dat_out,
                        wb_cyc_in => dmem_cyc_in,
                        wb_cyc_in => dmem_cyc_in,
                        wb_stb_in => dmem_stb_in,
                        wb_stb_in => dmem_stb_in,
                        wb_sel_in => dmem_sel_in,
                        wb_sel_in => dmem_sel_in,
                        wb_we_in => dmem_we_in,
                        wb_we_in => dmem_we_in,
                        wb_ack_out => dmem_ack_out
                        wb_ack_out => dmem_ack_out
                );
                );
 
 
        imem_adr_in <= wb_adr(imem_adr_in'range);
        imem_adr_in <= wb_adr(imem_adr_in'range);
        imem_dat_in <= wb_dat;
        imem_dat_in <= wb_dat;
        imem_we_in <= wb_we;
        imem_we_in <= wb_we;
        imem_sel_in <= wb_sel;
        imem_sel_in <= wb_sel;
        dmem_adr_in <= wb_adr(dmem_adr_in'range);
        dmem_adr_in <= wb_adr(dmem_adr_in'range);
        dmem_dat_in <= wb_dat;
        dmem_dat_in <= wb_dat;
        dmem_we_in <= wb_we;
        dmem_we_in <= wb_we;
        dmem_sel_in <= wb_sel;
        dmem_sel_in <= wb_sel;
 
 
        address_decoder: process(wb_adr, imem_dat_out, imem_ack_out, dmem_dat_out, dmem_ack_out,
        address_decoder: process(wb_adr, imem_dat_out, imem_ack_out, dmem_dat_out, dmem_ack_out,
                wb_cyc, wb_stb)
                wb_cyc, wb_stb)
        begin
        begin
                if to_integer(unsigned(wb_adr)) < IMEM_SIZE then
                if to_integer(unsigned(wb_adr)) < IMEM_SIZE then
                        p_dat_in <= imem_dat_out;
                        p_dat_in <= imem_dat_out;
                        p_ack_in <= imem_ack_out;
                        p_ack_in <= imem_ack_out;
                        imem_cyc_in <= wb_cyc;
                        imem_cyc_in <= wb_cyc;
                        imem_stb_in <= wb_stb;
                        imem_stb_in <= wb_stb;
                        dmem_cyc_in <= '0';
                        dmem_cyc_in <= '0';
                        dmem_stb_in <= '0';
                        dmem_stb_in <= '0';
                else
                else
                        p_dat_in <= dmem_dat_out;
                        p_dat_in <= dmem_dat_out;
                        p_ack_in <= dmem_ack_out;
                        p_ack_in <= dmem_ack_out;
                        dmem_cyc_in <= wb_cyc;
                        dmem_cyc_in <= wb_cyc;
                        dmem_stb_in <= wb_stb;
                        dmem_stb_in <= wb_stb;
                        imem_cyc_in <= '0';
                        imem_cyc_in <= '0';
                        imem_stb_in <= '0';
                        imem_stb_in <= '0';
                end if;
                end if;
        end process address_decoder;
        end process address_decoder;
 
 
        arbiter: process(initialized, init_adr_out, init_dat_out, init_cyc_out, init_stb_out, init_we_out,
        arbiter: process(initialized, init_adr_out, init_dat_out, init_cyc_out, init_stb_out, init_we_out,
                p_adr_out, p_dat_out, p_cyc_out, p_stb_out, p_we_out, p_sel_out)
                p_adr_out, p_dat_out, p_cyc_out, p_stb_out, p_we_out, p_sel_out)
        begin
        begin
                if not initialized then
                if not initialized then
                        wb_adr <= init_adr_out;
                        wb_adr <= init_adr_out;
                        wb_dat <= init_dat_out;
                        wb_dat <= init_dat_out;
                        wb_cyc <= init_cyc_out;
                        wb_cyc <= init_cyc_out;
                        wb_stb <= init_stb_out;
                        wb_stb <= init_stb_out;
                        wb_we <= init_we_out;
                        wb_we <= init_we_out;
                        wb_sel <= x"f";
                        wb_sel <= x"f";
                else
                else
                        wb_adr <= p_adr_out;
                        wb_adr <= p_adr_out;
                        wb_dat <= p_dat_out;
                        wb_dat <= p_dat_out;
                        wb_cyc <= p_cyc_out;
                        wb_cyc <= p_cyc_out;
                        wb_stb <= p_stb_out;
                        wb_stb <= p_stb_out;
                        wb_we <= p_we_out;
                        wb_we <= p_we_out;
                        wb_sel <= p_sel_out;
                        wb_sel <= p_sel_out;
                end if;
                end if;
        end process arbiter;
        end process arbiter;
 
 
        initializer: process
        initializer: process
                file imem_file : text open READ_MODE is IMEM_FILENAME;
                file imem_file : text open READ_MODE is IMEM_FILENAME;
                file dmem_file : text open READ_MODE is DMEM_FILENAME;
                file dmem_file : text open READ_MODE is DMEM_FILENAME;
                variable input_line  : line;
                variable input_line  : line;
                variable input_index : natural;
                variable input_index : natural;
                variable input_value : std_logic_vector(31 downto 0);
                variable input_value : std_logic_vector(31 downto 0);
                variable temp : std_logic_vector(31 downto 0);
                variable temp : std_logic_vector(31 downto 0);
 
 
                constant DMEM_START : natural := IMEM_SIZE;
                constant DMEM_START_ADDR : natural := IMEM_SIZE;
        begin
        begin
                if not initialized then
                if not initialized then
                        -- Read the instruction memory file:
                        -- Read the instruction memory file:
                        for i in 0 to IMEM_SIZE loop
                        for i in 0 to (IMEM_SIZE / 4) - 1 loop
                                exit when endfile(imem_file);
                                exit when endfile(imem_file);
 
 
                                readline(imem_file, input_line);
                                readline(imem_file, input_line);
                                hread(input_line, input_value);
                                hread(input_line, input_value);
 
 
                                init_adr_out <= std_logic_vector(to_unsigned(i * 4, init_adr_out'length));
                                init_adr_out <= std_logic_vector(to_unsigned(to_integer(unsigned(IMEM_START_ADDR)) + (i * 4),
 
                                        init_adr_out'length));
                                init_dat_out <= input_value;
                                init_dat_out <= input_value;
                                init_cyc_out <= '1';
                                init_cyc_out <= '1';
                                init_stb_out <= '1';
                                init_stb_out <= '1';
                                wait until imem_ack_out = '1';
                                wait until imem_ack_out = '1';
                                wait for clk_period;
                                wait for clk_period;
                                init_stb_out <= '0';
                                init_stb_out <= '0';
                                wait until imem_ack_out = '0';
                                wait until imem_ack_out = '0';
                                wait for clk_period;
                                wait for clk_period;
                        end loop;
                        end loop;
 
 
                        init_cyc_out <= '0';
                        init_cyc_out <= '0';
                        init_stb_out <= '0';
                        init_stb_out <= '0';
                        wait for clk_period;
                        wait for clk_period;
 
 
                        -- Read the data memory file:
                        -- Read the data memory file:
                        for i in 0 to DMEM_SIZE loop
                        for i in 0 to (DMEM_SIZE / 4) - 1 loop
                                exit when endfile(dmem_file);
                                exit when endfile(dmem_file);
 
 
                                readline(dmem_file, input_line);
                                readline(dmem_file, input_line);
                                hread(input_line, input_value);
                                hread(input_line, input_value);
 
 
 
 
                                -- Swap endianness, TODO: prevent this, fix scripts/extract_hex.sh
                                -- Swap endianness, TODO: prevent this, fix scripts/extract_hex.sh
                                temp(7 downto 0) := input_value(31 downto 24);
                                temp(7 downto 0) := input_value(31 downto 24);
                                temp(15 downto 8) := input_value(23 downto 16);
                                temp(15 downto 8) := input_value(23 downto 16);
                                temp(23 downto 16) := input_value(15 downto 8);
                                temp(23 downto 16) := input_value(15 downto 8);
                                temp(31 downto 24) := input_value(7 downto 0);
                                temp(31 downto 24) := input_value(7 downto 0);
 
 
                                input_value := temp;
                                input_value := temp;
 
 
                                init_adr_out <= std_logic_vector(to_unsigned(DMEM_START + (i * 4), init_adr_out'length));
                                init_adr_out <= std_logic_vector(to_unsigned(DMEM_START_ADDR + (i * 4), init_adr_out'length));
                                init_dat_out <= input_value;
                                init_dat_out <= input_value;
                                init_cyc_out <= '1';
                                init_cyc_out <= '1';
                                init_stb_out <= '1';
                                init_stb_out <= '1';
                                wait until dmem_ack_out = '1';
                                wait until dmem_ack_out = '1';
                                wait for clk_period;
                                wait for clk_period;
                                init_stb_out <= '0';
                                init_stb_out <= '0';
                                wait until dmem_ack_out = '0';
                                wait until dmem_ack_out = '0';
                                wait for clk_period;
                                wait for clk_period;
                        end loop;
                        end loop;
 
 
                        init_cyc_out <= '0';
                        init_cyc_out <= '0';
                        init_stb_out <= '0';
                        init_stb_out <= '0';
                        wait for clk_period;
                        wait for clk_period;
 
 
                        initialized <= true;
                        initialized <= true;
                        wait;
                        wait;
                end if;
                end if;
        end process initializer;
        end process initializer;
 
 
        clock: process
        clock: process
        begin
        begin
                clk <= '1';
                clk <= '1';
                wait for clk_period / 2;
                wait for clk_period / 2;
                clk <= '0';
                clk <= '0';
                wait for clk_period / 2;
                wait for clk_period / 2;
 
 
                if simulation_finished then
                if simulation_finished then
                        wait;
                        wait;
                end if;
                end if;
        end process clock;
        end process clock;
 
 
 
        timer_clock: process
 
        begin
 
                timer_clk <= '1';
 
                wait for timer_clk_period / 2;
 
                timer_clk <= '0';
 
                wait for timer_clk_period / 2;
 
 
 
                if simulation_finished then
 
                        wait;
 
                end if;
 
        end process timer_clock;
 
 
        stimulus: process
        stimulus: process
        begin
        begin
                wait for clk_period * 2;
                wait for clk_period * 2;
                reset <= '0';
                reset <= '0';
 
 
                wait until initialized;
                wait until initialized;
                processor_reset <= '0';
                processor_reset <= '0';
 
 
                wait until tohost_updated = '1';
                wait until tohost_updated = '1';
                wait for clk_period; -- Let the signal "settle", because of stupid clock edges
                wait for clk_period; -- Let the signal "settle", because of stupid clock edges
                if tohost_data = x"00000001" then
                if tohost_data = x"00000001" then
                        report "Success!" severity NOTE;
                        report "Success!" severity NOTE;
                else
                else
                        report "Failure in test " & integer'image(to_integer(shift_right(unsigned(tohost_data), 1))) & "!" severity NOTE;
                        report "Failure in test " & integer'image(to_integer(shift_right(unsigned(tohost_data), 1))) & "!" severity NOTE;
                end if;
                end if;
 
 
                simulation_finished <= true;
                simulation_finished <= true;
                wait;
                wait;
        end process stimulus;
        end process stimulus;
 
 
end architecture testbench;
end architecture testbench;
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.