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

Subversion Repositories potato

[/] [potato/] [trunk/] [testbenches/] [tb_processor.vhd] - Diff between revs 2 and 3

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

Rev 2 Rev 3
-- 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 <https://github.com/skordal/potato/issues>
-- 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;
 
 
entity tb_processor is
entity tb_processor is
        generic(
        generic(
                IMEM_SIZE : natural := 2048; --! Size of the instruction memory in bytes.
                IMEM_SIZE : natural := 2048; --! Size of the instruction memory in bytes.
                DMEM_SIZE : natural := 2048; --! Size of the data memory in bytes.
                DMEM_SIZE : natural := 2048; --! Size of the data memory in bytes.
                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_processor;
end entity tb_processor;
 
 
architecture testbench of tb_processor is
architecture testbench of tb_processor is
 
 
        -- Processor component prototype:
        -- Processor component prototype:
        component pp_core is
        component pp_core is
                port(
                port(
                        -- Common inputs:
                        -- Common inputs:
                        clk       : in std_logic; --! Processor clock
                        clk       : in std_logic; --! Processor clock
                        reset     : in std_logic; --! Reset signal
                        reset     : in std_logic; --! Reset signal
                        timer_clk : in std_logic; --! Timer clock input
                        timer_clk : in std_logic; --! Timer clock input
 
 
                        -- Instruction memory interface:
                        -- Instruction memory interface:
                        imem_address : out std_logic_vector(31 downto 0); --! Address of the next instruction
                        imem_address : out std_logic_vector(31 downto 0); --! Address of the next instruction
                        imem_data_in : in  std_logic_vector(31 downto 0); --! Instruction input
                        imem_data_in : in  std_logic_vector(31 downto 0); --! Instruction input
                        imem_req     : out std_logic;
                        imem_req     : out std_logic;
                        imem_ack     : in  std_logic;
                        imem_ack     : in  std_logic;
 
 
                        -- Data memory interface:
                        -- Data memory interface:
                        dmem_address   : out std_logic_vector(31 downto 0); --! Data address
                        dmem_address   : out std_logic_vector(31 downto 0); --! Data address
                        dmem_data_in   : in  std_logic_vector(31 downto 0); --! Input from the data memory
                        dmem_data_in   : in  std_logic_vector(31 downto 0); --! Input from the data memory
                        dmem_data_out  : out std_logic_vector(31 downto 0); --! Ouptut to the data memory
                        dmem_data_out  : out std_logic_vector(31 downto 0); --! Ouptut to the data memory
                        dmem_data_size : out std_logic_vector( 1 downto 0);  --! Size of the data, 1 = 8 bits, 2 = 16 bits, 0 = 32 bits. 
                        dmem_data_size : out std_logic_vector( 1 downto 0);  --! Size of the data, 1 = 8 bits, 2 = 16 bits, 0 = 32 bits. 
                        dmem_read_req  : out std_logic; --! Data memory read request
                        dmem_read_req  : out std_logic; --! Data memory read request
                        dmem_read_ack  : in  std_logic; --! Data memory read acknowledge
                        dmem_read_ack  : in  std_logic; --! Data memory read acknowledge
                        dmem_write_req : out std_logic; --! Data memory write request
                        dmem_write_req : out std_logic; --! Data memory write request
                        dmem_write_ack : in  std_logic; --! Data memory write acknowledge
                        dmem_write_ack : in  std_logic; --! Data memory write acknowledge
 
 
                        -- Tohost/fromhost interface:
                        -- Tohost/fromhost interface:
                        fromhost_data     : in  std_logic_vector(31 downto 0); --! Data from the host/simulator.
                        fromhost_data     : in  std_logic_vector(31 downto 0); --! Data from the host/simulator.
                        fromhost_write_en : in  std_logic;                     --! Write enable signal from the host/simulator.
                        fromhost_write_en : in  std_logic;                     --! Write enable signal from the host/simulator.
                        tohost_data       : out std_logic_vector(31 downto 0); --! Data to the host/simulator.
                        tohost_data       : out std_logic_vector(31 downto 0); --! Data to the host/simulator.
                        tohost_write_en   : out std_logic;                     --! Write enable signal to the host/simulator.
                        tohost_write_en   : out std_logic;                     --! Write enable signal to the host/simulator.
 
 
                        -- External interrupt input:
                        -- External interrupt input:
                        irq : in std_logic_vector(7 downto 0) --! IRQ input
                        irq : in std_logic_vector(7 downto 0) --! IRQ input
                );
                );
        end component pp_core;
        end component pp_core;
 
 
        -- Clock signal:
        -- Clock signal:
        signal clk : std_logic := '0';
        signal clk : std_logic := '0';
        constant clk_period : time := 10 ns;
        constant clk_period : time := 10 ns;
 
 
        -- Common inputs:
        -- Common inputs:
        signal reset  : std_logic := '1';
        signal reset  : std_logic := '1';
 
 
        -- Instruction memory interface:
        -- Instruction memory interface:
        signal imem_address : std_logic_vector(31 downto 0);
        signal imem_address : std_logic_vector(31 downto 0);
        signal imem_data_in : std_logic_vector(31 downto 0) := (others => '0');
        signal imem_data_in : std_logic_vector(31 downto 0) := (others => '0');
        signal imem_req     : std_logic;
        signal imem_req     : std_logic;
        signal imem_ack     : std_logic := '0';
        signal imem_ack     : std_logic := '0';
 
 
        -- Data memory interface:
        -- Data memory interface:
        signal dmem_address   : std_logic_vector(31 downto 0);
        signal dmem_address   : std_logic_vector(31 downto 0);
        signal dmem_data_in   : std_logic_vector(31 downto 0) := (others => '0');
        signal dmem_data_in   : std_logic_vector(31 downto 0) := (others => '0');
        signal dmem_data_out  : std_logic_vector(31 downto 0);
        signal dmem_data_out  : std_logic_vector(31 downto 0);
        signal dmem_data_size : std_logic_vector( 1 downto 0);
        signal dmem_data_size : std_logic_vector( 1 downto 0);
        signal dmem_read_req, dmem_write_req : std_logic;
        signal dmem_read_req, dmem_write_req : std_logic;
        signal dmem_read_ack, dmem_write_ack : std_logic := '1';
        signal dmem_read_ack, dmem_write_ack : std_logic := '1';
 
 
        -- Tohost/Fromhost:
        -- Tohost/Fromhost:
        signal tohost_data       : std_logic_vector(31 downto 0);
        signal tohost_data       : std_logic_vector(31 downto 0);
        signal fromhost_data     : std_logic_vectoR(31 downto 0) := (others => '0');
        signal fromhost_data     : std_logic_vectoR(31 downto 0) := (others => '0');
        signal tohost_write_en   : std_logic;
        signal tohost_write_en   : std_logic;
        signal fromhost_write_en : std_logic := '0';
        signal fromhost_write_en : std_logic := '0';
 
 
        -- External interrupt input:
        -- External interrupt input:
        signal irq : std_logic_vector(7 downto 0) := (others => '0');
        signal irq : std_logic_vector(7 downto 0) := (others => '0');
 
 
        -- Simulation initialized:
        -- Simulation initialized:
        signal imem_initialized, dmem_initialized, initialized : boolean := false;
        signal imem_initialized, dmem_initialized, initialized : boolean := false;
 
 
        -- Memory array type:
        -- Memory array type:
        type memory_array is array(natural range <>) of std_logic_vector(7 downto 0);
        type memory_array is array(natural range <>) of std_logic_vector(7 downto 0);
        constant IMEM_BASE : natural := 0;
        constant IMEM_BASE : natural := 0;
        constant IMEM_END  : natural := IMEM_SIZE - 1;
        constant IMEM_END  : natural := IMEM_SIZE - 1;
        constant DMEM_BASE : natural := IMEM_SIZE;
        constant DMEM_BASE : natural := IMEM_SIZE;
        constant DMEM_END  : natural := IMEM_SIZE + DMEM_SIZE - 1;
        constant DMEM_END  : natural := IMEM_SIZE + DMEM_SIZE - 1;
 
 
        -- Memories:
        -- Memories:
        signal imem_memory : memory_array(IMEM_BASE to IMEM_END);
        signal imem_memory : memory_array(IMEM_BASE to IMEM_END);
        signal dmem_memory : memory_array(DMEM_BASE to DMEM_END);
        signal dmem_memory : memory_array(DMEM_BASE to DMEM_END);
 
 
        signal simulation_finished : boolean := false;
        signal simulation_finished : boolean := false;
 
 
begin
begin
 
 
        uut: pp_core
        uut: pp_core
                port map(
                port map(
                        clk => clk,
                        clk => clk,
                        reset => reset,
                        reset => reset,
                        timer_clk => clk,
                        timer_clk => clk,
                        imem_address => imem_address,
                        imem_address => imem_address,
                        imem_data_in => imem_data_in,
                        imem_data_in => imem_data_in,
                        imem_req => imem_req,
                        imem_req => imem_req,
                        imem_ack => imem_ack,
                        imem_ack => imem_ack,
                        dmem_address => dmem_address,
                        dmem_address => dmem_address,
                        dmem_data_in => dmem_data_in,
                        dmem_data_in => dmem_data_in,
                        dmem_data_out => dmem_data_out,
                        dmem_data_out => dmem_data_out,
                        dmem_data_size => dmem_data_size,
                        dmem_data_size => dmem_data_size,
                        dmem_read_req => dmem_read_req,
                        dmem_read_req => dmem_read_req,
                        dmem_read_ack => dmem_read_ack,
                        dmem_read_ack => dmem_read_ack,
                        dmem_write_req => dmem_write_req,
                        dmem_write_req => dmem_write_req,
                        dmem_write_ack => dmem_write_ack,
                        dmem_write_ack => dmem_write_ack,
                        tohost_data => tohost_data,
                        tohost_data => tohost_data,
                        tohost_write_en => tohost_write_en,
                        tohost_write_en => tohost_write_en,
                        fromhost_data => fromhost_data,
                        fromhost_data => fromhost_data,
                        fromhost_write_en => fromhost_write_en,
                        fromhost_write_en => fromhost_write_en,
                        irq => irq
                        irq => irq
                );
                );
 
 
        clock: process
        clock: process
        begin
        begin
                clk <= '0';
                clk <= '0';
                wait for clk_period / 2;
                wait for clk_period / 2;
                clk <= '1';
                clk <= '1';
                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;
 
 
        --! Initializes the instruction memory from file.
        --! Initializes the instruction memory from file.
        imem_init: process
        imem_init: process
                file imem_file : text open READ_MODE is IMEM_FILENAME;
                file imem_file : text open READ_MODE is IMEM_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);
        begin
        begin
                for i in IMEM_BASE / 4 to IMEM_END / 4 loop
                for i in IMEM_BASE / 4 to IMEM_END / 4 loop
                        if not endfile(imem_file) then
                        if not endfile(imem_file) then
                                readline(imem_file, input_line);
                                readline(imem_file, input_line);
                                hread(input_line, input_value);
                                hread(input_line, input_value);
                                imem_memory(i * 4 + 0) <= input_value( 7 downto  0);
                                imem_memory(i * 4 + 0) <= input_value( 7 downto  0);
                                imem_memory(i * 4 + 1) <= input_value(15 downto  8);
                                imem_memory(i * 4 + 1) <= input_value(15 downto  8);
                                imem_memory(i * 4 + 2) <= input_value(23 downto 16);
                                imem_memory(i * 4 + 2) <= input_value(23 downto 16);
                                imem_memory(i * 4 + 3) <= input_value(31 downto 24);
                                imem_memory(i * 4 + 3) <= input_value(31 downto 24);
                        else
                        else
                                imem_memory(i * 4 + 0) <= RISCV_NOP( 7 downto 0);
                                imem_memory(i * 4 + 0) <= RISCV_NOP( 7 downto 0);
                                imem_memory(i * 4 + 1) <= RISCV_NOP(15 downto 8);
                                imem_memory(i * 4 + 1) <= RISCV_NOP(15 downto 8);
                                imem_memory(i * 4 + 2) <= RISCV_NOP(23 downto 16);
                                imem_memory(i * 4 + 2) <= RISCV_NOP(23 downto 16);
                                imem_memory(i * 4 + 3) <= RISCV_NOP(31 downto 24);
                                imem_memory(i * 4 + 3) <= RISCV_NOP(31 downto 24);
                        end if;
                        end if;
                end loop;
                end loop;
 
 
                imem_initialized <= true;
                imem_initialized <= true;
                wait;
                wait;
        end process imem_init;
        end process imem_init;
 
 
        --! Initializes and handles writes to the data memory.
        --! Initializes and handles writes to the data memory.
        dmem_init_and_write: process(clk)
        dmem_init_and_write: process(clk)
                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);
        begin
        begin
                if not dmem_initialized then
                if not dmem_initialized then
                        for i in DMEM_BASE / 4 to DMEM_END / 4 loop
                        for i in DMEM_BASE / 4 to DMEM_END / 4 loop
                                if not endfile(dmem_file) then
                                if not endfile(dmem_file) then
                                        readline(dmem_file, input_line);
                                        readline(dmem_file, input_line);
                                        hread(input_line, input_value);
                                        hread(input_line, input_value);
 
 
                                        -- Read from a big-endian file:
                                        -- Read from a big-endian file:
                                        dmem_memory(i * 4 + 3) <= input_value( 7 downto  0);
                                        dmem_memory(i * 4 + 3) <= input_value( 7 downto  0);
                                        dmem_memory(i * 4 + 2) <= input_value(15 downto  8);
                                        dmem_memory(i * 4 + 2) <= input_value(15 downto  8);
                                        dmem_memory(i * 4 + 1) <= input_value(23 downto 16);
                                        dmem_memory(i * 4 + 1) <= input_value(23 downto 16);
                                        dmem_memory(i * 4 + 0) <= input_value(31 downto 24);
                                        dmem_memory(i * 4 + 0) <= input_value(31 downto 24);
                                else
                                else
                                        dmem_memory(i * 4 + 0) <= (others => '0');
                                        dmem_memory(i * 4 + 0) <= (others => '0');
                                        dmem_memory(i * 4 + 1) <= (others => '0');
                                        dmem_memory(i * 4 + 1) <= (others => '0');
                                        dmem_memory(i * 4 + 2) <= (others => '0');
                                        dmem_memory(i * 4 + 2) <= (others => '0');
                                        dmem_memory(i * 4 + 3) <= (others => '0');
                                        dmem_memory(i * 4 + 3) <= (others => '0');
                                end if;
                                end if;
                        end loop;
                        end loop;
 
 
                        dmem_initialized <= true;
                        dmem_initialized <= true;
                end if;
                end if;
 
 
                if rising_edge(clk) then
                if rising_edge(clk) then
                        if dmem_write_ack = '1' then
                        if dmem_write_ack = '1' then
                                dmem_write_ack <= '0';
                                dmem_write_ack <= '0';
                        elsif dmem_write_req = '1' then
                        elsif dmem_write_req = '1' then
                                case dmem_data_size is
                                case dmem_data_size is
                                        when b"00" => -- 32 bits
                                        when b"00" => -- 32 bits
                                                dmem_memory(to_integer(unsigned(dmem_address)) + 0) <= dmem_data_out(7 downto 0);
                                                dmem_memory(to_integer(unsigned(dmem_address)) + 0) <= dmem_data_out(7 downto 0);
                                                dmem_memory(to_integer(unsigned(dmem_address)) + 1) <= dmem_data_out(15 downto 8);
                                                dmem_memory(to_integer(unsigned(dmem_address)) + 1) <= dmem_data_out(15 downto 8);
                                                dmem_memory(to_integer(unsigned(dmem_address)) + 2) <= dmem_data_out(23 downto 16);
                                                dmem_memory(to_integer(unsigned(dmem_address)) + 2) <= dmem_data_out(23 downto 16);
                                                dmem_memory(to_integer(unsigned(dmem_address)) + 3) <= dmem_data_out(31 downto 24);
                                                dmem_memory(to_integer(unsigned(dmem_address)) + 3) <= dmem_data_out(31 downto 24);
                                        when b"01" => -- 8 bits
                                        when b"01" => -- 8 bits
                                                dmem_memory(to_integer(unsigned(dmem_address))) <= dmem_data_out(7 downto 0);
                                                dmem_memory(to_integer(unsigned(dmem_address))) <= dmem_data_out(7 downto 0);
                                        when b"10" => -- 16 bits
                                        when b"10" => -- 16 bits
                                                dmem_memory(to_integer(unsigned(dmem_address)) + 0) <= dmem_data_out( 7 downto 0);
                                                dmem_memory(to_integer(unsigned(dmem_address)) + 0) <= dmem_data_out( 7 downto 0);
                                                dmem_memory(to_integer(unsigned(dmem_address)) + 1) <= dmem_data_out(15 downto 8);
                                                dmem_memory(to_integer(unsigned(dmem_address)) + 1) <= dmem_data_out(15 downto 8);
                                        when others => -- Reserved for possible future 64 bit support
                                        when others => -- Reserved for possible future 64 bit support
                                end case;
                                end case;
                                dmem_write_ack <= '1';
                                dmem_write_ack <= '1';
                        end if;
                        end if;
                end if;
                end if;
        end process dmem_init_and_write;
        end process dmem_init_and_write;
 
 
        initialized <= imem_initialized and dmem_initialized;
        initialized <= imem_initialized and dmem_initialized;
 
 
        --! Instruction memory read process.
        --! Instruction memory read process.
        imem_read: process(clk)
        imem_read: process(clk)
        begin
        begin
                if rising_edge(clk) then
                if rising_edge(clk) then
                        if reset = '1' then
                        if reset = '1' then
                                imem_ack <= '0';
                                imem_ack <= '0';
                        else
                        else
                                if to_integer(unsigned(imem_address)) > IMEM_END then
                                if to_integer(unsigned(imem_address)) > IMEM_END then
                                        imem_data_in <= (others => 'X');
                                        imem_data_in <= (others => 'X');
                                else
                                else
                                        imem_data_in <= imem_memory(to_integer(unsigned(imem_address)) + 3)
                                        imem_data_in <= imem_memory(to_integer(unsigned(imem_address)) + 3)
                                                & imem_memory(to_integer(unsigned(imem_address)) + 2)
                                                & imem_memory(to_integer(unsigned(imem_address)) + 2)
                                                & imem_memory(to_integer(unsigned(imem_address)) + 1)
                                                & imem_memory(to_integer(unsigned(imem_address)) + 1)
                                                & imem_memory(to_integer(unsigned(imem_address)) + 0);
                                                & imem_memory(to_integer(unsigned(imem_address)) + 0);
                                end if;
                                end if;
 
 
                                imem_ack <= '1';
                                imem_ack <= '1';
                        end if;
                        end if;
                end if;
                end if;
        end process imem_read;
        end process imem_read;
 
 
        --! Data memory read process.
        --! Data memory read process.
        dmem_read: process(clk)
        dmem_read: process(clk)
        begin
        begin
                if rising_edge(clk) then
                if rising_edge(clk) then
                        if dmem_read_ack = '1' then
                        if dmem_read_ack = '1' then
                                dmem_read_ack <= '0';
                                dmem_read_ack <= '0';
                        elsif dmem_read_req = '1' then
                        elsif dmem_read_req = '1' then
                                case dmem_data_size is
                                case dmem_data_size is
                                        when b"00" => -- 32 bits
                                        when b"00" => -- 32 bits
                                                dmem_data_in <= dmem_memory(to_integer(unsigned(dmem_address) + 3))
                                                dmem_data_in <= dmem_memory(to_integer(unsigned(dmem_address) + 3))
                                                        & dmem_memory(to_integer(unsigned(dmem_address) + 2))
                                                        & dmem_memory(to_integer(unsigned(dmem_address) + 2))
                                                        & dmem_memory(to_integer(unsigned(dmem_address) + 1))
                                                        & dmem_memory(to_integer(unsigned(dmem_address) + 1))
                                                        & dmem_memory(to_integer(unsigned(dmem_address) + 0));
                                                        & dmem_memory(to_integer(unsigned(dmem_address) + 0));
                                        when b"10" => -- 16 bits
                                        when b"10" => -- 16 bits
                                                dmem_data_in(15 downto 8) <= dmem_memory(to_integer(unsigned(dmem_address)) + 1);
                                                dmem_data_in(15 downto 8) <= dmem_memory(to_integer(unsigned(dmem_address)) + 1);
                                                dmem_data_in( 7 downto 0) <= dmem_memory(to_integer(unsigned(dmem_address)) + 0);
                                                dmem_data_in( 7 downto 0) <= dmem_memory(to_integer(unsigned(dmem_address)) + 0);
                                        when b"01" => -- 8  bits
                                        when b"01" => -- 8  bits
                                                dmem_data_in(7 downto 0) <= dmem_memory(to_integer(unsigned(dmem_address)));
                                                dmem_data_in(7 downto 0) <= dmem_memory(to_integer(unsigned(dmem_address)));
                                        when others => -- Reserved for possible future 64 bit support
                                        when others => -- Reserved for possible future 64 bit support
                                end case;
                                end case;
                                dmem_read_ack <= '1';
                                dmem_read_ack <= '1';
                        end if;
                        end if;
                end if;
                end if;
        end process dmem_read;
        end process dmem_read;
 
 
        stimulus: process
        stimulus: process
        begin
        begin
                wait until initialized = true;
                wait until initialized = true;
                report "Testbench initialized, starting behavioural simulation..." severity NOTE;
                report "Testbench initialized, starting behavioural simulation..." severity NOTE;
                wait for clk_period * 2;
                wait for clk_period * 2;
 
 
                -- Release the processor from reset:
                -- Release the processor from reset:
                reset <= '0';
                reset <= '0';
                wait for clk_period;
                wait for clk_period;
 
 
                wait until tohost_write_en = '1';
                wait until tohost_write_en = '1';
                wait for clk_period; -- Let the signal "settle", because of clock edges
                wait for clk_period; -- Let the signal "settle", because of 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.