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

Subversion Repositories potato

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /potato/branches
    from Rev 57 to Rev 59
    Reverse comparison

Rev 57 → Rev 59

new-privileged-isa/scripts/extract_hex.sh Property changes : Deleted: svn:executable ## -1 +0,0 ## -* \ No newline at end of property Index: new-privileged-isa/testbenches/tb_soc_memory.vhd =================================================================== --- new-privileged-isa/testbenches/tb_soc_memory.vhd (revision 57) +++ new-privileged-isa/testbenches/tb_soc_memory.vhd (nonexistent) @@ -1,99 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -entity tb_soc_memory is -end entity tb_soc_memory; - -architecture testbench of tb_soc_memory is - - -- Clock signal: - signal clk : std_logic; - constant clk_period : time := 10 ns; - - -- Reset signal: - signal reset : std_logic := '1'; - - -- Wishbone signals: - signal wb_adr_in : std_logic_vector(31 downto 0); - signal wb_dat_in : std_logic_vector(31 downto 0); - signal wb_dat_out : std_logic_vector(31 downto 0); - signal wb_cyc_in : std_logic := '0'; - signal wb_stb_in : std_logic := '0'; - signal wb_sel_in : std_logic_vector(3 downto 0) := (others => '1'); - signal wb_we_in : std_logic := '0'; - signal wb_ack_out : std_logic; - -begin - - uut: entity work.pp_soc_memory - port map( - clk => clk, - reset => reset, - wb_adr_in => wb_adr_in, - wb_dat_in => wb_dat_in, - wb_dat_out => wb_dat_out, - wb_cyc_in => wb_cyc_in, - wb_stb_in => wb_stb_in, - wb_sel_in => wb_sel_in, - wb_we_in => wb_we_in, - wb_ack_out => wb_ack_out - ); - - clock: process - begin - clk <= '1'; - wait for clk_period / 2; - clk <= '0'; - wait for clk_period / 2; - end process clock; - - stimulus: process - begin - wait for clk_period; - reset <= '0'; - - -- Write 32 bit of data to address 0: - wb_adr_in <= x"00000000"; - wb_dat_in <= x"deadbeef"; - wb_cyc_in <= '1'; - wb_stb_in <= '1'; - wb_we_in <= '1'; - wait for clk_period; - wb_stb_in <= '0'; - wb_cyc_in <= '0'; - wait for clk_period; - - -- Write a block write of two 32-bit words at address 0 and 1: - wb_adr_in <= x"00000000"; - wb_dat_in <= x"feedbeef"; - wb_cyc_in <= '1'; - wb_stb_in <= '1'; - wait for clk_period; - wb_stb_in <= '0'; - wb_adr_in <= x"00000004"; - wb_dat_in <= x"f00dd00d"; - wait for clk_period; - wb_stb_in <= '1'; - wait for clk_period; - wb_stb_in <= '0'; - wb_cyc_in <= '0'; - - -- Read address 4: - wait for clk_period; - wb_we_in <= '0'; - wb_adr_in <= x"00000000"; - wb_cyc_in <= '1'; - wb_stb_in <= '1'; - wait for clk_period; - - -- TODO: Make this testbench automatic. - - wait; - end process stimulus; - -end architecture testbench; Index: new-privileged-isa/testbenches/tb_processor.vhd =================================================================== --- new-privileged-isa/testbenches/tb_processor.vhd (revision 57) +++ new-privileged-isa/testbenches/tb_processor.vhd (nonexistent) @@ -1,277 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use ieee.std_logic_textio.all; -use std.textio.all; - -use work.pp_constants.all; - -entity tb_processor is - generic( - IMEM_SIZE : natural := 4096; --! Size of the instruction 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. - DMEM_FILENAME : string := "dmem_testfile.hex" --! File containing the contents of data memory. - ); -end entity tb_processor; - -architecture testbench of tb_processor is - - -- Clock signal: - signal clk : std_logic := '0'; - constant clk_period : time := 10 ns; - - -- Timer clock signal: - signal timer_clk : std_logic := '0'; - constant timer_clk_period : time := 100 ns; - - -- Common inputs: - signal reset : std_logic := '1'; - - -- Instruction memory interface: - signal imem_address : std_logic_vector(31 downto 0); - signal imem_data_in : std_logic_vector(31 downto 0) := (others => '0'); - signal imem_req : std_logic; - signal imem_ack : std_logic := '0'; - - -- Data memory interface: - signal dmem_address : std_logic_vector(31 downto 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_size : std_logic_vector( 1 downto 0); - signal dmem_read_req, dmem_write_req : std_logic; - signal dmem_read_ack, dmem_write_ack : std_logic := '1'; - - -- Tohost/Fromhost: - signal tohost_data : std_logic_vector(31 downto 0); - signal fromhost_data : std_logic_vectoR(31 downto 0) := (others => '0'); - signal tohost_write_en : std_logic; - signal fromhost_write_en : std_logic := '0'; - - -- External interrupt input: - signal irq : std_logic_vector(7 downto 0) := (others => '0'); - - -- Simulation initialized: - signal imem_initialized, dmem_initialized, initialized : boolean := false; - - -- Memory array type: - type memory_array is array(natural range <>) of std_logic_vector(7 downto 0); - constant IMEM_BASE : natural := 0; - constant IMEM_END : natural := IMEM_BASE + IMEM_SIZE - 1; - constant DMEM_BASE : natural := IMEM_END + 1; - constant DMEM_END : natural := IMEM_END + DMEM_SIZE; - - -- Memories: - signal imem_memory : memory_array(IMEM_BASE to IMEM_END); - signal dmem_memory : memory_array(DMEM_BASE to DMEM_END); - - signal simulation_finished : boolean := false; - -begin - - uut: entity work.pp_core - generic map( - RESET_ADDRESS => RESET_ADDRESS - ) port map( - clk => clk, - reset => reset, - timer_clk => timer_clk, - imem_address => imem_address, - imem_data_in => imem_data_in, - imem_req => imem_req, - imem_ack => imem_ack, - dmem_address => dmem_address, - dmem_data_in => dmem_data_in, - dmem_data_out => dmem_data_out, - dmem_data_size => dmem_data_size, - dmem_read_req => dmem_read_req, - dmem_read_ack => dmem_read_ack, - dmem_write_req => dmem_write_req, - dmem_write_ack => dmem_write_ack, - tohost_data => tohost_data, - tohost_write_en => tohost_write_en, - fromhost_data => fromhost_data, - fromhost_write_en => fromhost_write_en, - irq => irq - ); - - clock: process - begin - clk <= '0'; - wait for clk_period / 2; - clk <= '1'; - wait for clk_period / 2; - - if simulation_finished then - wait; - end if; - end process clock; - - timer_clock: process - begin - timer_clk <= '0'; - wait for timer_clk_period / 2; - timer_clk <= '1'; - wait for timer_clk_period / 2; - - if simulation_finished then - wait; - end if; - end process timer_clock; - - --! Initializes the instruction memory from file. - imem_init: process - file imem_file : text open READ_MODE is IMEM_FILENAME; - variable input_line : line; - variable input_index : natural; - variable input_value : std_logic_vector(31 downto 0); - begin - for i in to_integer(unsigned(IMEM_START_ADDR)) / 4 to IMEM_END / 4 loop - --for i in IMEM_BASE / 4 to IMEM_END / 4 loop - if not endfile(imem_file) then - readline(imem_file, input_line); - hread(input_line, input_value); - imem_memory(i * 4 + 0) <= input_value( 7 downto 0); - imem_memory(i * 4 + 1) <= input_value(15 downto 8); - imem_memory(i * 4 + 2) <= input_value(23 downto 16); - imem_memory(i * 4 + 3) <= input_value(31 downto 24); - else - imem_memory(i * 4 + 0) <= RISCV_NOP( 7 downto 0); - imem_memory(i * 4 + 1) <= RISCV_NOP(15 downto 8); - imem_memory(i * 4 + 2) <= RISCV_NOP(23 downto 16); - imem_memory(i * 4 + 3) <= RISCV_NOP(31 downto 24); - end if; - end loop; - - imem_initialized <= true; - wait; - end process imem_init; - - --! Initializes and handles writes to the data memory. - dmem_init_and_write: process(clk) - file dmem_file : text open READ_MODE is DMEM_FILENAME; - variable input_line : line; - variable input_index : natural; - variable input_value : std_logic_vector(31 downto 0); - begin - if not dmem_initialized then - for i in DMEM_BASE / 4 to DMEM_END / 4 loop - if not endfile(dmem_file) then - readline(dmem_file, input_line); - hread(input_line, input_value); - - -- Read from a big-endian file: - dmem_memory(i * 4 + 3) <= input_value( 7 downto 0); - dmem_memory(i * 4 + 2) <= input_value(15 downto 8); - dmem_memory(i * 4 + 1) <= input_value(23 downto 16); - dmem_memory(i * 4 + 0) <= input_value(31 downto 24); - else - dmem_memory(i * 4 + 0) <= (others => '0'); - dmem_memory(i * 4 + 1) <= (others => '0'); - dmem_memory(i * 4 + 2) <= (others => '0'); - dmem_memory(i * 4 + 3) <= (others => '0'); - end if; - end loop; - - dmem_initialized <= true; - end if; - - if rising_edge(clk) then - if dmem_write_ack = '1' then - dmem_write_ack <= '0'; - elsif dmem_write_req = '1' then - case dmem_data_size is - 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)) + 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)) + 3) <= dmem_data_out(31 downto 24); - when b"01" => -- 8 bits - dmem_memory(to_integer(unsigned(dmem_address))) <= dmem_data_out(7 downto 0); - 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)) + 1) <= dmem_data_out(15 downto 8); - when others => - end case; - dmem_write_ack <= '1'; - end if; - end if; - end process dmem_init_and_write; - - initialized <= imem_initialized and dmem_initialized; - - --! Instruction memory read process. - imem_read: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - imem_ack <= '0'; - else - if to_integer(unsigned(imem_address)) > IMEM_END then - imem_data_in <= (others => 'X'); - else - 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)) + 1) - & imem_memory(to_integer(unsigned(imem_address)) + 0); - end if; - - imem_ack <= '1'; - end if; - end if; - end process imem_read; - - --! Data memory read process. - dmem_read: process(clk) - begin - if rising_edge(clk) then - if dmem_read_ack = '1' then - dmem_read_ack <= '0'; - elsif dmem_read_req = '1' then - case dmem_data_size is - when b"00" => -- 32 bits - 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) + 1)) - & dmem_memory(to_integer(unsigned(dmem_address) + 0)); - when b"10" => -- 16 bits - 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); - when b"01" => -- 8 bits - dmem_data_in(7 downto 0) <= dmem_memory(to_integer(unsigned(dmem_address))); - when others => - end case; - dmem_read_ack <= '1'; - end if; - end if; - end process dmem_read; - - stimulus: process - begin - wait until initialized = true; - report "Testbench initialized, starting behavioural simulation..." severity NOTE; - wait for clk_period * 2; - - -- Release the processor from reset: - reset <= '0'; - wait for clk_period; - - wait until tohost_write_en = '1'; - wait for clk_period; -- Let the signal "settle", because of clock edges - if tohost_data = x"00000001" then - report "Success!" severity NOTE; - else - report "Failure in test " & integer'image(to_integer(shift_right(unsigned(tohost_data), 1))) & "!" severity NOTE; - end if; - - simulation_finished <= true; - wait; - end process stimulus; - -end architecture testbench; Index: new-privileged-isa/testbenches/tb_soc_uart.vhd =================================================================== --- new-privileged-isa/testbenches/tb_soc_uart.vhd (revision 57) +++ new-privileged-isa/testbenches/tb_soc_uart.vhd (nonexistent) @@ -1,95 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; - -entity tb_soc_uart is -end entity tb_soc_uart; - -architecture testbench of tb_soc_uart is - - -- Clock signal: - signal clk : std_logic := '0'; - constant clk_period : time := 10 ns; - - -- Reset signal: - signal reset : std_logic := '1'; - - -- UART ports: - signal txd : std_logic; - signal rxd : std_logic := '1'; - - -- interrupt signals: - signal irq_send_buffer_empty : std_logic; - signal irq_data_received : std_logic; - - -- Wishbone ports: - signal wb_adr_in : std_logic_vector(1 downto 0) := (others => '0'); - signal wb_dat_in : std_logic_vector(7 downto 0) := (others => '0'); - signal wb_dat_out : std_logic_vector(7 downto 0); - signal wb_we_in : std_logic := '0'; - signal wb_cyc_in : std_logic := '0'; - signal wb_stb_in : std_logic := '0'; - signal wb_ack_out : std_logic; - -begin - - uut: entity work.pp_soc_uart - port map( - clk => clk, - reset => reset, - txd => txd, - rxd => rxd, - irq_send_buffer_empty => irq_send_buffer_empty, - irq_data_received => irq_data_received, - wb_adr_in => wb_adr_in, - wb_dat_in => wb_dat_in, - wb_dat_out => wb_dat_out, - wb_we_in => wb_we_in, - wb_cyc_in => wb_cyc_in, - wb_stb_in => wb_stb_in, - wb_ack_out => wb_ack_out - ); - - -- Set up an internal loopback: - rxd <= txd; - - clock: process - begin - clk <= '1'; - wait for clk_period / 2; - clk <= '0'; - wait for clk_period / 2; - end process clock; - - stimulus: process - begin - wait for clk_period * 2; - reset <= '0'; - - -- Write a 'P' (for Potato the Processor) to the UART: - wb_adr_in <= b"00"; - wb_dat_in <= x"50"; - wb_we_in <= '1'; - wb_cyc_in <= '1'; - wb_stb_in <= '1'; - - wait until wb_ack_out = '1'; - wait for clk_period; - wb_stb_in <= '0'; - wait for clk_period; - - -- Write an 'o': - wb_dat_in <= x"6f"; - wb_stb_in <= '1'; - wait until wb_ack_out = '1'; - wait for clk_period; - wb_stb_in <= '0'; - wait for clk_period; - - wait; - end process stimulus; - -end architecture testbench; Index: new-privileged-isa/testbenches/tb_soc_gpio.vhd =================================================================== --- new-privileged-isa/testbenches/tb_soc_gpio.vhd (revision 57) +++ new-privileged-isa/testbenches/tb_soc_gpio.vhd (nonexistent) @@ -1,91 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; - -entity tb_soc_gpio is -end entity tb_soc_gpio; - -architecture testbench of tb_soc_gpio is - - -- Clock signal: - signal clk : std_logic := '0'; - constant clk_period : time := 10 ns; - - -- Reset signal: - signal reset : std_logic := '1'; - - -- GPIOs: - signal gpio : std_logic_vector(31 downto 0); - - -- Wishbone bus: - signal wb_adr_in : std_logic_vector( 1 downto 0) := (others => '0'); - signal wb_dat_in : std_logic_vector(31 downto 0) := (others => '0'); - signal wb_dat_out : std_logic_vector(31 downto 0); - signal wb_cyc_in : std_logic := '0'; - signal wb_stb_in : std_logic := '0'; - signal wb_we_in : std_logic := '0'; - signal wb_ack_out : std_logic; -begin - - uut: entity work.pp_soc_gpio - generic map( - NUM_GPIOS => 32 - ) port map( - clk => clk, - reset => reset, - gpio => gpio, - wb_adr_in => wb_adr_in, - wb_dat_in => wb_dat_in, - wb_dat_out => wb_dat_out, - wb_cyc_in => wb_cyc_in, - wb_stb_in => wb_stb_in, - wb_we_in => wb_we_in, - wb_ack_out => wb_ack_out - ); - - clock: process - begin - clk <= '1'; - wait for clk_period / 2; - clk <= '0'; - wait for clk_period / 2; - end process clock; - - stimulus: process - begin - wait for clk_period * 2; - reset <= '0'; - - -- Set the upper half of the GPIOs as inputs, the rest as outputs: - wb_dat_in <= x"0000ffff"; - wb_adr_in <= b"10"; - wb_we_in <= '1'; - wb_cyc_in <= '1'; - wb_stb_in <= '1'; - wait until wb_ack_out = '1'; - wait for clk_period; - wb_stb_in <= '0'; - wb_cyc_in <= '0'; - wb_we_in <= '0'; - wait for clk_period; - - -- Set the outputs to aa, see if the upper half gets ignored correctly: - wb_dat_in <= x"aaaaaaaa"; - wb_adr_in <= b"01"; - wb_we_in <= '1'; - wb_cyc_in <= '1'; - wb_stb_in <= '1'; - wait until wb_ack_out = '1'; - wait for clk_period; - wb_stb_in <= '0'; - wb_cyc_in <= '0'; - wb_we_in <= '0'; - wait for clk_period; - - wait; - end process stimulus; - -end architecture testbench; Index: new-privileged-isa/testbenches/tb_soc.vhd =================================================================== --- new-privileged-isa/testbenches/tb_soc.vhd (revision 57) +++ new-privileged-isa/testbenches/tb_soc.vhd (nonexistent) @@ -1,316 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use ieee.std_logic_textio.all; -use std.textio.all; - -use work.pp_constants.all; -use work.pp_utilities.all; - ---! @brief Testbench providing a full SoC architecture connected with a Wishbone bus. -entity tb_soc is - generic( - IMEM_SIZE : natural := 4096; --! Size of the instruction 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. - DMEM_FILENAME : string := "dmem_testfile.hex" --! File containing the contents of data memory. - ); -end entity tb_soc; - -architecture testbench of tb_soc is - - -- Clock signals: - signal clk : std_logic; - constant clk_period : time := 10 ns; - - signal timer_clk : std_logic; - constant timer_clk_period : time := 100 ns; - - -- Reset: - signal reset : std_logic := '1'; - - -- Interrupts: - signal irq : std_logic_vector(7 downto 0) := (others => '0'); - - -- HTIF: - signal fromhost_data, tohost_data : std_logic_vector(31 downto 0); - signal fromhost_updated : std_logic := '0'; - signal tohost_updated : std_logic; - - -- Instruction memory signals: - 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_out : std_logic_vector(31 downto 0); - signal imem_cyc_in : std_logic; - signal imem_stb_in : std_logic; - signal imem_sel_in : std_logic_vector(3 downto 0); - signal imem_we_in : std_logic; - signal imem_ack_out : std_logic; - - -- Data memory signals: - 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_out : std_logic_vector(31 downto 0); - signal dmem_cyc_in : std_logic; - signal dmem_stb_in : std_logic; - signal dmem_sel_in : std_logic_vector(3 downto 0); - signal dmem_we_in : std_logic; - signal dmem_ack_out : std_logic; - - -- Processor signals: - signal p_adr_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_cyc_out : std_logic; - signal p_stb_out : std_logic; - signal p_sel_out : std_logic_vector(3 downto 0); - signal p_we_out : std_logic; - signal p_ack_in : std_logic; - - -- Arbitrated wishbone signals: - signal wb_adr : 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_cyc : std_logic; - signal wb_stb : std_logic; - signal wb_we : std_logic; - - -- Initialization "module" signals: - 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_cyc_out : std_logic := '0'; - signal init_stb_out : std_logic := '0'; - signal init_we_out : std_logic := '1'; - - -- Processor reset signals: - signal processor_reset : std_logic := '1'; - - -- Simulation control: - signal initialized : boolean := false; - signal simulation_finished : boolean := false; - -begin - - processor: entity work.pp_potato - generic map( - RESET_ADDRESS => RESET_ADDRESS - ) port map( - clk => clk, - reset => processor_reset, - timer_clk => timer_clk, - irq => irq, - fromhost_data => fromhost_data, - fromhost_updated => fromhost_updated, - tohost_data => tohost_data, - tohost_updated => tohost_updated, - wb_adr_out => p_adr_out, - wb_sel_out => p_sel_out, - wb_cyc_out => p_cyc_out, - wb_stb_out => p_stb_out, - wb_we_out => p_we_out, - wb_dat_out => p_dat_out, - wb_dat_in => p_dat_in, - wb_ack_in => p_ack_in - ); - - imem: entity work.pp_soc_memory - generic map( - MEMORY_SIZE => IMEM_SIZE - ) port map( - clk => clk, - reset => reset, - wb_adr_in => imem_adr_in, - wb_dat_in => imem_dat_in, - wb_dat_out => imem_dat_out, - wb_cyc_in => imem_cyc_in, - wb_stb_in => imem_stb_in, - wb_sel_in => imem_sel_in, - wb_we_in => imem_we_in, - wb_ack_out => imem_ack_out - ); - - dmem: entity work.pp_soc_memory - generic map( - MEMORY_SIZE => DMEM_SIZE - ) port map( - clk => clk, - reset => reset, - wb_adr_in => dmem_adr_in, - wb_dat_in => dmem_dat_in, - wb_dat_out => dmem_dat_out, - wb_cyc_in => dmem_cyc_in, - wb_stb_in => dmem_stb_in, - wb_sel_in => dmem_sel_in, - wb_we_in => dmem_we_in, - wb_ack_out => dmem_ack_out - ); - - imem_adr_in <= wb_adr(imem_adr_in'range); - imem_dat_in <= wb_dat; - imem_we_in <= wb_we; - imem_sel_in <= wb_sel; - dmem_adr_in <= wb_adr(dmem_adr_in'range); - dmem_dat_in <= wb_dat; - dmem_we_in <= wb_we; - dmem_sel_in <= wb_sel; - - address_decoder: process(wb_adr, imem_dat_out, imem_ack_out, dmem_dat_out, dmem_ack_out, - wb_cyc, wb_stb) - begin - if to_integer(unsigned(wb_adr)) < IMEM_SIZE then - p_dat_in <= imem_dat_out; - p_ack_in <= imem_ack_out; - imem_cyc_in <= wb_cyc; - imem_stb_in <= wb_stb; - dmem_cyc_in <= '0'; - dmem_stb_in <= '0'; - else - p_dat_in <= dmem_dat_out; - p_ack_in <= dmem_ack_out; - dmem_cyc_in <= wb_cyc; - dmem_stb_in <= wb_stb; - imem_cyc_in <= '0'; - imem_stb_in <= '0'; - end if; - end process address_decoder; - - 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) - begin - if not initialized then - wb_adr <= init_adr_out; - wb_dat <= init_dat_out; - wb_cyc <= init_cyc_out; - wb_stb <= init_stb_out; - wb_we <= init_we_out; - wb_sel <= x"f"; - else - wb_adr <= p_adr_out; - wb_dat <= p_dat_out; - wb_cyc <= p_cyc_out; - wb_stb <= p_stb_out; - wb_we <= p_we_out; - wb_sel <= p_sel_out; - end if; - end process arbiter; - - initializer: process - file imem_file : text open READ_MODE is IMEM_FILENAME; - file dmem_file : text open READ_MODE is DMEM_FILENAME; - variable input_line : line; - variable input_index : natural; - variable input_value : std_logic_vector(31 downto 0); - variable temp : std_logic_vector(31 downto 0); - - constant DMEM_START_ADDR : natural := IMEM_SIZE; - begin - if not initialized then - -- Read the instruction memory file: - for i in 0 to (IMEM_SIZE / 4) - 1 loop - exit when endfile(imem_file); - - readline(imem_file, input_line); - hread(input_line, input_value); - - 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_cyc_out <= '1'; - init_stb_out <= '1'; - wait until imem_ack_out = '1'; - wait for clk_period; - init_stb_out <= '0'; - wait until imem_ack_out = '0'; - wait for clk_period; - end loop; - - init_cyc_out <= '0'; - init_stb_out <= '0'; - wait for clk_period; - - -- Read the data memory file: - for i in 0 to (DMEM_SIZE / 4) - 1 loop - exit when endfile(dmem_file); - - readline(dmem_file, input_line); - hread(input_line, input_value); - - -- Swap endianness, TODO: prevent this, fix scripts/extract_hex.sh - temp(7 downto 0) := input_value(31 downto 24); - temp(15 downto 8) := input_value(23 downto 16); - temp(23 downto 16) := input_value(15 downto 8); - temp(31 downto 24) := input_value(7 downto 0); - - input_value := temp; - - init_adr_out <= std_logic_vector(to_unsigned(DMEM_START_ADDR + (i * 4), init_adr_out'length)); - init_dat_out <= input_value; - init_cyc_out <= '1'; - init_stb_out <= '1'; - wait until dmem_ack_out = '1'; - wait for clk_period; - init_stb_out <= '0'; - wait until dmem_ack_out = '0'; - wait for clk_period; - end loop; - - init_cyc_out <= '0'; - init_stb_out <= '0'; - wait for clk_period; - - initialized <= true; - wait; - end if; - end process initializer; - - clock: process - begin - clk <= '1'; - wait for clk_period / 2; - clk <= '0'; - wait for clk_period / 2; - - if simulation_finished then - wait; - end if; - 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 - begin - wait for clk_period * 2; - reset <= '0'; - - wait until initialized; - processor_reset <= '0'; - - wait until tohost_updated = '1'; - wait for clk_period; -- Let the signal "settle", because of stupid clock edges - if tohost_data = x"00000001" then - report "Success!" severity NOTE; - else - report "Failure in test " & integer'image(to_integer(shift_right(unsigned(tohost_data), 1))) & "!" severity NOTE; - end if; - - simulation_finished <= true; - wait; - end process stimulus; - -end architecture testbench; Index: new-privileged-isa/testbenches/tb_soc_timer.vhd =================================================================== --- new-privileged-isa/testbenches/tb_soc_timer.vhd (revision 57) +++ new-privileged-isa/testbenches/tb_soc_timer.vhd (nonexistent) @@ -1,108 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; - -entity tb_soc_timer is -end entity tb_soc_timer; - -architecture behaviour of tb_soc_timer is - - -- Clock signal: - signal clk : std_logic := '0'; - constant clk_period : time := 10 ns; - - -- Reset signal: - signal reset : std_logic := '1'; - - -- IRQ signal: - signal irq : std_logic; - - -- Wishbone interface: - signal wb_adr_in : std_logic_vector(1 downto 0) := (others => '0'); - signal wb_dat_in : std_logic_vector(31 downto 0) := (others => '0'); - signal wb_dat_out : std_logic_vector(31 downto 0); - signal wb_cyc_in : std_logic := '0'; - signal wb_stb_in : std_logic := '0'; - signal wb_we_in : std_logic := '0'; - signal wb_ack_out : std_logic; - -begin - - uut: entity work.pp_soc_timer - port map( - clk => clk, - reset => reset, - irq => irq, - wb_adr_in => wb_adr_in, - wb_dat_in => wb_dat_in, - wb_dat_out => wb_dat_out, - wb_cyc_in => wb_cyc_in, - wb_stb_in => wb_stb_in, - wb_we_in => wb_we_in, - wb_ack_out => wb_ack_out - ); - - clock: process - begin - clk <= '1'; - wait for clk_period / 2; - clk <= '0'; - wait for clk_period / 2; - end process clock; - - stimulus: process - begin - wait for clk_period * 2; - reset <= '0'; - - wait for clk_period; - - -- Set the compare register to 50: - wb_cyc_in <= '1'; - wb_stb_in <= '1'; - wb_adr_in <= b"01"; - wb_dat_in <= x"00000032"; - wb_we_in <= '1'; - wait until wb_ack_out = '1'; - wait for clk_period; - - wb_stb_in <= '0'; - wait for clk_period; - - -- Start the timer: - wb_stb_in <= '1'; - wb_adr_in <= b"00"; - wb_dat_in <= x"00000003"; - wait until wb_ack_out = '1'; - wait for clk_period; - - wb_stb_in <= '0'; - wb_cyc_in <= '0'; - wb_we_in <= '0'; - wait for clk_period; - - -- Wait for the interrupt: - wait until irq = '1'; - wait for clk_period; - - -- Reset the interrupt: - wb_cyc_in <= '1'; - wb_stb_in <= '1'; - wb_we_in <= '1'; - wb_adr_in <= b"00"; - wb_dat_in <= x"00000003"; - wait until wb_ack_out = '1'; - wait for clk_period; - - wb_stb_in <= '0'; - wb_cyc_in <= '0'; - wb_we_in <= '0'; - wait for clk_period; - - wait; - end process stimulus; - -end architecture behaviour; Index: new-privileged-isa/src/pp_execute.vhd =================================================================== --- new-privileged-isa/src/pp_execute.vhd (revision 57) +++ new-privileged-isa/src/pp_execute.vhd (nonexistent) @@ -1,541 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.pp_types.all; -use work.pp_csr.all; -use work.pp_utilities.all; - -entity pp_execute is - port( - clk : in std_logic; - reset : in std_logic; - - stall, flush : in std_logic; - - -- Interrupt inputs: - irq : in std_logic_vector(7 downto 0); - software_interrupt, timer_interrupt : in std_logic; - - -- Data memory outputs: - dmem_address : out std_logic_vector(31 downto 0); - dmem_data_out : out std_logic_vector(31 downto 0); - dmem_data_size : out std_logic_vector( 1 downto 0); - dmem_read_req : out std_logic; - dmem_write_req : out std_logic; - - -- Register addresses: - rs1_addr_in, rs2_addr_in, rd_addr_in : in register_address; - rd_addr_out : out register_address; - - -- Register values: - rs1_data_in, rs2_data_in : in std_logic_vector(31 downto 0); - rd_data_out : out std_logic_vector(31 downto 0); - - -- Constant values: - shamt_in : in std_logic_vector(4 downto 0); - immediate_in : in std_logic_vector(31 downto 0); - - -- Instruction address: - pc_in : in std_logic_vector(31 downto 0); - pc_out : out std_logic_vector(31 downto 0); - - -- Funct3 value from the instruction, used to choose which comparison - -- is used when branching: - funct3_in : in std_logic_vector(2 downto 0); - - -- CSR signals: - csr_addr_in : in csr_address; - csr_addr_out : out csr_address; - csr_write_in : in csr_write_mode; - csr_write_out : out csr_write_mode; - csr_value_in : in std_logic_vector(31 downto 0); - csr_value_out : out std_logic_vector(31 downto 0); - csr_writeable_in : in boolean; - csr_use_immediate_in : in std_logic; - - -- Control signals: - alu_op_in : in alu_operation; - alu_x_src_in : in alu_operand_source; - alu_y_src_in : in alu_operand_source; - rd_write_in : in std_logic; - rd_write_out : out std_logic; - branch_in : in branch_type; - branch_out : out branch_type; - - -- Memory control signals: - mem_op_in : in memory_operation_type; - mem_op_out : out memory_operation_type; - mem_size_in : in memory_operation_size; - mem_size_out : out memory_operation_size; - - -- Whether the instruction should be counted: - count_instruction_in : in std_logic; - count_instruction_out : out std_logic; - - -- Exception control registers: - ie_in, ie1_in : in std_logic; - mie_in : in std_logic_vector(31 downto 0); - mtvec_in : in std_logic_vector(31 downto 0); - mtvec_out : out std_logic_vector(31 downto 0); - --mepc_in : in std_logic_vector(31 downto 0); - - -- Exception signals: - decode_exception_in : in std_logic; - decode_exception_cause_in : in csr_exception_cause; - - -- Exception outputs: - exception_out : out std_logic; - exception_context_out : out csr_exception_context; - - -- Control outputs: - jump_out : out std_logic; - jump_target_out : out std_logic_vector(31 downto 0); - - -- Inputs to the forwarding logic from the MEM stage: - mem_rd_write : in std_logic; - mem_rd_addr : in register_address; - mem_rd_value : in std_logic_vector(31 downto 0); - mem_csr_addr : in csr_address; - mem_csr_write : in csr_write_mode; - mem_csr_value : in std_logic_vector(31 downto 0); - mem_exception : in std_logic; - mem_exception_context : in csr_exception_context; - - -- Inputs to the forwarding logic from the WB stage: - wb_rd_write : in std_logic; - wb_rd_addr : in register_address; - wb_rd_value : in std_logic_vector(31 downto 0); - wb_csr_addr : in csr_address; - wb_csr_write : in csr_write_mode; - wb_csr_value : in std_logic_vector(31 downto 0); - wb_exception : in std_logic; - wb_exception_context : in csr_exception_context; - - -- Hazard detection unit signals: - mem_mem_op : in memory_operation_type; - hazard_detected : out std_logic - ); -end entity pp_execute; - -architecture behaviour of pp_execute is - signal alu_op : alu_operation; - signal alu_x_src, alu_y_src : alu_operand_source; - - signal alu_x, alu_y, alu_result : std_logic_vector(31 downto 0); - - signal rs1_addr, rs2_addr : register_address; - signal rs1_data, rs2_data : std_logic_vector(31 downto 0); - - signal mem_op : memory_operation_type; - signal mem_size : memory_operation_size; - - signal pc : std_logic_vector(31 downto 0); - signal immediate : std_logic_vector(31 downto 0); - signal shamt : std_logic_vector( 4 downto 0); - signal funct3 : std_logic_vector( 2 downto 0); - - signal rs1_forwarded, rs2_forwarded : std_logic_vector(31 downto 0); - - signal branch : branch_type; - signal branch_condition : std_logic; - signal do_jump : std_logic; - signal jump_target : std_logic_vector(31 downto 0); - - signal mtvec, mtvec_forwarded : std_logic_vector(31 downto 0); - signal mie, mie_forwarded : std_logic_vector(31 downto 0); - - signal csr_write : csr_write_mode; - signal csr_addr : csr_address; - signal csr_use_immediate : std_logic; - signal csr_writeable : boolean; - - signal csr_value, csr_value_forwarded : std_logic_vector(31 downto 0); - - signal decode_exception : std_logic; - signal decode_exception_cause : csr_exception_cause; - - signal exception_taken : std_logic; - signal exception_cause : csr_exception_cause; - signal exception_addr : std_logic_vector(31 downto 0); - - signal exception_context_forwarded : csr_exception_context; - - signal data_misaligned, instr_misaligned : std_logic; - - signal irq_asserted : std_logic; - signal irq_asserted_num : std_logic_vector(3 downto 0); -begin - - -- Register values should not be latched in by a clocked process, - -- this is already done in the register files. - csr_value <= csr_value_in; - rd_data_out <= alu_result; - - branch_out <= branch; - - mem_op_out <= mem_op; - mem_size_out <= mem_size; - - csr_write_out <= csr_write; - csr_addr_out <= csr_addr; - - pc_out <= pc; - - exception_out <= exception_taken; - exception_context_out <= ( - ie => exception_context_forwarded.ie, - ie1 => exception_context_forwarded.ie1, - cause => exception_cause, - badaddr => exception_addr - ) when exception_taken = '1' else exception_context_forwarded; - - do_jump <= (to_std_logic(branch = BRANCH_JUMP or branch = BRANCH_JUMP_INDIRECT) - or (to_std_logic(branch = BRANCH_CONDITIONAL) and branch_condition) - or to_std_logic(branch = BRANCH_SRET)) and not stall; - jump_out <= do_jump; - jump_target_out <= jump_target; - - mtvec_out <= std_logic_vector(unsigned(mtvec_forwarded) + CSR_MTVEC_M_OFFSET); - exception_taken <= not stall and (decode_exception or to_std_logic(exception_cause /= CSR_CAUSE_NONE)); - - irq_asserted <= to_std_logic(exception_context_forwarded.ie = '1' and (irq and mie_forwarded(31 downto 24)) /= x"00"); - - rs1_data <= rs1_data_in; - rs2_data <= rs2_data_in; - - dmem_address <= alu_result when (mem_op /= MEMOP_TYPE_NONE and mem_op /= MEMOP_TYPE_INVALID) and exception_taken = '0' - else (others => '0'); - dmem_data_out <= rs2_forwarded; - dmem_write_req <= '1' when mem_op = MEMOP_TYPE_STORE and exception_taken = '0' else '0'; - dmem_read_req <= '1' when memop_is_load(mem_op) and exception_taken = '0' else '0'; - - pipeline_register: process(clk) - begin - if rising_edge(clk) then - if reset = '1' or flush = '1' then - rd_write_out <= '0'; - branch <= BRANCH_NONE; - csr_write <= CSR_WRITE_NONE; - mem_op <= MEMOP_TYPE_NONE; - decode_exception <= '0'; - count_instruction_out <= '0'; - elsif stall = '0' then - pc <= pc_in; - count_instruction_out <= count_instruction_in; - - -- Register signals: - rd_write_out <= rd_write_in; - rd_addr_out <= rd_addr_in; - rs1_addr <= rs1_addr_in; - rs2_addr <= rs2_addr_in; - - -- ALU signals: - alu_op <= alu_op_in; - alu_x_src <= alu_x_src_in; - alu_y_src <= alu_y_src_in; - - -- Control signals: - branch <= branch_in; - mem_op <= mem_op_in; - mem_size <= mem_size_in; - - -- Constant values: - immediate <= immediate_in; - shamt <= shamt_in; - funct3 <= funct3_in; - - -- CSR signals: - csr_write <= csr_write_in; - csr_addr <= csr_addr_in; - csr_use_immediate <= csr_use_immediate_in; - csr_writeable <= csr_writeable_in; - - -- Exception vector base: - mtvec <= mtvec_in; - mie <= mie_in; - - -- Instruction decoder exceptions: - decode_exception <= decode_exception_in; - decode_exception_cause <= decode_exception_cause_in; - end if; - end if; - end process pipeline_register; - - set_data_size: process(mem_size) - begin - case mem_size is - when MEMOP_SIZE_BYTE => - dmem_data_size <= b"01"; - when MEMOP_SIZE_HALFWORD => - dmem_data_size <= b"10"; - when MEMOP_SIZE_WORD => - dmem_data_size <= b"00"; - when others => - dmem_data_size <= b"11"; - end case; - end process set_data_size; - - get_irq_num: process(irq, exception_context_forwarded, mie_forwarded) - variable temp : std_logic_vector(3 downto 0); - begin - temp := (others => '0'); - - for i in 0 to 7 loop - if irq(i) = '1' and mie_forwarded(24 + i) = '1' then - temp := std_logic_vector(to_unsigned(i, temp'length)); - exit; - end if; - end loop; - - irq_asserted_num <= temp; - end process get_irq_num; - - data_misalign_check: process(mem_size, alu_result) - begin - case mem_size is - when MEMOP_SIZE_HALFWORD => - if alu_result(0) /= '0' then - data_misaligned <= '1'; - else - data_misaligned <= '0'; - end if; - when MEMOP_SIZE_WORD => - if alu_result(1 downto 0) /= b"00" then - data_misaligned <= '1'; - else - data_misaligned <= '0'; - end if; - when others => - data_misaligned <= '0'; - end case; - end process data_misalign_check; - - instr_misalign_check: process(jump_target, branch, branch_condition, do_jump) - begin - if jump_target(1 downto 0) /= b"00" and do_jump = '1' then - instr_misaligned <= '1'; - else - instr_misaligned <= '0'; - end if; - end process instr_misalign_check; - - find_exception_cause: process(decode_exception, decode_exception_cause, mem_op, - data_misaligned, instr_misaligned, irq_asserted, irq_asserted_num, mie_forwarded, - software_interrupt, timer_interrupt, exception_context_forwarded) - begin - if irq_asserted = '1' then - exception_cause <= std_logic_vector(unsigned(CSR_CAUSE_IRQ_BASE) + unsigned(irq_asserted_num)); - elsif software_interrupt = '1' and mie_forwarded(CSR_MIE_MSIE) = '1' and exception_context_forwarded.ie = '1' then - exception_cause <= CSR_CAUSE_SOFTWARE_INT; - elsif timer_interrupt = '1' and mie_forwarded(CSR_MIE_MTIE) = '1' and exception_context_forwarded.ie = '1' then - exception_cause <= CSR_CAUSE_TIMER_INT; - elsif decode_exception = '1' then - exception_cause <= decode_exception_cause; - elsif mem_op = MEMOP_TYPE_INVALID then - exception_cause <= CSR_CAUSE_INVALID_INSTR; - elsif instr_misaligned = '1' then - exception_cause <= CSR_CAUSE_INSTR_MISALIGN; - elsif data_misaligned = '1' and mem_op = MEMOP_TYPE_STORE then - exception_cause <= CSR_CAUSE_STORE_MISALIGN; - elsif data_misaligned = '1' and memop_is_load(mem_op) then - exception_cause <= CSR_CAUSE_LOAD_MISALIGN; - else - exception_cause <= CSR_CAUSE_NONE; - end if; - end process find_exception_cause; - - find_exception_addr: process(instr_misaligned, data_misaligned, jump_target, alu_result) - begin - if instr_misaligned = '1' then - exception_addr <= jump_target; - elsif data_misaligned = '1' then - exception_addr <= alu_result; - else - exception_addr <= (others => '0'); - end if; - end process find_exception_addr; - - calc_jump_tgt: process(branch, pc, rs1_forwarded, immediate, csr_value_forwarded) - begin - case branch is - when BRANCH_JUMP | BRANCH_CONDITIONAL => - jump_target <= std_logic_vector(unsigned(pc) + unsigned(immediate)); - when BRANCH_JUMP_INDIRECT => - jump_target <= std_logic_vector(unsigned(rs1_forwarded) + unsigned(immediate)); - when BRANCH_SRET => - jump_target <= csr_value_forwarded; - when others => - jump_target <= (others => '0'); - end case; - end process calc_jump_tgt; - - alu_x_mux: entity work.pp_alu_mux - port map( - source => alu_x_src, - register_value => rs1_forwarded, - immediate_value => immediate, - shamt_value => shamt, - pc_value => pc, - csr_value => csr_value_forwarded, - output => alu_x - ); - - alu_y_mux: entity work.pp_alu_mux - port map( - source => alu_y_src, - register_value => rs2_forwarded, - immediate_value => immediate, - shamt_value => shamt, - pc_value => pc, - csr_value => csr_value_forwarded, - output => alu_y - ); - - alu_x_forward: process(mem_rd_write, mem_rd_value, mem_rd_addr, rs1_addr, - rs1_data, wb_rd_write, wb_rd_addr, wb_rd_value) - begin - if mem_rd_write = '1' and mem_rd_addr = rs1_addr and mem_rd_addr /= b"00000" then - rs1_forwarded <= mem_rd_value; - elsif wb_rd_write = '1' and wb_rd_addr = rs1_addr and wb_rd_addr /= b"00000" then - rs1_forwarded <= wb_rd_value; - else - rs1_forwarded <= rs1_data; - end if; - end process alu_x_forward; - - alu_y_forward: process(mem_rd_write, mem_rd_value, mem_rd_addr, rs2_addr, - rs2_data, wb_rd_write, wb_rd_addr, wb_rd_value) - begin - if mem_rd_write = '1' and mem_rd_addr = rs2_addr and mem_rd_addr /= b"00000" then - rs2_forwarded <= mem_rd_value; - elsif wb_rd_write = '1' and wb_rd_addr = rs2_addr and wb_rd_addr /= b"00000" then - rs2_forwarded <= wb_rd_value; - else - rs2_forwarded <= rs2_data; - end if; - end process alu_y_forward; - - csr_forward: process(mem_csr_write, wb_csr_write, csr_addr, mem_csr_addr, wb_csr_addr, - csr_value, mem_csr_value, wb_csr_value, csr_writeable, mem_exception, wb_exception, - mem_exception_context, wb_exception_context) - begin - if csr_addr = CSR_MCAUSE and mem_exception = '1' then - csr_value_forwarded <= to_std_logic_vector(mem_exception_context.cause); - elsif csr_addr = CSR_MSTATUS and mem_exception = '1' then - csr_value_forwarded <= csr_make_mstatus(mem_exception_context.ie, mem_exception_context.ie1); - elsif csr_addr = CSR_MBADADDR and mem_exception = '1' then - csr_value_forwarded <= mem_exception_context.badaddr; - elsif mem_csr_write /= CSR_WRITE_NONE and mem_csr_addr = csr_addr and csr_writeable then - csr_value_forwarded <= mem_csr_value; - elsif csr_addr = CSR_MCAUSE and wb_exception = '1' then - csr_value_forwarded <= to_std_logic_vector(wb_exception_context.cause); - elsif csr_addr = CSR_MSTATUS and wb_exception = '1' then - csr_value_forwarded <= csr_make_mstatus(wb_exception_context.ie, wb_exception_context.ie1); - elsif csr_addr = CSR_MBADADDR and wb_exception = '1' then - csr_value_forwarded <= wb_exception_context.badaddr; - elsif wb_csr_write /= CSR_WRITE_NONE and wb_csr_addr = csr_addr and csr_writeable then - csr_value_forwarded <= wb_csr_value; - else - csr_value_forwarded <= csr_value; - end if; - end process csr_forward; - - mtvec_forward: process(mem_csr_write, mem_csr_addr, mem_csr_value, - wb_csr_write, wb_csr_addr, wb_csr_value, mtvec) - begin - if mem_csr_write /= CSR_WRITE_NONE and mem_csr_addr = CSR_MTVEC then - mtvec_forwarded <= mem_csr_value; - elsif wb_csr_write /= CSR_WRITE_NONE and wb_csr_addr = CSR_MTVEC then - mtvec_forwarded <= wb_csr_value; - else - mtvec_forwarded <= mtvec; - end if; - end process mtvec_forward; - - mie_forward: process(mem_csr_write, mem_csr_addr, mem_csr_value, - wb_csr_write, wb_csr_addr, wb_csr_value, mie) - begin - if mem_csr_write /= CSR_WRITE_NONE and mem_csr_addr = CSR_MIE then - mie_forwarded <= mem_csr_value; - elsif wb_csr_write /= CSR_WRITE_NONE and wb_csr_addr = CSR_MIE then - mie_forwarded <= wb_csr_value; - else - mie_forwarded <= mie; - end if; - end process mie_forward; - - exception_ctx_forward: process(mem_exception, wb_exception, mem_exception_context, wb_exception_context, - exception_cause, exception_addr, mem_csr_write, mem_csr_addr, mem_csr_value, - wb_csr_write, wb_csr_addr, wb_csr_value, ie_in, ie1_in) - begin - if mem_exception = '1' then - exception_context_forwarded <= mem_exception_context; - elsif mem_csr_write /= CSR_WRITE_NONE and mem_csr_addr = CSR_MSTATUS then - exception_context_forwarded <= ( - ie => mem_csr_value(CSR_SR_IE), - ie1 => mem_csr_value(CSR_SR_IE1), - cause => exception_cause, - badaddr => exception_addr); - elsif wb_exception = '1' then - exception_context_forwarded <= wb_exception_context; - elsif wb_csr_write /= CSR_WRITE_NONE and wb_csr_addr = CSR_MSTATUS then - exception_context_forwarded <= ( - ie => wb_csr_value(CSR_SR_IE), - ie1 => wb_csr_value(CSR_SR_IE1), - cause => exception_cause, - badaddr => exception_addr); - else - exception_context_forwarded.ie <= ie_in; - exception_context_forwarded.ie1 <= ie1_in; - exception_context_forwarded.cause <= exception_cause; - exception_context_forwarded.badaddr <= exception_addr; - end if; - end process exception_ctx_forward; - - detect_load_hazard: process(mem_mem_op, mem_rd_addr, rs1_addr, rs2_addr, - alu_x_src, alu_y_src) - begin - if (mem_mem_op = MEMOP_TYPE_LOAD or mem_mem_op = MEMOP_TYPE_LOAD_UNSIGNED) and - ((alu_x_src = ALU_SRC_REG and mem_rd_addr = rs1_addr and rs1_addr /= b"00000") - or - (alu_y_src = ALU_SRC_REG and mem_rd_addr = rs2_addr and rs2_addr /= b"00000")) - then - hazard_detected <= '1'; - else - hazard_detected <= '0'; - end if; - end process detect_load_hazard; - - branch_comparator: entity work.pp_comparator - port map( - funct3 => funct3, - rs1 => rs1_forwarded, - rs2 => rs2_forwarded, - result => branch_condition - ); - - alu_instance: entity work.pp_alu - port map( - result => alu_result, - x => alu_x, - y => alu_y, - operation => alu_op - ); - - csr_alu_instance: entity work.pp_csr_alu - port map( - x => csr_value_forwarded, - y => rs1_forwarded, - result => csr_value_out, - immediate => rs1_addr, - use_immediate => csr_use_immediate, - write_mode => csr_write - ); - - -end architecture behaviour; Index: new-privileged-isa/src/pp_types.vhd =================================================================== --- new-privileged-isa/src/pp_types.vhd (revision 57) +++ new-privileged-isa/src/pp_types.vhd (nonexistent) @@ -1,70 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; - -package pp_types is - - --! Type used for register addresses. - subtype register_address is std_logic_vector(4 downto 0); - - --! The available ALU operations. - type alu_operation is ( - ALU_AND, ALU_OR, ALU_XOR, - ALU_SLT, ALU_SLTU, - ALU_ADD, ALU_SUB, - ALU_SRL, ALU_SLL, ALU_SRA, - ALU_NOP, ALU_INVALID - ); - - --! Types of branches. - type branch_type is ( - BRANCH_NONE, BRANCH_JUMP, BRANCH_JUMP_INDIRECT, BRANCH_CONDITIONAL, BRANCH_SRET - ); - - --! Source of an ALU operand. - type alu_operand_source is ( - ALU_SRC_REG, ALU_SRC_IMM, ALU_SRC_SHAMT, ALU_SRC_PC, ALU_SRC_PC_NEXT, ALU_SRC_NULL, ALU_SRC_CSR - ); - - --! Type of memory operation: - type memory_operation_type is ( - MEMOP_TYPE_NONE, MEMOP_TYPE_INVALID, MEMOP_TYPE_LOAD, MEMOP_TYPE_LOAD_UNSIGNED, MEMOP_TYPE_STORE - ); - - -- Determines if a memory operation is a load: - function memop_is_load(input : in memory_operation_type) return boolean; - - --! Size of a memory operation: - type memory_operation_size is ( - MEMOP_SIZE_BYTE, MEMOP_SIZE_HALFWORD, MEMOP_SIZE_WORD - ); - - --! Wishbone master output signals: - type wishbone_master_outputs is record - adr : std_logic_vector(31 downto 0); - sel : std_logic_vector( 3 downto 0); - cyc : std_logic; - stb : std_logic; - we : std_logic; - dat : std_logic_vector(31 downto 0); - end record; - - --! Wishbone master input signals: - type wishbone_master_inputs is record - dat : std_logic_vector(31 downto 0); - ack : std_logic; - end record; - -end package pp_types; - -package body pp_types is - - function memop_is_load(input : in memory_operation_type) return boolean is - begin - return (input = MEMOP_TYPE_LOAD or input = MEMOP_TYPE_LOAD_UNSIGNED); - end function memop_is_load; - -end package body pp_types; Index: new-privileged-isa/src/pp_potato.vhd =================================================================== --- new-privileged-isa/src/pp_potato.vhd (revision 57) +++ new-privileged-isa/src/pp_potato.vhd (nonexistent) @@ -1,150 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; - -use work.pp_types.all; - ---! @brief The Potato Processor. ---! This file provides a Wishbone-compatible interface to the Potato processor. -entity pp_potato is - generic( - PROCESSOR_ID : std_logic_vector(31 downto 0) := x"00000000"; --! Processor ID. - RESET_ADDRESS : std_logic_vector(31 downto 0) := x"00000200" --! Address of the first instruction to execute. - ); - port( - clk : in std_logic; - timer_clk : in std_logic; - reset : in std_logic; - - -- Interrupts: - irq : in std_logic_vector(7 downto 0); - - -- Host/Target interface: - fromhost_data : in std_logic_vector(31 downto 0); - fromhost_updated : in std_logic; - tohost_data : out std_logic_vector(31 downto 0); - tohost_updated : out std_logic; - - -- Wishbone interface: - wb_adr_out : out std_logic_vector(31 downto 0); - wb_sel_out : out std_logic_vector( 3 downto 0); - wb_cyc_out : out std_logic; - wb_stb_out : out std_logic; - wb_we_out : out std_logic; - wb_dat_out : out std_logic_vector(31 downto 0); - wb_dat_in : in std_logic_vector(31 downto 0); - wb_ack_in : in std_logic - ); -end entity pp_potato; - -architecture behaviour of pp_potato is - - -- Instruction memory signals: - signal imem_address : std_logic_vector(31 downto 0); - signal imem_data : std_logic_vector(31 downto 0); - signal imem_req, imem_ack : std_logic; - - -- Data memory signals: - signal dmem_address : std_logic_vector(31 downto 0); - signal dmem_data_in : 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_read_req : std_logic; - signal dmem_read_ack : std_logic; - signal dmem_write_req : std_logic; - signal dmem_write_ack : std_logic; - - -- Wishbone signals: - signal icache_inputs, dmem_if_inputs : wishbone_master_inputs; - signal icache_outputs, dmem_if_outputs : wishbone_master_outputs; - -begin - processor: entity work.pp_core - generic map( - PROCESSOR_ID => PROCESSOR_ID, - RESET_ADDRESS => RESET_ADDRESS - ) port map( - clk => clk, - reset => reset, - timer_clk => timer_clk, - imem_address => imem_address, - imem_data_in => imem_data, - imem_req => imem_req, - imem_ack => imem_ack, - dmem_address => dmem_address, - dmem_data_in => dmem_data_in, - dmem_data_out => dmem_data_out, - dmem_data_size => dmem_data_size, - dmem_read_req => dmem_read_req, - dmem_read_ack => dmem_read_ack, - dmem_write_req => dmem_write_req, - dmem_write_ack => dmem_write_ack, - fromhost_data => fromhost_data, - fromhost_write_en => fromhost_updated, - tohost_data => tohost_data, - tohost_write_en => tohost_updated, - irq => irq - ); - - icache: entity work.pp_icache - generic map( - LINE_SIZE => 4, - NUM_LINES => 128 - ) port map( - clk => clk, - reset => reset, - cache_enable => '1', - cache_flush => '0', - cached_areas => (others => '1'), - mem_address_in => imem_address, - mem_data_out => imem_data, - mem_data_in => (others => '0'), - mem_data_size => b"00", - mem_read_req => imem_req, - mem_read_ack => imem_ack, - mem_write_req => '0', - mem_write_ack => open, - wb_inputs => icache_inputs, - wb_outputs => icache_outputs - ); - - dmem_if: entity work.pp_wb_adapter - port map( - clk => clk, - reset => reset, - dmem_address => dmem_address, - dmem_data_in => dmem_data_out, - dmem_data_out => dmem_data_in, - dmem_data_size => dmem_data_size, - dmem_read_req => dmem_read_req, - dmem_read_ack => dmem_read_ack, - dmem_write_req => dmem_write_req, - dmem_write_ack => dmem_write_ack, - wb_inputs => dmem_if_inputs, - wb_outputs => dmem_if_outputs - ); - - arbiter: entity work.pp_wb_arbiter - port map( - clk => clk, - reset => reset, - --m1_inputs => dmem_if_inputs, - --m1_outputs => dmem_if_outputs, - m1_inputs => icache_inputs, - m1_outputs => icache_outputs, - m2_inputs => dmem_if_inputs, - m2_outputs => dmem_if_outputs, - wb_adr_out => wb_adr_out, - wb_sel_out => wb_sel_out, - wb_cyc_out => wb_cyc_out, - wb_stb_out => wb_stb_out, - wb_we_out => wb_we_out, - wb_dat_out => wb_dat_out, - wb_dat_in => wb_dat_in, - wb_ack_in => wb_ack_in - ); - -end architecture behaviour; Index: new-privileged-isa/src/pp_comparator.vhd =================================================================== --- new-privileged-isa/src/pp_comparator.vhd (revision 57) +++ new-privileged-isa/src/pp_comparator.vhd (nonexistent) @@ -1,43 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.pp_utilities.all; - ---! @brief Component for comparing two registers in the ID stage whens branching. -entity pp_comparator is - port( - funct3 : in std_logic_vector(14 downto 12); - rs1, rs2 : in std_logic_vector(31 downto 0); - result : out std_logic --! Result of the comparison. - ); -end entity pp_comparator; - -architecture behaviour of pp_comparator is -begin - - compare: process(funct3, rs1, rs2) - begin - case funct3 is - when b"000" => -- EQ - result <= to_std_logic(rs1 = rs2); - when b"001" => -- NE - result <= to_std_logic(rs1 /= rs2); - when b"100" => -- LT - result <= to_std_logic(signed(rs1) < signed(rs2)); - when b"101" => -- GE - result <= to_std_logic(signed(rs1) >= signed(rs2)); - when b"110" => -- LTU - result <= to_std_logic(unsigned(rs1) < unsigned(rs2)); - when b"111" => -- GEU - result <= to_std_logic(unsigned(rs1) >= unsigned(rs2)); - when others => - result <= '0'; - end case; - end process compare; - -end architecture behaviour; Index: new-privileged-isa/src/pp_imm_decoder.vhd =================================================================== --- new-privileged-isa/src/pp_imm_decoder.vhd (revision 57) +++ new-privileged-isa/src/pp_imm_decoder.vhd (nonexistent) @@ -1,35 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; - ---! @brief Module decoding immediate values from instruction words. -entity pp_imm_decoder is - port( - instruction : in std_logic_vector(31 downto 2); - immediate : out std_logic_vector(31 downto 0) - ); -end entity pp_imm_decoder; - -architecture behaviour of pp_imm_decoder is -begin - decode: process(instruction) - begin - case instruction(6 downto 2) is - when b"01101" | b"00101" => -- U type - immediate <= instruction(31 downto 12) & (11 downto 0 => '0'); - when b"11011" => -- UJ type - immediate <= (31 downto 20 => instruction(31)) & instruction(19 downto 12) & instruction(20) & instruction(30 downto 21) & '0'; - when b"11001" | b"00000" | b"00100" | b"11100"=> -- I type - immediate <= (31 downto 11 => instruction(31)) & instruction(30 downto 20); - when b"11000" => -- SB type - immediate <= (31 downto 12 => instruction(31)) & instruction(7) & instruction(30 downto 25) & instruction(11 downto 8) & '0'; - when b"01000" => -- S type - immediate <= (31 downto 11 => instruction(31)) & instruction(30 downto 25) & instruction(11 downto 7); - when others => - immediate <= (others => '0'); - end case; - end process decode; -end architecture behaviour; Index: new-privileged-isa/src/pp_memory.vhd =================================================================== --- new-privileged-isa/src/pp_memory.vhd (revision 57) +++ new-privileged-isa/src/pp_memory.vhd (nonexistent) @@ -1,154 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.pp_types.all; -use work.pp_csr.all; -use work.pp_utilities.all; - -entity pp_memory is - port( - clk : in std_logic; - reset : in std_logic; - stall : in std_logic; - - -- Data memory inputs: - dmem_read_ack : in std_logic; - dmem_write_ack : in std_logic; - dmem_data_in : in std_logic_vector(31 downto 0); - - -- Current PC value: - pc : in std_logic_vector(31 downto 0); - - -- Destination register signals: - rd_write_in : in std_logic; - rd_write_out : out std_logic; - rd_data_in : in std_logic_vector(31 downto 0); - rd_data_out : out std_logic_vector(31 downto 0); - rd_addr_in : in register_address; - rd_addr_out : out register_address; - - -- Control signals: - branch : in branch_type; - mem_op_in : in memory_operation_type; - mem_size_in : in memory_operation_size; - mem_op_out : out memory_operation_type; - - -- Whether the instruction should be counted: - count_instr_in : in std_logic; - count_instr_out : out std_logic; - - -- Exception signals: - exception_in : in std_logic; - exception_out : out std_logic; - exception_context_in : in csr_exception_context; - exception_context_out : out csr_exception_context; - - -- CSR signals: - csr_addr_in : in csr_address; - csr_addr_out : out csr_address; - csr_write_in : in csr_write_mode; - csr_write_out : out csr_write_mode; - csr_data_in : in std_logic_vector(31 downto 0); - csr_data_out : out std_logic_vector(31 downto 0) - ); -end entity pp_memory; - -architecture behaviour of pp_memory is - signal mem_op : memory_operation_type; - signal mem_size : memory_operation_size; - - signal rd_data : std_logic_vector(31 downto 0); -begin - - mem_op_out <= mem_op; - - pipeline_register: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - rd_write_out <= '0'; - csr_write_out <= CSR_WRITE_NONE; - count_instr_out <= '0'; - mem_op <= MEMOP_TYPE_NONE; - elsif stall = '0' then - mem_size <= mem_size_in; - rd_data <= rd_data_in; - rd_addr_out <= rd_addr_in; - - if exception_in = '1' then - mem_op <= MEMOP_TYPE_NONE; - rd_write_out <= '0'; - csr_write_out <= CSR_WRITE_REPLACE; - csr_addr_out <= CSR_MEPC; - csr_data_out <= pc; - count_instr_out <= '0'; - else - mem_op <= mem_op_in; - rd_write_out <= rd_write_in; - csr_write_out <= csr_write_in; - csr_addr_out <= csr_addr_in; - csr_data_out <= csr_data_in; - count_instr_out <= count_instr_in; - end if; - end if; - end if; - end process pipeline_register; - - update_exception_context: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - exception_out <= '0'; - else - exception_out <= exception_in or to_std_logic(branch = BRANCH_SRET); - - if exception_in = '1' then - exception_context_out.ie <= '0'; - exception_context_out.ie1 <= exception_context_in.ie; - exception_context_out.cause <= exception_context_in.cause; - exception_context_out.badaddr <= exception_context_in.badaddr; - elsif branch = BRANCH_SRET then - exception_context_out.ie <= exception_context_in.ie1; - exception_context_out.ie1 <= exception_context_in.ie; - exception_context_out.cause <= CSR_CAUSE_NONE; - exception_context_out.badaddr <= (others => '0'); - else - exception_context_out.ie <= exception_context_in.ie; - exception_context_out.ie1 <= exception_context_in.ie1; - exception_context_out.cause <= CSR_CAUSE_NONE; - exception_context_out.badaddr <= (others => '0'); - end if; - end if; - end if; - end process update_exception_context; - - rd_data_mux: process(rd_data, dmem_data_in, mem_op, mem_size) - begin - if mem_op = MEMOP_TYPE_LOAD or mem_op = MEMOP_TYPE_LOAD_UNSIGNED then - case mem_size is - when MEMOP_SIZE_BYTE => - if mem_op = MEMOP_TYPE_LOAD_UNSIGNED then - rd_data_out <= std_logic_vector(resize(unsigned(dmem_data_in(7 downto 0)), rd_data_out'length)); - else - rd_data_out <= std_logic_vector(resize(signed(dmem_data_in(7 downto 0)), rd_data_out'length)); - end if; - when MEMOP_SIZE_HALFWORD => - if mem_op = MEMOP_TYPE_LOAD_UNSIGNED then - rd_data_out <= std_logic_vector(resize(unsigned(dmem_data_in(15 downto 0)), rd_data_out'length)); - else - rd_data_out <= std_logic_vector(resize(signed(dmem_data_in(15 downto 0)), rd_data_out'length)); - end if; - when MEMOP_SIZE_WORD => - rd_data_out <= dmem_data_in; - end case; - else - rd_data_out <= rd_data; - end if; - end process rd_data_mux; - -end architecture behaviour; Index: new-privileged-isa/src/pp_wb_adapter.vhd =================================================================== --- new-privileged-isa/src/pp_wb_adapter.vhd (revision 57) +++ new-privileged-isa/src/pp_wb_adapter.vhd (nonexistent) @@ -1,126 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.pp_types.all; -use work.pp_utilities.all; - ---! @brief Wishbone adapter, for connecting the processor to a Wishbone bus when not using caches. -entity pp_wb_adapter is - port( - clk : in std_logic; - reset : in std_logic; - - -- Processor data memory signals: - signal dmem_address : in std_logic_vector(31 downto 0); - signal dmem_data_in : in std_logic_vector(31 downto 0); -- Data in to the bus - signal dmem_data_out : out std_logic_vector(31 downto 0); -- Data out to the bus - signal dmem_data_size : in std_logic_vector( 1 downto 0); - signal dmem_read_req : in std_logic; - signal dmem_read_ack : out std_logic; - signal dmem_write_req : in std_logic; - signal dmem_write_ack : out std_logic; - - -- Wishbone interface: - wb_inputs : in wishbone_master_inputs; - wb_outputs : out wishbone_master_outputs - ); -end entity pp_wb_adapter; - -architecture behaviour of pp_wb_adapter is - - type states is (IDLE, READ_WAIT_ACK, WRITE_WAIT_ACK); - signal state : states; - - signal dmem_r_ack : std_logic; - - function get_data_shift(size : in std_logic_vector(1 downto 0); address : in std_logic_vector) - return natural is - begin - case size is - when b"01" => - case address(1 downto 0) is - when b"00" => - return 0; - when b"01" => - return 8; - when b"10" => - return 16; - when b"11" => - return 24; - when others => - return 0; - end case; - when b"10" => - if address(1) = '0' then - return 0; - else - return 16; - end if; - when others => - return 0; - end case; - end function get_data_shift; - -begin - - dmem_write_ack <= '1' when state = WRITE_WAIT_ACK and wb_inputs.ack = '1' else '0'; - dmem_read_ack <= dmem_r_ack; - - wishbone: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - state <= IDLE; - wb_outputs.cyc <= '0'; - wb_outputs.stb <= '0'; - dmem_r_ack <= '0'; - else - case state is - when IDLE => - dmem_r_ack <= '0'; - - -- Prioritize requests from the data memory: - if dmem_write_req = '1' then - wb_outputs.adr <= dmem_address; - wb_outputs.dat <= std_logic_vector(shift_left(unsigned(dmem_data_in), - get_data_shift(dmem_data_size, dmem_address))); - wb_outputs.sel <= wb_get_data_sel(dmem_data_size, dmem_address); - wb_outputs.cyc <= '1'; - wb_outputs.stb <= '1'; - wb_outputs.we <= '1'; - state <= WRITE_WAIT_ACK; - elsif dmem_read_req = '1' then - wb_outputs.adr <= dmem_address; - wb_outputs.sel <= wb_get_data_sel(dmem_data_size, dmem_address); - wb_outputs.cyc <= '1'; - wb_outputs.stb <= '1'; - wb_outputs.we <= '0'; - state <= READ_WAIT_ACK; - end if; - when READ_WAIT_ACK => - if wb_inputs.ack = '1' then - dmem_data_out <= std_logic_vector(shift_right(unsigned(wb_inputs.dat), - get_data_shift(dmem_data_size, dmem_address))); - wb_outputs.cyc <= '0'; - wb_outputs.stb <= '0'; - dmem_r_ack <= '1'; - state <= IDLE; - end if; - when WRITE_WAIT_ACK => - if wb_inputs.ack = '1' then - wb_outputs.cyc <= '0'; - wb_outputs.stb <= '0'; - wb_outputs.we <= '0'; - state <= IDLE; - end if; - end case; - end if; - end if; - end process wishbone; - -end architecture behaviour;
new-privileged-isa/src/pp_wb_adapter.vhd Property changes : Deleted: svn:mergeinfo ## -0,1 +0,0 ## Reverse-merged /potato/branches/cache-playground/src/pp_wb_adapter.vhd:r31-33,44 Index: new-privileged-isa/src/pp_alu_mux.vhd =================================================================== --- new-privileged-isa/src/pp_alu_mux.vhd (revision 57) +++ new-privileged-isa/src/pp_alu_mux.vhd (nonexistent) @@ -1,49 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.pp_types.all; - ---! @brief Multiplexer used to choose between ALU inputs. -entity pp_alu_mux is - port( - source : in alu_operand_source; - - register_value : in std_logic_vector(31 downto 0); - immediate_value : in std_logic_vector(31 downto 0); - shamt_value : in std_logic_vector( 4 downto 0); - pc_value : in std_logic_vector(31 downto 0); - csr_value : in std_logic_vector(31 downto 0); - - output : out std_logic_vector(31 downto 0) - ); -end entity pp_alu_mux; - -architecture behaviour of pp_alu_mux is -begin - - mux: process(source, register_value, immediate_value, shamt_value, pc_value, csr_value) - begin - case source is - when ALU_SRC_REG => - output <= register_value; - when ALU_SRC_IMM => - output <= immediate_value; - when ALU_SRC_PC => - output <= pc_value; - when ALU_SRC_PC_NEXT => - output <= std_logic_vector(unsigned(pc_value) + 4); - when ALU_SRC_CSR => - output <= csr_value; - when ALU_SRC_SHAMT => - output <= (31 downto 5 => '0') & shamt_value; - when ALU_SRC_NULL => - output <= (others => '0'); - end case; - end process mux; - -end architecture behaviour; Index: new-privileged-isa/src/pp_utilities.vhd =================================================================== --- new-privileged-isa/src/pp_utilities.vhd (revision 57) +++ new-privileged-isa/src/pp_utilities.vhd (nonexistent) @@ -1,94 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; - -use work.pp_types.all; -use work.pp_constants.all; - -package pp_utilities is - - --! Converts a boolean to an std_logic. - function to_std_logic(input : in boolean) return std_logic; - - -- Checks if a number is 2^n: - function is_pow2(input : in natural) return boolean; - - --! Calculates log2 with integers. - function log2(input : in natural) return natural; - - -- Gets the value of the sel signals to the wishbone interconnect for the specified - -- operand size and address. - function wb_get_data_sel(size : in std_logic_vector(1 downto 0); address : in std_logic_vector) - return std_logic_vector; - -end package pp_utilities; - -package body pp_utilities is - - function to_std_logic(input : in boolean) return std_logic is - begin - if input then - return '1'; - else - return '0'; - end if; - end function to_std_logic; - - function is_pow2(input : in natural) return boolean is - variable c : natural := 1; - begin - for i in 0 to 30 loop -- FIXME: Simulator complains about 2^31 being out of range! - if input = i then - return true; - end if; - - c := c * 2; - end loop; - - return false; - end function is_pow2; - - function log2(input : in natural) return natural is - variable retval : natural := 0; - variable temp : natural := input; - begin - while temp > 1 loop - retval := retval + 1; - temp := temp / 2; - end loop; - - return retval; - end function log2; - - function wb_get_data_sel(size : in std_logic_vector(1 downto 0); address : in std_logic_vector) - return std_logic_vector is - begin - case size is - when b"01" => - case address(1 downto 0) is - when b"00" => - return b"0001"; - when b"01" => - return b"0010"; - when b"10" => - return b"0100"; - when b"11" => - return b"1000"; - when others => - return b"0001"; - end case; - when b"10" => - if address(1) = '0' then - return b"0011"; - else - return b"1100"; - end if; - when others => - return b"1111"; - end case; - end function wb_get_data_sel; - -end package body pp_utilities; Index: new-privileged-isa/src/pp_writeback.vhd =================================================================== --- new-privileged-isa/src/pp_writeback.vhd (revision 57) +++ new-privileged-isa/src/pp_writeback.vhd (nonexistent) @@ -1,71 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.pp_types.all; -use work.pp_csr.all; - -entity pp_writeback is - port( - clk : in std_logic; - reset : in std_logic; - - -- Count instruction: - count_instr_in : in std_logic; - count_instr_out : out std_logic; - - -- Exception signals: - exception_ctx_in : in csr_exception_context; - exception_in : in std_logic; - exception_ctx_out : out csr_exception_context; - exception_out : out std_logic; - - -- CSR signals: - csr_write_in : in csr_write_mode; - csr_write_out : out csr_write_mode; - csr_data_in : in std_logic_vector(31 downto 0); - csr_data_out : out std_logic_vector(31 downto 0); - csr_addr_in : in csr_address; - csr_addr_out : out csr_address; - - -- Destination register interface: - rd_addr_in : in register_address; - rd_addr_out : out register_address; - rd_write_in : in std_logic; - rd_write_out : out std_logic; - rd_data_in : in std_logic_vector(31 downto 0); - rd_data_out : out std_logic_vector(31 downto 0) - ); -end entity pp_writeback; - -architecture behaviour of pp_writeback is -begin - - pipeline_register: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - rd_write_out <= '0'; - exception_out <= '0'; - count_instr_out <= '0'; - else - count_instr_out <= count_instr_in; - rd_data_out <= rd_data_in; - rd_write_out <= rd_write_in; - rd_addr_out <= rd_addr_in; - - exception_out <= exception_in; - exception_ctx_out <= exception_ctx_in; - - csr_write_out <= csr_write_in; - csr_data_out <= csr_data_in; - csr_addr_out <= csr_addr_in; - end if; - end if; - end process pipeline_register; - -end architecture behaviour; Index: new-privileged-isa/src/pp_constants.vhd =================================================================== --- new-privileged-isa/src/pp_constants.vhd (revision 57) +++ new-privileged-isa/src/pp_constants.vhd (nonexistent) @@ -1,15 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; - -use work.pp_types.all; - -package pp_constants is - - --! No-operation instruction, addi x0, x0, 0. - constant RISCV_NOP : std_logic_vector(31 downto 0) := (31 downto 5 => '0') & b"10011"; --! ADDI x0, x0, 0. - -end package pp_constants; Index: new-privileged-isa/src/pp_icache.vhd =================================================================== --- new-privileged-isa/src/pp_icache.vhd (revision 57) +++ new-privileged-isa/src/pp_icache.vhd (nonexistent) @@ -1,293 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.pp_types.all; -use work.pp_utilities.all; - ---! @brief Simple read-only direct-mapped instruction cache. -entity pp_icache is - generic( - LINE_SIZE : natural := 4; --! Number of words per cache line - NUM_LINES : natural := 128 --! Number of lines in the cache - ); - port( - clk : in std_logic; - reset : in std_logic; - - -- Control interface: - cache_enable : in std_logic; - cache_flush : in std_logic; - cached_areas : in std_logic_vector(31 downto 0); - - -- Memory interface: - mem_address_in : in std_logic_vector(31 downto 0); - mem_data_in : in std_logic_vector(31 downto 0); - mem_data_out : out std_logic_vector(31 downto 0); - mem_data_size : in std_logic_vector( 1 downto 0); - mem_read_req : in std_logic; - mem_read_ack : out std_logic; - mem_write_req : in std_logic; - mem_write_ack : out std_logic; - - -- Wishbone interface: - wb_inputs : in wishbone_master_inputs; - wb_outputs : out wishbone_master_outputs - ); -end entity pp_icache; - -architecture behaviour of pp_icache is - - -- Counter types: - subtype line_counter_type is natural range 0 to NUM_LINES; - subtype word_counter_type is natural range 0 to LINE_SIZE; - - -- Cache line types: - subtype cache_line_type is std_logic_vector((LINE_SIZE * 32) - 1 downto 0); - type cache_line_word_array is array(0 to LINE_SIZE - 1) of std_logic_vector(31 downto 0); - type cache_line_array is array(0 to NUM_LINES - 1) of cache_line_type; - - -- Cache tag type: - subtype cache_tag_type is std_logic_vector(31 - log2(LINE_SIZE * 4) - log2(NUM_LINES) downto 0); - type cache_tag_array is array(0 to NUM_LINES - 1) of cache_tag_type; - - -- Cache memories: - signal cache_memory : cache_line_array; - signal tag_memory : cache_tag_array; - signal valid : std_logic_vector(NUM_LINES - 1 downto 0) := (others => '0'); - - attribute ram_style : string; - attribute ram_style of cache_memory: signal is "block"; - --attribute ram_style of tag_memory: signal is "block"; - - -- Cache controller signals: - type state_type is (IDLE, CACHE_READ_STALL, SINGLE_READ, SINGLE_WRITE, - LOAD_CACHELINE_START, LOAD_CACHELINE_WAIT_ACK, LOAD_CACHELINE_FINISH); - signal state : state_type := IDLE; - - -- Is the current input address in the cache? - signal input_address_cached : boolean; - - -- Input address components: - signal input_address_line : std_logic_vector(log2(NUM_LINES) - 1 downto 0); - signal input_address_word : std_logic_vector(log2(LINE_SIZE) - 1 downto 0); - signal input_address_tag : std_logic_vector(31 - log2(LINE_SIZE * 4) - log2(NUM_LINES) downto 0); - - -- Cacheline matching the current input address: - signal current_cache_line, cache_lookup : cache_line_type; - signal current_cache_line_words : cache_line_word_array; - signal current_tag : cache_tag_type; - - -- Base address to store a cacheline to: - signal cl_store_address : std_logic_vector(31 downto log2(LINE_SIZE * 4)); - -- Base address to load a cacheline from: - signal cl_load_address : std_logic_vector(31 downto log2(LINE_SIZE * 4)); - -- Cache line to load: - signal cl_current_line : line_counter_type; - -- Current word being loaded/stored: - signal cl_current_word : word_counter_type; - - -- Buffer for holding a cache line while loading: - signal load_buffer : cache_line_type; - signal load_buffer_tag : cache_tag_type; - - -- Causes a cache line to be stored in the cache memory: - signal store_cache_line : std_logic; - - -- Set when the current input address matches a cache line: - signal cache_hit : std_logic; - - -- For regular reads: - signal read_ack : std_logic; - signal read_data_out : std_logic_vector(31 downto 0); - - -- For regular writes: - signal write_ack : std_logic; - - -- Gets the amount to shift output data to the processor with for requests of size != 32 bits: - function get_data_shift(size : in std_logic_vector(1 downto 0); address : in std_logic_vector) - return natural is - begin - case size is - when b"01" => - case address(1 downto 0) is - when b"00" => - return 0; - when b"01" => - return 8; - when b"10" => - return 16; - when b"11" => - return 24; - when others => - return 0; - end case; - when b"10" => - if address(1) = '0' then - return 0; - else - return 16; - end if; - when others => - return 0; - end case; - end function get_data_shift; - -begin - - --assert is_pow2(LINE_SIZE) report "Cache line size must be a power of 2!" severity FAILURE; - --assert is_pow2(NUM_LINES) report "Number of cache lines must be a power of 2!" severity FAILURE; - - -- Check if the current input address should be/is in the cache: - input_address_cached <= cached_areas(to_integer(unsigned(mem_address_in(31 downto 27)))) = '1'; - - mem_data_out <= current_cache_line_words(to_integer(unsigned(input_address_word))) when - input_address_cached and cache_enable = '1' and cache_flush = '0' - else read_data_out; - mem_read_ack <= (cache_hit and mem_read_req) - when state = IDLE and input_address_cached and cache_enable = '1' and cache_flush = '0' - else read_ack; - write_ack <= wb_inputs.ack when state = SINGLE_WRITE else '0'; - mem_write_ack <= write_ack; - - input_address_line <= mem_address_in(log2(LINE_SIZE * 4) + log2(NUM_LINES) - 1 downto log2(LINE_SIZE * 4)); - input_address_tag <= mem_address_in(31 downto log2(LINE_SIZE * 4) + log2(NUM_LINES)); - - find_word: process(clk) - begin - if rising_edge(clk) then - input_address_word <= mem_address_in(log2(LINE_SIZE * 4) - 1 downto 2); - end if; - end process find_word; - - cacheline_lookup: process(clk) - begin - if rising_edge(clk) then - if store_cache_line = '1' then - cache_memory(cl_current_line) <= load_buffer; - end if; - - current_cache_line <= cache_memory(to_integer(unsigned(input_address_line))); - end if; - end process cacheline_lookup; - - decompose_cache_line: for i in 0 to LINE_SIZE - 1 generate - current_cache_line_words(i) <= current_cache_line(32 * i + 31 downto 32 * i); - end generate decompose_cache_line; - - tag_lookup: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - cache_hit <= '0'; - else - if store_cache_line = '1' then - tag_memory(cl_current_line) <= load_buffer_tag; - end if; - - current_tag <= tag_memory(to_integer(unsigned(input_address_line))); - cache_hit <= valid(to_integer(unsigned(input_address_line))) and to_std_logic(tag_memory(to_integer(unsigned(input_address_line))) = input_address_tag); - end if; - end if; - end process tag_lookup; - - controller: process(clk) - variable current_word : std_logic_vector(31 downto 0); - begin - if rising_edge(clk) then - if reset = '1' then - state <= IDLE; - wb_outputs.cyc <= '0'; - wb_outputs.stb <= '0'; - store_cache_line <= '0'; - read_ack <= '0'; - valid <= (others => '0'); - read_data_out <= (others => '0'); - else - case state is - when IDLE => - read_ack <= '0'; - if cache_flush = '1' then - valid <= (others => '0'); - elsif input_address_cached and cache_enable = '1' then - if (mem_read_req = '1' or mem_write_req = '1') and cache_hit = '0' then - wb_outputs.adr <= mem_address_in(31 downto log2(LINE_SIZE * 4)) & (log2(LINE_SIZE * 4) - 1 downto 0 => '0'); - wb_outputs.cyc <= '1'; - wb_outputs.we <= '0'; - wb_outputs.sel <= (others => '1'); - load_buffer_tag <= input_address_tag; - cl_load_address <= mem_address_in(31 downto log2(LINE_SIZE * 4)); - cl_store_address <= input_address_tag & input_address_line; - cl_current_line <= to_integer(unsigned(input_address_line)); - cl_current_word <= 0; - state <= LOAD_CACHELINE_START; - end if; - else - if mem_read_req = '1' and read_ack = '0' then -- Do an uncached read - wb_outputs.adr <= mem_address_in; - wb_outputs.sel <= wb_get_data_sel(mem_data_size, mem_address_in); - wb_outputs.cyc <= '1'; - wb_outputs.stb <= '1'; - wb_outputs.we <= '0'; - state <= SINGLE_READ; - elsif mem_write_req = '1' then -- Do an uncached write - wb_outputs.adr <= mem_address_in; - wb_outputs.dat <= std_logic_vector(shift_left(unsigned(mem_data_in), - get_data_shift(mem_data_size, mem_address_in))); - wb_outputs.sel <= wb_get_data_sel(mem_data_size, mem_address_in); - wb_outputs.cyc <= '1'; - wb_outputs.stb <= '1'; - wb_outputs.we <= '1'; - state <= SINGLE_WRITE; - end if; - end if; - when CACHE_READ_STALL => - state <= IDLE; - when SINGLE_READ => - if wb_inputs.ack = '1' then - read_data_out <= std_logic_vector(shift_right(unsigned(wb_inputs.dat), - get_data_shift(mem_data_size, mem_address_in))); - wb_outputs.cyc <= '0'; - wb_outputs.stb <= '0'; - read_ack <= '1'; - state <= IDLE; - end if; - when SINGLE_WRITE => - if wb_inputs.ack = '1' then - wb_outputs.cyc <= '0'; - wb_outputs.stb <= '0'; - wb_outputs.we <= '0'; - state <= IDLE; - end if; - when LOAD_CACHELINE_START => - wb_outputs.stb <= '1'; - wb_outputs.we <= '0'; - wb_outputs.adr <= cl_load_address & std_logic_vector(to_unsigned(cl_current_word, log2(LINE_SIZE))) & b"00"; - state <= LOAD_CACHELINE_WAIT_ACK; - when LOAD_CACHELINE_WAIT_ACK => - if wb_inputs.ack = '1' then - wb_outputs.stb <= '0'; - load_buffer(cl_current_word * 32 + 31 downto cl_current_word * 32) <= wb_inputs.dat; - if natural(cl_current_word) = LINE_SIZE - 1 then - wb_outputs.cyc <= '0'; - store_cache_line <= '1'; - state <= LOAD_CACHELINE_FINISH; - else - cl_current_word <= cl_current_word + 1; - state <= LOAD_CACHELINE_START; - end if; - end if; - when LOAD_CACHELINE_FINISH => - store_cache_line <= '0'; - valid(cl_current_line) <= '1'; - state <= CACHE_READ_STALL; - end case; - end if; - end if; - end process controller; - -end architecture behaviour; Index: new-privileged-isa/src/pp_control_unit.vhd =================================================================== --- new-privileged-isa/src/pp_control_unit.vhd (revision 57) +++ new-privileged-isa/src/pp_control_unit.vhd (nonexistent) @@ -1,220 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; - -use work.pp_constants.all; -use work.pp_csr.all; -use work.pp_types.all; -use work.pp_utilities.all; - ---! @brief Unit decoding instructions and setting control signals apropriately. -entity pp_control_unit is - port( - -- Inputs, indices correspond to instruction word indices: - opcode : in std_logic_vector( 4 downto 0); - funct3 : in std_logic_vector( 2 downto 0); - funct7 : in std_logic_vector( 6 downto 0); - funct12 : in std_logic_vectoR(11 downto 0); - - -- Control signals: - rd_write : out std_logic; - branch : out branch_type; - - -- Exception signals: - decode_exception : out std_logic; - decode_exception_cause : out csr_exception_cause; - - -- Control register signals: - csr_write : out csr_write_mode; - csr_imm : out std_logic; --! Indicating an immediate variant of the csrr* instructions. - - -- Sources of operands to the ALU: - alu_x_src, alu_y_src : out alu_operand_source; - - -- ALU operation: - alu_op : out alu_operation; - - -- Memory transaction parameters: - mem_op : out memory_operation_type; - mem_size : out memory_operation_size - ); -end entity pp_control_unit; - -architecture behaviour of pp_control_unit is - signal exception : std_logic; - signal exception_cause : csr_exception_cause; - signal alu_op_temp : alu_operation; -begin - - csr_imm <= funct3(2); - alu_op <= alu_op_temp; - - decode_exception <= exception or to_std_logic(alu_op_temp = ALU_INVALID); - decode_exception_cause <= exception_cause when alu_op_temp /= ALU_INVALID - else CSR_CAUSE_INVALID_INSTR; - - alu_control: entity work.pp_alu_control_unit - port map( - opcode => opcode, - funct3 => funct3, - funct7 => funct7, - alu_x_src => alu_x_src, - alu_y_src => alu_y_src, - alu_op => alu_op_temp - ); - - decode_ctrl: process(opcode, funct3, funct12) - begin - case opcode is - when b"01101" => -- Load upper immediate - rd_write <= '1'; - exception <= '0'; - exception_cause <= CSR_CAUSE_NONE; - branch <= BRANCH_NONE; - when b"00101" => -- Add upper immediate to PC - rd_write <= '1'; - exception <= '0'; - exception_cause <= CSR_CAUSE_NONE; - branch <= BRANCH_NONE; - when b"11011" => -- Jump and link - rd_write <= '1'; - exception <= '0'; - exception_cause <= CSR_CAUSE_NONE; - branch <= BRANCH_JUMP; - when b"11001" => -- Jump and link register - rd_write <= '1'; - exception <= '0'; - exception_cause <= CSR_CAUSE_NONE; - branch <= BRANCH_JUMP_INDIRECT; - when b"11000" => -- Branch operations - rd_write <= '0'; - exception <= '0'; - exception_cause <= CSR_CAUSE_NONE; - branch <= BRANCH_CONDITIONAL; - when b"00000" => -- Load instructions - rd_write <= '1'; - exception <= '0'; - exception_cause <= CSR_CAUSE_NONE; - branch <= BRANCH_NONE; - when b"01000" => -- Store instructions - rd_write <= '0'; - exception <= '0'; - exception_cause <= CSR_CAUSE_NONE; - branch <= BRANCH_NONE; - when b"00100" => -- Register-immediate operations - rd_write <= '1'; - exception <= '0'; - exception_cause <= CSR_CAUSE_NONE; - branch <= BRANCH_NONE; - when b"01100" => -- Register-register operations - rd_write <= '1'; - exception <= '0'; - exception_cause <= CSR_CAUSE_NONE; - branch <= BRANCH_NONE; - when b"00011" => -- Fence instructions, ignored - rd_write <= '0'; - exception <= '0'; - exception_cause <= CSR_CAUSE_NONE; - branch <= BRANCH_NONE; - when b"11100" => -- System instructions - if funct3 = b"000" then - rd_write <= '0'; - - if funct12 = x"000" then - exception <= '1'; - exception_cause <= CSR_CAUSE_ECALL; - branch <= BRANCH_NONE; - elsif funct12 = x"001" then - exception <= '1'; - exception_cause <= CSR_CAUSE_BREAKPOINT; - branch <= BRANCH_NONE; - elsif funct12 = CSR_EPC_ERET then - exception <= '0'; - exception_cause <= CSR_CAUSE_NONE; - branch <= BRANCH_SRET; - else - exception <= '1'; - exception_cause <= CSR_CAUSE_INVALID_INSTR; - branch <= BRANCH_NONE; - end if; - else - rd_write <= '1'; - exception <= '0'; - exception_cause <= CSR_CAUSE_NONE; - branch <= BRANCH_NONE; - end if; - when others => - rd_write <= '0'; - exception <= '1'; - exception_cause <= CSR_CAUSE_INVALID_INSTR; - branch <= BRANCH_NONE; - end case; - end process decode_ctrl; - - decode_csr: process(opcode, funct3) - begin - if opcode = b"11100" then - case funct3 is - when b"001" | b"101" => -- csrrw/i - csr_write <= CSR_WRITE_REPLACE; - when b"010" | b"110" => -- csrrs/i - csr_write <= CSR_WRITE_SET; - when b"011" | b"111" => -- csrrc/i - csr_write <= CSR_WRITE_CLEAR; - when others => - csr_write <= CSR_WRITE_NONE; - end case; - else - csr_write <= CSR_WRITE_NONE; - end if; - end process decode_csr; - - decode_mem: process(opcode, funct3) - begin - case opcode is - when b"00000" => -- Load instructions - case funct3 is - when b"000" => -- lw - mem_size <= MEMOP_SIZE_BYTE; - mem_op <= MEMOP_TYPE_LOAD; - when b"001" => -- lh - mem_size <= MEMOP_SIZE_HALFWORD; - mem_op <= MEMOP_TYPE_LOAD; - when b"010" | b"110" => -- lw - mem_size <= MEMOP_SIZE_WORD; - mem_op <= MEMOP_TYPE_LOAD; - when b"100" => -- lbu - mem_size <= MEMOP_SIZE_BYTE; - mem_op <= MEMOP_TYPE_LOAD_UNSIGNED; - when b"101" => -- lhu - mem_size <= MEMOP_SIZE_HALFWORD; - mem_op <= MEMOP_TYPE_LOAD_UNSIGNED; - when others => -- FIXME: Treat others as lw. - mem_size <= MEMOP_SIZE_WORD; - mem_op <= MEMOP_TYPE_INVALID; - end case; - when b"01000" => -- Store instructions - case funct3 is - when b"000" => - mem_op <= MEMOP_TYPE_STORE; - mem_size <= MEMOP_SIZE_BYTE; - when b"001" => - mem_op <= MEMOP_TYPE_STORE; - mem_size <= MEMOP_SIZE_HALFWORD; - when b"010" => - mem_op <= MEMOP_TYPE_STORE; - mem_size <= MEMOP_SIZE_WORD; - when others => - mem_op <= MEMOP_TYPE_INVALID; - mem_size <= MEMOP_SIZE_WORD; - end case; - when others => - mem_op <= MEMOP_TYPE_NONE; - mem_size <= MEMOP_SIZE_WORD; - end case; - end process decode_mem; - -end architecture behaviour; Index: new-privileged-isa/src/pp_counter.vhd =================================================================== --- new-privileged-isa/src/pp_counter.vhd (revision 57) +++ new-privileged-isa/src/pp_counter.vhd (nonexistent) @@ -1,40 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 -2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -entity pp_counter is - generic( - COUNTER_WIDTH : natural := 64; - COUNTER_STEP : natural := 1 - ); - port( - clk : in std_logic; - reset : in std_logic; - - count : out std_logic_vector(COUNTER_WIDTH - 1 downto 0); - increment : in std_logic - ); -end entity pp_counter; - -architecture behaviour of pp_counter is - signal current_count : std_logic_vector(COUNTER_WIDTH - 1 downto 0); -begin - - count <= current_count; - - counter: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - current_count <= (others => '0'); - elsif increment = '1' then - current_count <= std_logic_vector(unsigned(current_count) + COUNTER_STEP); - end if; - end if; - end process counter; - -end architecture behaviour; Index: new-privileged-isa/src/pp_alu_control_unit.vhd =================================================================== --- new-privileged-isa/src/pp_alu_control_unit.vhd (revision 57) +++ new-privileged-isa/src/pp_alu_control_unit.vhd (nonexistent) @@ -1,141 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; - -use work.pp_types.all; -use work.pp_constants.all; - -entity pp_alu_control_unit is - port( - opcode : in std_logic_vector( 4 downto 0); - funct3 : in std_logic_vector( 2 downto 0); - funct7 : in std_logic_vector( 6 downto 0); - - -- Sources of ALU operands: - alu_x_src, alu_y_src : out alu_operand_source; - - -- ALU operation: - alu_op : out alu_operation - ); -end entity pp_alu_control_unit; - -architecture behaviour of pp_alu_control_unit is -begin - - decode_alu: process(opcode, funct3, funct7) - begin - case opcode is - when b"01101" => -- Load upper immediate - alu_x_src <= ALU_SRC_NULL; - alu_y_src <= ALU_SRC_IMM; - alu_op <= ALU_ADD; - when b"00101" => -- Add upper immediate to PC - alu_x_src <= ALU_SRC_PC; - alu_y_src <= ALU_SRC_IMM; - alu_op <= ALU_ADD; - when b"11011" => -- Jump and link - alu_x_src <= ALU_SRC_PC_NEXT; - alu_y_src <= ALU_SRC_NULL; - alu_op <= ALU_ADD; - when b"11001" => -- Jump and link register - alu_x_src <= ALU_SRC_PC_NEXT; - alu_y_src <= ALU_SRC_NULL; - alu_op <= ALU_ADD; - when b"11000" => -- Branch operations - -- The funct3 field decides which type of branch comparison is - -- done; this is decoded in the branch comparator module. - alu_x_src <= ALU_SRC_NULL; - alu_y_src <= ALU_SRC_NULL; - alu_op <= ALU_NOP; - when b"00000" => -- Load instruction - alu_x_src <= ALU_SRC_REG; - alu_y_src <= ALU_SRC_IMM; - alu_op <= ALU_ADD; - when b"01000" => -- Store instruction - alu_x_src <= ALU_SRC_REG; - alu_y_src <= ALU_SRC_IMM; - alu_op <= ALU_ADD; - when b"00100" => -- Register-immediate operations - alu_x_src <= ALU_SRC_REG; - - if funct3 = b"001" or funct3 = b"101" then - alu_y_src <= ALU_SRC_SHAMT; - else - alu_y_src <= ALU_SRC_IMM; - end if; - - case funct3 is - when b"000" => - alu_op <= ALU_ADD; - when b"001" => - alu_op <= ALU_SLL; - when b"010" => - alu_op <= ALU_SLT; - when b"011" => - alu_op <= ALU_SLTU; - when b"100" => - alu_op <= ALU_XOR; - when b"101" => - if funct7 = b"0000000" then - alu_op <= ALU_SRL; - else - alu_op <= ALU_SRA; - end if; - when b"110" => - alu_op <= ALU_OR; - when b"111" => - alu_op <= ALU_AND; - when others => - alu_op <= ALU_INVALID; - end case; - when b"01100" => -- Register-register operations - alu_x_src <= ALU_SRC_REG; - alu_y_src <= ALU_SRC_REG; - - case funct3 is - when b"000" => - if funct7 = b"0000000" then - alu_op <= ALU_ADD; - else - alu_op <= ALU_SUB; - end if; - when b"001" => - alu_op <= ALU_SLL; - when b"010" => - alu_op <= ALU_SLT; - when b"011" => - alu_op <= ALU_SLTU; - when b"100" => - alu_op <= ALU_XOR; - when b"101" => - if funct7 = b"0000000" then - alu_op <= ALU_SRL; - else - alu_op <= ALU_SRA; - end if; - when b"110" => - alu_op <= ALU_OR; - when b"111" => - alu_op <= ALU_AND; - when others => - alu_op <= ALU_INVALID; - end case; - when b"00011" => -- Fence instructions, ignored - alu_x_src <= ALU_SRC_REG; - alu_y_src <= ALU_SRC_REG; - alu_op <= ALU_NOP; - when b"11100" => -- System instructions - alu_x_src <= ALU_SRC_CSR; - alu_y_src <= ALU_SRC_NULL; - alu_op <= ALU_ADD; - when others => - alu_x_src <= ALU_SRC_REG; - alu_y_src <= ALU_SRC_REG; - alu_op <= ALU_INVALID; - end case; - end process decode_alu; - -end architecture behaviour; Index: new-privileged-isa/src/pp_wb_arbiter.vhd =================================================================== --- new-privileged-isa/src/pp_wb_arbiter.vhd (revision 57) +++ new-privileged-isa/src/pp_wb_arbiter.vhd (nonexistent) @@ -1,100 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; - -use work.pp_types.all; - ---! @brief Simple priority-based wishbone arbiter. ---! This module is used as an arbiter between the instruction and data caches. -entity pp_wb_arbiter is - port( - clk : in std_logic; - reset : in std_logic; - - -- Wishbone input 1: - m1_inputs : out wishbone_master_inputs; - m1_outputs : in wishbone_master_outputs; - - -- Wishbone input 2: - m2_inputs : out wishbone_master_inputs; - m2_outputs : in wishbone_master_outputs; - - -- Wishbone interface: - wb_adr_out : out std_logic_vector(31 downto 0); - wb_sel_out : out std_logic_vector( 3 downto 0); - wb_cyc_out : out std_logic; - wb_stb_out : out std_logic; - wb_we_out : out std_logic; - wb_dat_out : out std_logic_vector(31 downto 0); - wb_dat_in : in std_logic_vector(31 downto 0); - wb_ack_in : in std_logic - ); -end entity pp_wb_arbiter; - -architecture behaviour of pp_wb_arbiter is - - type state_type is (IDLE, M1_BUSY, M2_BUSY); - signal state : state_type := IDLE; - -begin - - m1_inputs <= (ack => wb_ack_in, dat => wb_dat_in) when state = M1_BUSY else (ack => '0', dat => (others => '0')); - m2_inputs <= (ack => wb_ack_in, dat => wb_dat_in) when state = M2_BUSY else (ack => '0', dat => (others => '0')); - - output_mux: process(state, m1_outputs, m2_outputs) - begin - case state is - when IDLE => - wb_adr_out <= (others => '0'); - wb_sel_out <= (others => '0'); - wb_dat_out <= (others => '0'); - wb_cyc_out <= '0'; - wb_stb_out <= '0'; - wb_we_out <= '0'; - when M1_BUSY => - wb_adr_out <= m1_outputs.adr; - wb_sel_out <= m1_outputs.sel; - wb_dat_out <= m1_outputs.dat; - wb_cyc_out <= m1_outputs.cyc; - wb_stb_out <= m1_outputs.stb; - wb_we_out <= m1_outputs.we; - when M2_BUSY => - wb_adr_out <= m2_outputs.adr; - wb_sel_out <= m2_outputs.sel; - wb_dat_out <= m2_outputs.dat; - wb_cyc_out <= m2_outputs.cyc; - wb_stb_out <= m2_outputs.stb; - wb_we_out <= m2_outputs.we; - end case; - end process output_mux; - - controller: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - state <= IDLE; - else - case state is - when IDLE => - if m1_outputs.cyc = '1' then - state <= M1_BUSY; - elsif m2_outputs.cyc = '1' then - state <= M2_BUSY; - end if; - when M1_BUSY => - if m1_outputs.cyc = '0' then - state <= IDLE; - end if; - when M2_BUSY => - if m2_outputs.cyc = '0' then - state <= IDLE; - end if; - end case; - end if; - end if; - end process controller; - -end architecture behaviour; Index: new-privileged-isa/src/pp_alu.vhd =================================================================== --- new-privileged-isa/src/pp_alu.vhd (revision 57) +++ new-privileged-isa/src/pp_alu.vhd (nonexistent) @@ -1,58 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.pp_types.all; - -entity pp_alu is - port( - x, y : in std_logic_vector(31 downto 0); - result : out std_logic_vector(31 downto 0); - operation : in alu_operation - ); -end entity pp_alu; - -architecture behaviour of pp_alu is -begin - - calculate: process(operation, x, y) - begin - case operation is - when ALU_AND => - result <= x and y; - when ALU_OR => - result <= x or y; - when ALU_XOR => - result <= x xor y; - when ALU_SLT => - if signed(x) < signed(y) then - result <= (0 => '1', others => '0'); - else - result <= (others => '0'); - end if; - when ALU_SLTU => - if unsigned(x) < unsigned(y) then - result <= (0 => '1', others => '0'); - else - result <= (others => '0'); - end if; - when ALU_ADD => - result <= std_logic_vector(unsigned(x) + unsigned(y)); - when ALU_SUB => - result <= std_logic_vector(unsigned(x) - unsigned(y)); - when ALU_SRL => - result <= std_logic_vector(shift_right(unsigned(x), to_integer(unsigned(y(4 downto 0))))); - when ALU_SLL => - result <= std_logic_vector(shift_left(unsigned(x), to_integer(unsigned(y(4 downto 0))))); - when ALU_SRA => - result <= std_logic_vector(shift_right(signed(x), to_integer(unsigned(y(4 downto 0))))); - when others => - result <= (others => '0'); - end case; - end process calculate; - -end architecture behaviour; Index: new-privileged-isa/src/pp_register_file.vhd =================================================================== --- new-privileged-isa/src/pp_register_file.vhd (revision 57) +++ new-privileged-isa/src/pp_register_file.vhd (nonexistent) @@ -1,55 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.pp_types.all; -use work.pp_utilities.all; - ---! @brief 32-bit RISC-V register file. -entity pp_register_file is - port( - clk : in std_logic; - - -- Read port 1: - rs1_addr : in register_address; - rs1_data : out std_logic_vector(31 downto 0); - - -- Read port 2: - rs2_addr : in register_address; - rs2_data : out std_logic_vector(31 downto 0); - - -- Write port: - rd_addr : in register_address; - rd_data : in std_logic_vector(31 downto 0); - rd_write : in std_logic - ); -end entity pp_register_file; - -architecture behaviour of pp_register_file is - - --! Register array type. - type regfile_array is array(0 to 31) of std_logic_vector(31 downto 0); - - --! Register array. - --shared variable registers : regfile_array := (others => (others => '0')); -- Shared variable used to simulate write-first RAM - -begin - - regfile: process(clk) - variable registers : regfile_array := (others => (others => '0')); - begin - if rising_edge(clk) then - if rd_write = '1' and rd_addr /= b"00000" then - registers(to_integer(unsigned(rd_addr))) := rd_data; - end if; - - rs1_data <= registers(to_integer(unsigned(rs1_addr))); - rs2_data <= registers(to_integer(unsigned(rs2_addr))); - end if; - end process regfile; - -end architecture behaviour; Index: new-privileged-isa/src/pp_fifo.vhd =================================================================== --- new-privileged-isa/src/pp_fifo.vhd (revision 57) +++ new-privileged-isa/src/pp_fifo.vhd (nonexistent) @@ -1,92 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; - ---! @brief A generic FIFO module. ---! Adopted from the FIFO module in . -entity pp_fifo is - generic( - DEPTH : natural := 64; - WIDTH : natural := 31 - ); - port( - -- Control lines: - clk : in std_logic; - reset : in std_logic; - - -- Status lines: - full : out std_logic; - empty : out std_logic; - - -- Data in: - data_in : in std_logic_vector(WIDTH - 1 downto 0); - data_out : out std_logic_vector(WIDTH - 1 downto 0); - push, pop : in std_logic - ); -end entity pp_fifo; - -architecture behaviour of pp_fifo is - - type memory_array is array(0 to DEPTH - 1) of std_logic_vector(WIDTH - 1 downto 0); - shared variable memory : memory_array := (others => (others => '0')); - - subtype index_type is integer range 0 to DEPTH - 1; - signal top, bottom : index_type; - - type fifo_op is (FIFO_POP, FIFO_PUSH); - signal prev_op : fifo_op := FIFO_POP; - -begin - - empty <= '1' when top = bottom and prev_op = FIFO_POP else '0'; - full <= '1' when top = bottom and prev_op = FIFO_PUSH else '0'; - - read: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - bottom <= 0; - else - if pop = '1' then - data_out <= memory(bottom); - bottom <= (bottom + 1) mod DEPTH; - end if; - end if; - end if; - end process read; - - write: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - top <= 0; - else - if push = '1' then - memory(top) := data_in; - top <= (top + 1) mod DEPTH; - end if; - end if; - end if; - end process write; - - set_prev_op: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - prev_op <= FIFO_POP; - else - if push = '1' and pop = '1' then - prev_op <= FIFO_POP; - elsif push = '1' then - prev_op <= FIFO_PUSH; - elsif pop = '1' then - prev_op <= FIFO_POP; - end if; - end if; - end if; - end process set_prev_op; - -end architecture behaviour; Index: new-privileged-isa/src/pp_decode.vhd =================================================================== --- new-privileged-isa/src/pp_decode.vhd (revision 57) +++ new-privileged-isa/src/pp_decode.vhd (nonexistent) @@ -1,140 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.pp_types.all; -use work.pp_constants.all; -use work.pp_csr.all; - ---! @brief Instruction decode unit. -entity pp_decode is - generic( - RESET_ADDRESS : std_logic_vector(31 downto 0); - PROCESSOR_ID : std_logic_vector(31 downto 0) - ); - port( - clk : in std_logic; - reset : in std_logic; - - flush : in std_logic; - stall : in std_logic; - - -- Instruction input: - instruction_data : in std_logic_vector(31 downto 0); - instruction_address : in std_logic_vector(31 downto 0); - instruction_ready : in std_logic; - instruction_count : in std_logic; - - -- Register addresses: - rs1_addr, rs2_addr, rd_addr : out register_address; - csr_addr : out csr_address; - - -- Shamt value for shift operations: - shamt : out std_logic_vector(4 downto 0); - funct3 : out std_logic_vector(2 downto 0); - - -- Immediate value for immediate instructions: - immediate : out std_logic_vector(31 downto 0); - - -- Control signals: - rd_write : out std_logic; - branch : out branch_type; - alu_x_src : out alu_operand_source; - alu_y_src : out alu_operand_source; - alu_op : out alu_operation; - mem_op : out memory_operation_type; - mem_size : out memory_operation_size; - count_instruction : out std_logic; - - -- Instruction address: - pc : out std_logic_vector(31 downto 0); - - -- CSR control signals: - csr_write : out csr_write_mode; - csr_use_imm : out std_logic; - - -- Exception output signals: - decode_exception : out std_logic; - decode_exception_cause : out csr_exception_cause - ); - -end entity pp_decode; - -architecture behaviour of pp_decode is - signal instruction : std_logic_vector(31 downto 0); - signal immediate_value : std_logic_vector(31 downto 0); -begin - - immediate <= immediate_value; - - get_instruction: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - instruction <= RISCV_NOP; - pc <= RESET_ADDRESS; - count_instruction <= '0'; - elsif stall = '1' then - count_instruction <= '0'; - elsif flush = '1' or instruction_ready = '0' then - instruction <= RISCV_NOP; - count_instruction <= '0'; - else - instruction <= instruction_data; - count_instruction <= instruction_count; - pc <= instruction_address; - end if; - end if; - end process get_instruction; - --- -- Extract register addresses from the instruction word: - rs1_addr <= instruction(19 downto 15); - rs2_addr <= instruction(24 downto 20); - rd_addr <= instruction(11 downto 7); - - -- Extract the shamt value from the instruction word: - shamt <= instruction(24 downto 20); - - -- Extract the value specifying which comparison to do in branch instructions: - funct3 <= instruction(14 downto 12); - - -- Extract the immediate value from the instruction word: - immediate_decoder: entity work.pp_imm_decoder - port map( - instruction => instruction(31 downto 2), - immediate => immediate_value - ); - - decode_csr_addr: process(immediate_value) - begin - if immediate_value(11 downto 0) = CSR_EPC_ERET then - csr_addr <= CSR_MEPC; - else - csr_addr <= immediate_value(11 downto 0); - end if; - end process decode_csr_addr; - - control_unit: entity work.pp_control_unit - port map( - opcode => instruction(6 downto 2), - funct3 => instruction(14 downto 12), - funct7 => instruction(31 downto 25), - funct12 => instruction(31 downto 20), - rd_write => rd_write, - branch => branch, - alu_x_src => alu_x_src, - alu_y_src => alu_y_src, - alu_op => alu_op, - mem_op => mem_op, - mem_size => mem_size, - decode_exception => decode_exception, - decode_exception_cause => decode_exception_cause, - csr_write => csr_write, - csr_imm => csr_use_imm - ); - -end architecture behaviour; Index: new-privileged-isa/src/pp_csr_unit.vhd =================================================================== --- new-privileged-isa/src/pp_csr_unit.vhd (revision 57) +++ new-privileged-isa/src/pp_csr_unit.vhd (nonexistent) @@ -1,294 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.pp_csr.all; -use work.pp_utilities.all; - -entity pp_csr_unit is - generic( - PROCESSOR_ID : std_logic_vector(31 downto 0) - ); - port( - clk, timer_clk : in std_logic; - reset : in std_logic; - - -- IRQ signals: - irq : in std_logic_vector(7 downto 0); - - -- Count retired instruction: - count_instruction : in std_logic; - - -- HTIF interface: - fromhost_data : in std_logic_vector(31 downto 0); - fromhost_updated : in std_logic; - tohost_data : out std_logic_vector(31 downto 0); - tohost_updated : out std_logic; - - -- Read port: - read_address : in csr_address; - read_data_out : out std_logic_vector(31 downto 0); - read_writeable : out boolean; - - -- Write port: - write_address : in csr_address; - write_data_in : in std_logic_vector(31 downto 0); - write_mode : in csr_write_mode; - - -- Exception context write port: - exception_context : in csr_exception_context; - exception_context_write : in std_logic; - - -- Interrupts originating from this unit: - software_interrupt_out : out std_logic; - timer_interrupt_out : out std_logic; - - -- Registers needed for exception handling, always read: - mie_out : out std_logic_vector(31 downto 0); - mtvec_out : out std_logic_vector(31 downto 0); - ie_out, ie1_out : out std_logic - ); -end entity pp_csr_unit; - -architecture behaviour of pp_csr_unit is - - -- Counters: - signal counter_time : std_logic_vector(63 downto 0); - signal counter_cycle : std_logic_vector(63 downto 0); - signal counter_instret : std_logic_vector(63 downto 0); - - -- Machine time counter: - signal counter_mtime : std_logic_vector(31 downto 0); - signal mtime_compare : std_logic_vector(31 downto 0); - - -- Machine-mode registers: - signal mcause : csr_exception_cause; - signal mbadaddr : std_logic_vector(31 downto 0); - signal mscratch : std_logic_vector(31 downto 0); - signal mepc : std_logic_vector(31 downto 0); - signal mtvec : std_logic_vector(31 downto 0) := x"00000100"; - signal mie : std_logic_vector(31 downto 0) := (others => '0'); - - -- Interrupt enable bits: - signal ie, ie1 : std_logic; - - -- HTIF FROMHOST register: - signal fromhost: std_logic_vector(31 downto 0); - - -- Interrupt signals: - signal timer_interrupt : std_logic; - signal software_interrupt : std_logic; - -begin - - -- Interrupt signals: - software_interrupt_out <= software_interrupt; - timer_interrupt_out <= timer_interrupt; - ie_out <= ie; - ie1_out <= ie1; - mie_out <= mie; - - -- The two upper bits of the CSR address encodes the accessibility of the CSR: - read_writeable <= read_address(11 downto 10) /= b"11"; - - --! Updates the FROMHOST register when new data is available. - htif_fromhost: process(clk) - begin - if rising_edge(clk) then - if fromhost_updated = '1' then - fromhost <= fromhost_data; - end if; - end if; - end process htif_fromhost; - - --! Sends a word to the host over the HTIF interface. - htif_tohost: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - tohost_data <= (others => '0'); - tohost_updated <= '0'; - else - if write_mode /= CSR_WRITE_NONE and write_address = CSR_MTOHOST then - tohost_data <= write_data_in; - tohost_updated <= '1'; - else - tohost_updated <= '0'; - end if; - end if; - end if; - end process htif_tohost; - - mtime_counter: process(timer_clk, reset) - begin - if reset = '1' then -- Asynchronous reset because timer_clk is slower than clk - counter_mtime <= (others => '0'); - elsif rising_edge(timer_clk) then - counter_mtime <= std_logic_vector(unsigned(counter_mtime) + 1); - end if; - end process mtime_counter; - - mtime_interrupt: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - timer_interrupt <= '0'; - else - if write_mode /= CSR_WRITE_NONE and write_address = CSR_MTIMECMP then - timer_interrupt <= '0'; - elsif counter_mtime = mtime_compare then - timer_interrupt <= '1'; - end if; - end if; - end if; - end process mtime_interrupt; - - write: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - software_interrupt <= '0'; - mtvec <= x"00000100"; - mepc <= x"00000100"; - mie <= (others => '0'); - ie <= '0'; - ie1 <= '0'; - else - if exception_context_write = '1' then - ie <= exception_context.ie; - ie1 <= exception_context.ie1; - mcause <= exception_context.cause; - mbadaddr <= exception_context.badaddr; - end if; - - if write_mode /= CSR_WRITE_NONE then - case write_address is - when CSR_MSTATUS => -- Status register - ie1 <= write_data_in(CSR_SR_IE1); - ie <= write_data_in(CSR_SR_IE); - when CSR_MSCRATCH => -- Scratch register - mscratch <= write_data_in; - when CSR_MEPC => -- Exception return address - mepc <= write_data_in; - --when CSR_MCAUSE => -- Exception cause - -- mcause <= write_data_in(31) & write_data_in(4 downto 0); - when CSR_MTVEC => -- Exception vector address - mtvec <= write_data_in; - when CSR_MTIMECMP => -- Time compare register - mtime_compare <= write_data_in; - when CSR_MIE => -- Interrupt enable register: - mie <= write_data_in; - when CSR_MIP => -- Interrupt pending register: - software_interrupt <= write_data_in(CSR_MIP_MSIP); - when others => - -- Ignore writes to invalid or read-only registers - end case; - end if; - end if; - end if; - end process write; - - read: process(clk) - begin - if rising_edge(clk) then - - if write_mode /= CSR_WRITE_NONE and write_address = CSR_MTVEC then - mtvec_out <= write_data_in; - else - mtvec_out <= mtvec; - end if; - - if write_mode /= CSR_WRITE_NONE and write_address = read_address then - read_data_out <= write_data_in; - else - case read_address is - - -- Machine mode registers: - when CSR_MCPUID => -- CPU features register - read_data_out <= ( - 8 => '1', -- Set the bit corresponding to I - others => '0'); - when CSR_MIMPID => -- Implementation/Implementor ID - read_data_out <= (31 downto 16 => '0') & x"8000"; - -- The anonymous source ID, 0x8000 is used until an open-source implementation ID - -- is available for use. - when CSR_MHARTID => -- Hardware thread ID - read_data_out <= PROCESSOR_ID; - when CSR_MFROMHOST => -- Data from a host environment - read_data_out <= fromhost; - when CSR_MSTATUS => -- Status register - read_data_out <= csr_make_mstatus(ie, ie1); - when CSR_MSCRATCH => -- Scratch register - read_data_out <= mscratch; - when CSR_MEPC => -- Exception PC value - read_data_out <= mepc; - when CSR_MTVEC => -- Exception vector address - read_data_out <= mtvec; - when CSR_MTDELEG => -- Exception vector delegation register, unsupported - read_data_out <= (others => '0'); - when CSR_MIP => -- Interrupt pending - read_data_out <= irq & (CSR_MIP_MTIP => timer_interrupt, CSR_MIP_MSIP => software_interrupt, - 23 downto 8 => '0', 6 downto 4 => '0', 2 downto 0 => '0'); - when CSR_MIE => -- Interrupt enable register - read_data_out <= mie; - when CSR_MBADADDR => -- Bad memory address - read_data_out <= mbadaddr; - when CSR_MCAUSE => -- Exception cause - read_data_out <= mcause(5) & (30 downto 5 => '0') & mcause(4 downto 0); --to_std_logic_vector(mcause); - - -- Timers and counters: - when CSR_MTIME => -- Machine time counter register - read_data_out <= counter_mtime; - when CSR_MTIMECMP => -- Machine time compare register - read_data_out <= mtime_compare; - - when CSR_TIME => - read_data_out <= counter_time(31 downto 0); - when CSR_TIMEH => - read_data_out <= counter_time(63 downto 32); - when CSR_CYCLE => - read_data_out <= counter_cycle(31 downto 0); - when CSR_CYCLEH => - read_data_out <= counter_cycle(63 downto 32); - when CSR_INSTRET => - read_data_out <= counter_instret(31 downto 0); - when CSR_INSTRETH => - read_data_out <= counter_instret(63 downto 32); - - -- Return zero from write-only registers and invalid register addresses: - when others => - read_data_out <= (others => '0'); - end case; - end if; - end if; - end process read; - - timer_counter: entity work.pp_counter - port map( - clk => timer_clk, - reset => reset, - count => counter_time, - increment => '1' - ); - - cycle_counter: entity work.pp_counter - port map( - clk => clk, - reset => reset, - count => counter_cycle, - increment => '1' - ); - - instret_counter: entity work.pp_counter - port map( - clk => clk, - reset => reset, - count => counter_instret, - increment => count_instruction - ); - -end architecture behaviour; Index: new-privileged-isa/src/pp_csr.vhd =================================================================== --- new-privileged-isa/src/pp_csr.vhd (revision 57) +++ new-privileged-isa/src/pp_csr.vhd (nonexistent) @@ -1,127 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; - ---! @brief Package containing constants and utility functions relating to status and control registers. -package pp_csr is - - --! Type used for specifying control and status register addresses. - subtype csr_address is std_logic_vector(11 downto 0); - - --! Type used for exception cause values. - subtype csr_exception_cause is std_logic_vector(5 downto 0); -- Upper bit is the interrupt bit - - --! Converts an exception cause to a std_logic_vector. - function to_std_logic_vector(input : in csr_exception_cause) return std_logic_vector; - - --! Control/status register write mode: - type csr_write_mode is ( - CSR_WRITE_NONE, CSR_WRITE_SET, CSR_WRITE_CLEAR, CSR_WRITE_REPLACE - ); - - -- Exception cause values: - constant CSR_CAUSE_INSTR_MISALIGN : csr_exception_cause := b"000000"; - constant CSR_CAUSE_INSTR_FETCH : csr_exception_cause := b"000001"; - constant CSR_CAUSE_INVALID_INSTR : csr_exception_cause := b"000010"; - constant CSR_CAUSE_BREAKPOINT : csr_exception_cause := b"000011"; - constant CSR_CAUSE_LOAD_MISALIGN : csr_exception_cause := b"000100"; - constant CSR_CAUSE_LOAD_ERROR : csr_exception_cause := b"000101"; - constant CSR_CAUSE_STORE_MISALIGN : csr_exception_cause := b"000110"; - constant CSR_CAUSE_STORE_ERROR : csr_exception_cause := b"000111"; - constant CSR_CAUSE_ECALL : csr_exception_cause := b"001011"; - constant CSR_CAUSE_NONE : csr_exception_cause := b"011111"; - - constant CSR_CAUSE_SOFTWARE_INT : csr_exception_cause := b"100000"; - constant CSR_CAUSE_TIMER_INT : csr_exception_cause := b"100001"; - constant CSR_CAUSE_IRQ_BASE : csr_exception_cause := b"110000"; - - -- Control register IDs, specified in the immediate field of csr* instructions: - constant CSR_CYCLE : csr_address := x"c00"; - constant CSR_CYCLEH : csr_address := x"c80"; - constant CSR_TIME : csr_address := x"c01"; - constant CSR_TIMEH : csr_address := x"c81"; - constant CSR_INSTRET : csr_address := x"c02"; - constant CSR_INSTRETH : csr_address := x"c82"; - - constant CSR_MCPUID : csr_address := x"f00"; - constant CSR_MIMPID : csr_address := x"f01"; - constant CSR_MHARTID : csr_address := x"f10"; - - constant CSR_MSTATUS : csr_address := x"300"; - constant CSR_MTVEC : csr_address := x"301"; - constant CSR_MTDELEG : csr_address := x"302"; - constant CSR_MIE : csr_address := x"304"; - - constant CSR_MTIMECMP : csr_address := x"321"; - constant CSR_MTIME : csr_address := x"701"; - - constant CSR_MSCRATCH : csr_address := x"340"; - constant CSR_MEPC : csr_address := x"341"; - constant CSR_MCAUSE : csr_address := x"342"; - constant CSR_MBADADDR : csr_address := x"343"; - constant CSR_MIP : csr_address := x"344"; - - constant CSR_MTOHOST : csr_address := x"780"; - constant CSR_MFROMHOST : csr_address := x"781"; - - -- Values used as control register IDs in ERET: - constant CSR_EPC_ERET : csr_address := x"100"; - - -- Offset into the exception vector for handling machine-mode exceptions: - constant CSR_MTVEC_M_OFFSET : natural := 192; - - -- Additional CSRs from supervisor mode that aliases machine mode registers - -- in this implementation: - --constant CSR_STVEC : csr_address := x"101"; - --constant CSR_SEPC : csr_address := x"141"; - - -- Status register bit indices: - constant CSR_SR_IE : natural := 0; - constant CSR_SR_IE1 : natural := 3; - - -- MIE and MIP register bit indices: - constant CSR_MIE_MSIE : natural := 3; - constant CSR_MIE_MTIE : natural := 7; - constant CSR_MIP_MSIP : natural := CSR_MIE_MSIE; - constant CSR_MIP_MTIP : natural := CSR_MIE_MTIE; - - -- Exception context; this record contains all state that can be manipulated - -- when an exception is taken. - type csr_exception_context is - record - ie, ie1 : std_logic; -- Enable Interrupt bits - cause : csr_exception_cause; - badaddr : std_logic_vector(31 downto 0); - end record; - - --! Creates the value of the mstatus registe from the EI and EI1 bits. - function csr_make_mstatus(ie, ie1 : in std_logic) return std_logic_vector; - -end package pp_csr; - -package body pp_csr is - - function to_std_logic_vector(input : in csr_exception_cause) - return std_logic_vector is - begin - return (31 => input(5), 30 downto 5 => '0') & input(4 downto 0); - end function to_std_logic_vector; - - function csr_make_mstatus(ie, ie1 : in std_logic) return std_logic_vector is - variable retval : std_logic_vector(31 downto 0); - begin - retval := ( - 11 downto 10 => '1', -- PRV3 - 8 downto 7 => '1', -- PRV2 - 5 downto 4 => '1', -- PRV1 - CSR_SR_IE1 => ie1, -- IE1 - 2 downto 1 => '1', -- PRV - CSR_SR_IE => ie, -- IE - others => '0'); - return retval; - end function csr_make_mstatus; - -end package body pp_csr; Index: new-privileged-isa/src/pp_csr_alu.vhd =================================================================== --- new-privileged-isa/src/pp_csr_alu.vhd (revision 57) +++ new-privileged-isa/src/pp_csr_alu.vhd (nonexistent) @@ -1,43 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.pp_csr.all; - ---! @brief ALU used for calculating new values of control and status registers. -entity pp_csr_alu is - port( - x, y : in std_logic_vector(31 downto 0); - result : out std_logic_vector(31 downto 0); - immediate : in std_logic_vector(4 downto 0); - use_immediate : in std_logic; - write_mode : in csr_write_mode - ); -end entity pp_csr_alu; - -architecture behaviour of pp_csr_alu is - signal a, b : std_logic_vector(31 downto 0); -begin - - a <= x; - b <= y when use_immediate = '0' else std_logic_vector(resize(unsigned(immediate), b'length)); - - calculate: process(a, b, write_mode) - begin - case write_mode is - when CSR_WRITE_NONE => - result <= a; - when CSR_WRITE_SET => - result <= a or b; - when CSR_WRITE_CLEAR => - result <= a and (not b); - when CSR_WRITE_REPLACE => - result <= b; - end case; - end process calculate; - -end architecture behaviour; Index: new-privileged-isa/src/pp_core.vhd =================================================================== --- new-privileged-isa/src/pp_core.vhd (revision 57) +++ new-privileged-isa/src/pp_core.vhd (nonexistent) @@ -1,458 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.pp_types.all; -use work.pp_constants.all; -use work.pp_utilities.all; -use work.pp_csr.all; - ---! @brief The Potato Processor is a simple processor core for use in FPGAs. ---! @details ---! It implements the RV32I (RISC-V base integer subset) ISA with additional ---! instructions for manipulation of control and status registers from the ---! currently unpublished supervisor extension. -entity pp_core is - generic( - PROCESSOR_ID : std_logic_vector(31 downto 0) := x"00000000"; --! Processor ID. - RESET_ADDRESS : std_logic_vector(31 downto 0) := x"00000200" --! Address of the first instruction to execute. - ); - port( - -- Control inputs: - clk : in std_logic; --! Processor clock - reset : in std_logic; --! Reset signal - - timer_clk : in std_logic; --! Clock used for the timer/counter - - -- Instruction memory interface: - 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_req : out std_logic; - imem_ack : in std_logic; - - -- Data memory interface: - 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_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_read_req : out std_logic; --! Data memory read request - dmem_read_ack : in std_logic; --! Data memory read acknowledge - dmem_write_req : out std_logic; --! Data memory write request - dmem_write_ack : in std_logic; --! Data memory write acknowledge - - -- Tohost/fromhost interface: - 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. - 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. - - -- External interrupt input: - irq : in std_logic_vector(7 downto 0) --! IRQ inputs. - ); -end entity pp_core; - -architecture behaviour of pp_core is - - ------- Flush signals ------- - signal flush_if, flush_id, flush_ex : std_logic; - - ------- Stall signals ------- - signal stall_if, stall_id, stall_ex, stall_mem : std_logic; - - -- Signals used to determine if an instruction should be counted - -- by the instret counter: - signal if_count_instruction, id_count_instruction : std_logic; - signal ex_count_instruction, mem_count_instruction : std_logic; - signal wb_count_instruction : std_logic; - - -- CSR read port signals: - signal csr_read_data : std_logic_vector(31 downto 0); - signal csr_read_writeable : boolean; - signal csr_read_address, csr_read_address_p : csr_address; - - -- Status register outputs: - signal mtvec : std_logic_vector(31 downto 0); - signal mie : std_logic_vector(31 downto 0); - signal ie, ie1 : std_logic; - - -- Internal interrupt signals: - signal software_interrupt, timer_interrupt : std_logic; - - -- Load hazard detected in the execute stage: - signal load_hazard_detected : std_logic; - - -- Branch targets: - signal exception_target, branch_target : std_logic_vector(31 downto 0); - signal branch_taken, exception_taken : std_logic; - - -- Register file read ports: - signal rs1_address_p, rs2_address_p : register_address; - signal rs1_address, rs2_address : register_address; - signal rs1_data, rs2_data : std_logic_vector(31 downto 0); - - -- Data memory signals: - signal dmem_address_p : std_logic_vector(31 downto 0); - signal dmem_data_size_p : std_logic_vector(1 downto 0); - signal dmem_data_out_p : std_logic_vector(31 downto 0); - signal dmem_read_req_p : std_logic; - signal dmem_write_req_p : std_logic; - - -- Fetch stage signals: - signal if_instruction, if_pc : std_logic_vector(31 downto 0); - signal if_instruction_ready : std_logic; - - -- Decode stage signals: - signal id_funct3 : std_logic_vector(2 downto 0); - signal id_rd_address : register_address; - signal id_rd_write : std_logic; - signal id_rs1_address : register_address; - signal id_rs2_address : register_address; - signal id_csr_address : csr_address; - signal id_csr_write : csr_write_mode; - signal id_csr_use_immediate : std_logic; - signal id_shamt : std_logic_vector(4 downto 0); - signal id_immediate : std_logic_vector(31 downto 0); - signal id_branch : branch_type; - signal id_alu_x_src, id_alu_y_src : alu_operand_source; - signal id_alu_op : alu_operation; - signal id_mem_op : memory_operation_type; - signal id_mem_size : memory_operation_size; - signal id_pc : std_logic_vector(31 downto 0); - signal id_exception : std_logic; - signal id_exception_cause : csr_exception_cause; - - -- Execute stage signals: - signal ex_dmem_address : std_logic_vector(31 downto 0); - signal ex_dmem_data_size : std_logic_vector(1 downto 0); - signal ex_dmem_data_out : std_logic_vector(31 downto 0); - signal ex_dmem_read_req : std_logic; - signal ex_dmem_write_req : std_logic; - signal ex_rd_address : register_address; - signal ex_rd_data : std_logic_vector(31 downto 0); - signal ex_rd_write : std_logic; - signal ex_pc : std_logic_vector(31 downto 0); - signal ex_csr_address : csr_address; - signal ex_csr_write : csr_write_mode; - signal ex_csr_data : std_logic_vector(31 downto 0); - signal ex_branch : branch_type; - signal ex_mem_op : memory_operation_type; - signal ex_mem_size : memory_operation_size; - signal ex_exception_context : csr_exception_context; - - -- Memory stage signals: - signal mem_rd_write : std_logic; - signal mem_rd_address : register_address; - signal mem_rd_data : std_logic_vector(31 downto 0); - signal mem_csr_address : csr_address; - signal mem_csr_write : csr_write_mode; - signal mem_csr_data : std_logic_vector(31 downto 0); - signal mem_mem_op : memory_operation_type; - - signal mem_exception : std_logic; - signal mem_exception_context : csr_exception_context; - - -- Writeback signals: - signal wb_rd_address : register_address; - signal wb_rd_data : std_logic_vector(31 downto 0); - signal wb_rd_write : std_logic; - signal wb_csr_address : csr_address; - signal wb_csr_write : csr_write_mode; - signal wb_csr_data : std_logic_vector(31 downto 0); - - signal wb_exception : std_logic; - signal wb_exception_context : csr_exception_context; - -begin - - stall_if <= stall_id; - stall_id <= stall_ex; - stall_ex <= load_hazard_detected or stall_mem; - stall_mem <= to_std_logic(memop_is_load(mem_mem_op) and dmem_read_ack = '0') - or to_std_logic(mem_mem_op = MEMOP_TYPE_STORE and dmem_write_ack = '0'); - - flush_if <= (branch_taken or exception_taken) and not stall_if; - flush_id <= (branch_taken or exception_taken) and not stall_id; - flush_ex <= (branch_taken or exception_taken) and not stall_ex; - - ------- Control and status module ------- - csr_unit: entity work.pp_csr_unit - generic map( - PROCESSOR_ID => PROCESSOR_ID - ) port map( - clk => clk, - reset => reset, - timer_clk => timer_clk, - irq => irq, - count_instruction => wb_count_instruction, - fromhost_data => fromhost_data, - fromhost_updated => fromhost_write_en, - tohost_data => tohost_data, - tohost_updated => tohost_write_en, - read_address => csr_read_address, - read_data_out => csr_read_data, - read_writeable => csr_read_writeable, - write_address => wb_csr_address, - write_data_in => wb_csr_data, - write_mode => wb_csr_write, - exception_context => wb_exception_context, - exception_context_write => wb_exception, - mie_out => mie, - mtvec_out => mtvec, - ie_out => ie, - ie1_out => ie1, - software_interrupt_out => software_interrupt, - timer_interrupt_out => timer_interrupt - ); - - csr_read_address <= id_csr_address when stall_ex = '0' else csr_read_address_p; - store_previous_csr_addr: process(clk, stall_ex) - begin - if rising_edge(clk) and stall_ex = '0' then - csr_read_address_p <= id_csr_address; - end if; - end process store_previous_csr_addr; - - ------- Register file ------- - regfile: entity work.pp_register_file - port map( - clk => clk, - rs1_addr => rs1_address, - rs2_addr => rs2_address, - rs1_data => rs1_data, - rs2_data => rs2_data, - rd_addr => wb_rd_address, - rd_data => wb_rd_data, - rd_write => wb_rd_write - ); - - rs1_address <= id_rs1_address when stall_ex = '0' else rs1_address_p; - rs2_address <= id_rs2_address when stall_ex = '0' else rs2_address_p; - - store_previous_rsaddr: process(clk, stall_ex) - begin - if rising_edge(clk) and stall_ex = '0' then - rs1_address_p <= id_rs1_address; - rs2_address_p <= id_rs2_address; - end if; - end process store_previous_rsaddr; - - ------- Instruction Fetch (IF) Stage ------- - fetch: entity work.pp_fetch - generic map( - RESET_ADDRESS => RESET_ADDRESS - ) port map( - clk => clk, - reset => reset, - imem_address => imem_address, - imem_data_in => imem_data_in, - imem_req => imem_req, - imem_ack => imem_ack, - stall => stall_if, - flush => flush_if, - branch => branch_taken, - exception => exception_taken, - branch_target => branch_target, - evec => exception_target, - instruction_data => if_instruction, - instruction_address => if_pc, - instruction_ready => if_instruction_ready - ); - if_count_instruction <= if_instruction_ready; - - ------- Instruction Decode (ID) Stage ------- - decode: entity work.pp_decode - generic map( - RESET_ADDRESS => RESET_ADDRESS, - PROCESSOR_ID => PROCESSOR_ID - ) port map( - clk => clk, - reset => reset, - flush => flush_id, - stall => stall_id, - instruction_data => if_instruction, - instruction_address => if_pc, - instruction_ready => if_instruction_ready, - instruction_count => if_count_instruction, - funct3 => id_funct3, - rs1_addr => id_rs1_address, - rs2_addr => id_rs2_address, - rd_addr => id_rd_address, - csr_addr => id_csr_address, - shamt => id_shamt, - immediate => id_immediate, - rd_write => id_rd_write, - branch => id_branch, - alu_x_src => id_alu_x_src, - alu_y_src => id_alu_y_src, - alu_op => id_alu_op, - mem_op => id_mem_op, - mem_size => id_mem_size, - count_instruction => id_count_instruction, - pc => id_pc, - csr_write => id_csr_write, - csr_use_imm => id_csr_use_immediate, - decode_exception => id_exception, - decode_exception_cause => id_exception_cause - ); - - ------- Execute (EX) Stage ------- - execute: entity work.pp_execute - port map( - clk => clk, - reset => reset, - stall => stall_ex, - flush => flush_ex, - irq => irq, - software_interrupt => software_interrupt, - timer_interrupt => timer_interrupt, - dmem_address => ex_dmem_address, - dmem_data_size => ex_dmem_data_size, - dmem_data_out => ex_dmem_data_out, - dmem_read_req => ex_dmem_read_req, - dmem_write_req => ex_dmem_write_req, - rs1_addr_in => rs1_address, - rs2_addr_in => rs2_address, - rd_addr_in => id_rd_address, - rd_addr_out => ex_rd_address, - rs1_data_in => rs1_data, - rs2_data_in => rs2_data, - shamt_in => id_shamt, - immediate_in => id_immediate, - funct3_in => id_funct3, - pc_in => id_pc, - pc_out => ex_pc, - csr_addr_in => csr_read_address, - csr_addr_out => ex_csr_address, - csr_write_in => id_csr_write, - csr_write_out => ex_csr_write, - csr_value_in => csr_read_data, - csr_value_out => ex_csr_data, - csr_writeable_in => csr_read_writeable, - csr_use_immediate_in => id_csr_use_immediate, - alu_op_in => id_alu_op, - alu_x_src_in => id_alu_x_src, - alu_y_src_in => id_alu_y_src, - rd_write_in => id_rd_write, - rd_write_out => ex_rd_write, - rd_data_out => ex_rd_data, - branch_in => id_branch, - branch_out => ex_branch, - mem_op_in => id_mem_op, - mem_op_out => ex_mem_op, - mem_size_in => id_mem_size, - mem_size_out => ex_mem_size, - count_instruction_in => id_count_instruction, - count_instruction_out => ex_count_instruction, - ie_in => ie, - ie1_in => ie1, - mie_in => mie, - mtvec_in => mtvec, - mtvec_out => exception_target, - decode_exception_in => id_exception, - decode_exception_cause_in => id_exception_cause, - exception_out => exception_taken, - exception_context_out => ex_exception_context, - jump_out => branch_taken, - jump_target_out => branch_target, - mem_rd_write => mem_rd_write, - mem_rd_addr => mem_rd_address, - mem_rd_value => mem_rd_data, - mem_csr_addr => mem_csr_address, - mem_csr_value => mem_csr_data, - mem_csr_write => mem_csr_write, - mem_exception => mem_exception, - mem_exception_context => mem_exception_context, - wb_rd_write => wb_rd_write, - wb_rd_addr => wb_rd_address, - wb_rd_value => wb_rd_data, - wb_csr_addr => wb_csr_address, - wb_csr_value => wb_csr_data, - wb_csr_write => wb_csr_write, - wb_exception => wb_exception, - wb_exception_context => wb_exception_context, - mem_mem_op => mem_mem_op, - hazard_detected => load_hazard_detected - ); - - dmem_address <= ex_dmem_address when stall_mem = '0' else dmem_address_p; - dmem_data_size <= ex_dmem_data_size when stall_mem = '0' else dmem_data_size_p; - dmem_data_out <= ex_dmem_data_out when stall_mem = '0' else dmem_data_out_p; - dmem_read_req <= ex_dmem_read_req when stall_mem = '0' else dmem_read_req_p; - dmem_write_req <= ex_dmem_write_req when stall_mem = '0' else dmem_write_req_p; - - store_previous_dmem_address: process(clk, stall_mem) - begin - if rising_edge(clk) and stall_mem = '0' then - dmem_address_p <= ex_dmem_address; - dmem_data_size_p <= ex_dmem_data_size; - dmem_data_out_p <= ex_dmem_data_out; - dmem_read_req_p <= ex_dmem_read_req; - dmem_write_req_p <= ex_dmem_write_req; - end if; - end process store_previous_dmem_address; - - ------- Memory (MEM) Stage ------- - memory: entity work.pp_memory - port map( - clk => clk, - reset => reset, - stall => stall_mem, - dmem_data_in => dmem_data_in, - dmem_read_ack => dmem_read_ack, - dmem_write_ack => dmem_write_ack, - pc => ex_pc, - rd_write_in => ex_rd_write, - rd_write_out => mem_rd_write, - rd_data_in => ex_rd_data, - rd_data_out => mem_rd_data, - rd_addr_in => ex_rd_address, - rd_addr_out => mem_rd_address, - branch => ex_branch, - mem_op_in => ex_mem_op, - mem_op_out => mem_mem_op, - mem_size_in => ex_mem_size, - count_instr_in => ex_count_instruction, - count_instr_out => mem_count_instruction, - exception_in => exception_taken, - exception_out => mem_exception, - exception_context_in => ex_exception_context, - exception_context_out => mem_exception_context, - csr_addr_in => ex_csr_address, - csr_addr_out => mem_csr_address, - csr_write_in => ex_csr_write, - csr_write_out => mem_csr_write, - csr_data_in => ex_csr_data, - csr_data_out => mem_csr_data - ); - - ------- Writeback (WB) Stage ------- - writeback: entity work.pp_writeback - port map( - clk => clk, - reset => reset, - count_instr_in => mem_count_instruction, - count_instr_out => wb_count_instruction, - exception_ctx_in => mem_exception_context, - exception_ctx_out => wb_exception_context, - exception_in => mem_exception, - exception_out => wb_exception, - csr_write_in => mem_csr_write, - csr_write_out => wb_csr_write, - csr_data_in => mem_csr_data, - csr_data_out => wb_csr_data, - csr_addr_in => mem_csr_address, - csr_addr_out => wb_csr_address, - rd_addr_in => mem_rd_address, - rd_addr_out => wb_rd_address, - rd_write_in => mem_rd_write, - rd_write_out => wb_rd_write, - rd_data_in => mem_rd_data, - rd_data_out => wb_rd_data - ); - -end architecture behaviour; - Index: new-privileged-isa/src/pp_fetch.vhd =================================================================== --- new-privileged-isa/src/pp_fetch.vhd (revision 57) +++ new-privileged-isa/src/pp_fetch.vhd (nonexistent) @@ -1,89 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.pp_constants.all; - ---! @brief Instruction fetch unit. -entity pp_fetch is - generic( - RESET_ADDRESS : std_logic_vector(31 downto 0) - ); - port( - clk : in std_logic; - reset : in std_logic; - - -- Instruction memory connections: - imem_address : out std_logic_vector(31 downto 0); - imem_data_in : in std_logic_vector(31 downto 0); - imem_req : out std_logic; - imem_ack : in std_logic; - - -- Control inputs: - stall : in std_logic; - flush : in std_logic; - branch : in std_logic; - exception : in std_logic; - - branch_target : in std_logic_vector(31 downto 0); - evec : in std_logic_vector(31 downto 0); - - -- Outputs to the instruction decode unit: - instruction_data : out std_logic_vector(31 downto 0); - instruction_address : out std_logic_vector(31 downto 0); - instruction_ready : out std_logic - ); -end entity pp_fetch; - -architecture behaviour of pp_fetch is - signal pc : std_logic_vector(31 downto 0); - signal pc_next : std_logic_vector(31 downto 0); - signal cancel_fetch : std_logic; -begin - - imem_address <= pc_next when cancel_fetch = '0' else pc; - - instruction_data <= imem_data_in; - instruction_ready <= imem_ack and (not stall) and (not cancel_fetch); - instruction_address <= pc; - - imem_req <= '1'; - - set_pc: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - pc <= RESET_ADDRESS; - cancel_fetch <= '0'; - else - if (exception = '1' or branch = '1') and imem_ack = '0' then - cancel_fetch <= '1'; - pc <= pc_next; - elsif cancel_fetch = '1' and imem_ack = '1' then - --pc <= pc_next; - cancel_fetch <= '0'; - else - pc <= pc_next; - end if; - end if; - end if; - end process set_pc; - - calc_next_pc: process(reset, stall, branch, exception, imem_ack, branch_target, evec, pc, cancel_fetch) - begin - if exception = '1' then - pc_next <= evec; - elsif branch = '1' then - pc_next <= branch_target; - elsif imem_ack = '1' and stall = '0' and cancel_fetch = '0' then - pc_next <= std_logic_vector(unsigned(pc) + 4); - else - pc_next <= pc; - end if; - end process calc_next_pc; - -end architecture behaviour; Index: new-privileged-isa/docs/example.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = image/png Index: new-privileged-isa/docs/example.png =================================================================== --- new-privileged-isa/docs/example.png (revision 57) +++ new-privileged-isa/docs/example.png (nonexistent)
new-privileged-isa/docs/example.png Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -image/png \ No newline at end of property Index: new-privileged-isa/docs/opencores.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = image/png Index: new-privileged-isa/docs/opencores.png =================================================================== --- new-privileged-isa/docs/opencores.png (revision 57) +++ new-privileged-isa/docs/opencores.png (nonexistent)
new-privileged-isa/docs/opencores.png Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -image/png \ No newline at end of property Index: new-privileged-isa/docs/datasheet.tex =================================================================== --- new-privileged-isa/docs/datasheet.tex (revision 57) +++ new-privileged-isa/docs/datasheet.tex (nonexistent) @@ -1,136 +0,0 @@ -% The Potato Processor - Processor Datasheet -% (c) Kristian Klomsten Skordal 2015 -% Report bugs and issues on - -\documentclass[10pt,a4paper]{article} - -\usepackage[pdftitle={The Potato Processor Datasheet}, - pdfauthor={Kristian Klomsten Skordal}]{hyperref} -\usepackage{graphicx} -\usepackage{multicol} -\usepackage{enumitem} -\usepackage{titlesec} -\usepackage{tabularx} -\usepackage[margin=2.0cm,includefoot,footskip=10pt]{geometry} -\usepackage[british]{babel} - -\renewcommand{\familydefault}{\sfdefault} - -\titleformat{\section}[block]{}{}{0pt}{\normalfont\large\bfseries} -\pagestyle{empty} - -\setlength{\parindent}{0pt} -\setlist[itemize]{leftmargin=*,nosep} - -\begin{document} - -\begin{minipage}{0.5\textwidth} -\raggedright -\includegraphics[width=0.6\textwidth]{opencores.png} -\end{minipage} -\begin{minipage}{0.5\textwidth} -\raggedleft\Large\bf -\textsf{The Potato Processor\\Datasheet} -\end{minipage} - -\vspace{0.5em} -\noindent\rule{\linewidth}{1pt}\\ - -\begin{minipage}[t]{0.48\textwidth} - -\section{Architecture} -\includegraphics[width=\textwidth]{diagram.png} - -\section{Features} - -\begin{itemize} -\item Supports the complete 32-bit RISC-V base integer ISA (RV32I) version 2.0 -\item Supports machine mode as defined by the RISC-V supervisor extensions version 1.7 -\item Includes a hardware timer with microsecond resolution and compare interrupt -\item 8 IRQ inputs that can be invidually enabled -\item Classic 5-stage RISC pipeline -\item Instruction cache -\item Wishbone interface -\item Automatic test suite -\end{itemize} - -\section{Interface} - -The processor includes a wishbone interface conforming to the B4 revision of the -wishbone specification.\\ - -\begin{tabularx}{\textwidth}{|l|X|} -\hline -Interface type & Master \\ -Address port width & 32 bits \\ -Data port width & 32 bits \\ -Data port granularity & 8 bits \\ -Maximum operand size & 32 bits \\ -Endianess & Little \\ -Sequence of data transfer & In-order \\ -\hline -\end{tabularx} - -\section{Programming} - -Tools for writing programmes for the RISC-V architecture are available from the -RISC-V project, at:\\[1em] -\url{https://github.com/riscv/riscv-tools}\\ - -Use the \texttt{new\_privileged\_isa} branch to get tools that work with the -current supervisor extensions. - -\end{minipage}\hfill -\begin{minipage}[t]{0.48\textwidth} - -\section{Application} -\includegraphics[width=\textwidth]{example.png} - -\section{Signals} - -The processor is provided by a VHDL module named \texttt{pp\_potato}. The signals of -the module are all active high and are as follows:\\ - -\begin{tabularx}{\textwidth}{|l|l|X|} -\hline -\textbf{Name} & \textbf{Width} & \textbf{Description} \\ -\hline -\texttt{clk} & 1 & Processor clock \\ -\texttt{timer\_clk} & 1 & 10~MHz timer clock \\ -\texttt{reset} & 1 & Reset signal \\ -\hline -\texttt{irq} & 8 & IRQ inputs \\ -\hline -\texttt{wb\_adr\_out} & 32 & Wishbone address \\ -\texttt{wb\_sel\_out} & 4 & Wishbone byte select \\ -\texttt{wb\_cyc\_out} & 1 & Wishbone cycle \\ -\texttt{wb\_stb\_out} & 1 & Wishbone strobe \\ -\texttt{wb\_we\_out} & 1 & Wishbone write enable \\ -\texttt{wb\_dat\_out} & 32 & Wishbone data output \\ -\texttt{wb\_dat\_in} & 32 & Wishbone data input \\ -\texttt{wb\_ack\_in} & 1 & Wishbone acknowledge \\ -\hline -\end{tabularx}\\ - -Additional signals are used to implement a host-target interface used in the automatic testing -environment. These signals have names starting with \texttt{fromhost} and \texttt{tohost} and -should be left unconnected for normal use.\\ - -\section{Specifications} - -The base RISC-V instruction set and the privileged extensions are available in the -specifications published at:\\ - -\url{http://riscv.org/download.html}. - -\end{minipage} - -\vfill -\noindent\rule{\linewidth}{1pt} -{\small -Project page: \url{http://opencores.org/project,potato}\\ -Report bugs and issues on \url{http://opencores.org/project,potato,bugtracker}} - -\end{document} - - Index: new-privileged-isa/docs/diagram.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = image/png Index: new-privileged-isa/docs/diagram.png =================================================================== --- new-privileged-isa/docs/diagram.png (revision 57) +++ new-privileged-isa/docs/diagram.png (nonexistent)
new-privileged-isa/docs/diagram.png Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -image/png \ No newline at end of property Index: new-privileged-isa/docs/datasheet.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/pdf Index: new-privileged-isa/docs/datasheet.pdf =================================================================== --- new-privileged-isa/docs/datasheet.pdf (revision 57) +++ new-privileged-isa/docs/datasheet.pdf (nonexistent)
new-privileged-isa/docs/datasheet.pdf Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/pdf \ No newline at end of property Index: new-privileged-isa/example/README =================================================================== --- new-privileged-isa/example/README (revision 57) +++ new-privileged-isa/example/README (nonexistent) @@ -1,35 +0,0 @@ -# Demo design for the Nexys 4 board - -This folder contains a design for a simple demo design using the Potato -processor. It has been tested using Vivado 2014.4. - -## Quick Start - -In order to use the design, first import all source files from the folders -`src/`, `soc/` and `example/` into your project. Make sure the testbench files -(the files starting with "tb_") is added as simulation-only files. - -### Clocking - -Add a clock generator using the Clocking Wizard. To seamlessly integrate -it into the design, name it "clock_generator". Choose the following options: - -* Frequency Synthesis -* Safe Clock Startup - -Set up two output clocks, `clk_out1` with frequency 60 MHz, and `clk_out2` with -a frequency of 10 MHz. Rename the corresponding ports to `system_clk` and -`timer_clk` respectively. Name the input clock `clk`. - -### Instruction memory - -Add a block RAM to use as instruction ROM using the Block Memory Generator. -Choose "Single Port ROM" as memory type, name it "instruction_rom" and set -port A width to 32 bits and port A depth to 2048. Initialize it with your -application binary and, optionally, fill the remaining memory locations with -0x00000013 (no-operation opcode). - -### Test it! - -Now you can test it and hopefully it works :-) - Index: new-privileged-isa/example/nexys4_constraints.xdc =================================================================== --- new-privileged-isa/example/nexys4_constraints.xdc (revision 57) +++ new-privileged-isa/example/nexys4_constraints.xdc (nonexistent) @@ -1,94 +0,0 @@ -# The Potato Processor - A simple processor for FPGAs -# (c) Kristian Klomsten Skordal 2014 -# Report bugs and issues on - -# Set operating conditions to improve temperature estimation: -set_operating_conditions -airflow 0 -set_operating_conditions -heatsink low - -# Clock: -set_property PACKAGE_PIN E3 [get_ports clk] - set_property IOSTANDARD LVCMOS33 [get_ports clk] - create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk] - - # Reset: - set_property PACKAGE_PIN C12 [get_ports reset_n] - set_property IOSTANDARD LVCMOS33 [get_ports reset_n] - - # External interrupt button: - set_property PACKAGE_PIN E16 [get_ports external_interrupt] - set_property IOSTANDARD LVCMOS33 [get_ports external_interrupt] - -# UART (to host) lines: -set_property PACKAGE_PIN C4 [get_ports uart_rxd] - set_property IOSTANDARD LVCMOS33 [get_ports uart_rxd] -set_property PACKAGE_PIN D4 [get_ports uart_txd] - set_property IOSTANDARD LVCMOS33 [get_ports uart_txd] - -# Switches: -set_property PACKAGE_PIN U9 [get_ports {switches[0]}] - set_property IOSTANDARD LVCMOS33 [get_ports {switches[0]}] -set_property PACKAGE_PIN U8 [get_ports {switches[1]}] - set_property IOSTANDARD LVCMOS33 [get_ports {switches[1]}] -set_property PACKAGE_PIN R7 [get_ports {switches[2]}] - set_property IOSTANDARD LVCMOS33 [get_ports {switches[2]}] -set_property PACKAGE_PIN R6 [get_ports {switches[3]}] - set_property IOSTANDARD LVCMOS33 [get_ports {switches[3]}] -set_property PACKAGE_PIN R5 [get_ports {switches[4]}] - set_property IOSTANDARD LVCMOS33 [get_ports {switches[4]}] -set_property PACKAGE_PIN V7 [get_ports {switches[5]}] - set_property IOSTANDARD LVCMOS33 [get_ports {switches[5]}] -set_property PACKAGE_PIN V6 [get_ports {switches[6]}] - set_property IOSTANDARD LVCMOS33 [get_ports {switches[6]}] -set_property PACKAGE_PIN V5 [get_ports {switches[7]}] - set_property IOSTANDARD LVCMOS33 [get_ports {switches[7]}] -set_property PACKAGE_PIN U4 [get_ports {switches[8]}] - set_property IOSTANDARD LVCMOS33 [get_ports {switches[8]}] -set_property PACKAGE_PIN V2 [get_ports {switches[9]}] - set_property IOSTANDARD LVCMOS33 [get_ports {switches[9]}] -set_property PACKAGE_PIN U2 [get_ports {switches[10]}] - set_property IOSTANDARD LVCMOS33 [get_ports {switches[10]}] -set_property PACKAGE_PIN T3 [get_ports {switches[11]}] - set_property IOSTANDARD LVCMOS33 [get_ports {switches[11]}] -set_property PACKAGE_PIN T1 [get_ports {switches[12]}] - set_property IOSTANDARD LVCMOS33 [get_ports {switches[12]}] -set_property PACKAGE_PIN R3 [get_ports {switches[13]}] - set_property IOSTANDARD LVCMOS33 [get_ports {switches[13]}] -set_property PACKAGE_PIN P3 [get_ports {switches[14]}] - set_property IOSTANDARD LVCMOS33 [get_ports {switches[14]}] -set_property PACKAGE_PIN P4 [get_ports {switches[15]}] - set_property IOSTANDARD LVCMOS33 [get_ports {switches[15]}] - -# LEDs: -set_property PACKAGE_PIN T8 [get_ports {leds[0]}] - set_property IOSTANDARD LVCMOS33 [get_ports {leds[0]}] -set_property PACKAGE_PIN V9 [get_ports {leds[1]}] - set_property IOSTANDARD LVCMOS33 [get_ports {leds[1]}] -set_property PACKAGE_PIN R8 [get_ports {leds[2]}] - set_property IOSTANDARD LVCMOS33 [get_ports {leds[2]}] -set_property PACKAGE_PIN T6 [get_ports {leds[3]}] - set_property IOSTANDARD LVCMOS33 [get_ports {leds[3]}] -set_property PACKAGE_PIN T5 [get_ports {leds[4]}] - set_property IOSTANDARD LVCMOS33 [get_ports {leds[4]}] -set_property PACKAGE_PIN T4 [get_ports {leds[5]}] - set_property IOSTANDARD LVCMOS33 [get_ports {leds[5]}] -set_property PACKAGE_PIN U7 [get_ports {leds[6]}] - set_property IOSTANDARD LVCMOS33 [get_ports {leds[6]}] -set_property PACKAGE_PIN U6 [get_ports {leds[7]}] - set_property IOSTANDARD LVCMOS33 [get_ports {leds[7]}] -set_property PACKAGE_PIN V4 [get_ports {leds[8]}] - set_property IOSTANDARD LVCMOS33 [get_ports {leds[8]}] -set_property PACKAGE_PIN U3 [get_ports {leds[9]}] - set_property IOSTANDARD LVCMOS33 [get_ports {leds[9]}] -set_property PACKAGE_PIN V1 [get_ports {leds[10]}] - set_property IOSTANDARD LVCMOS33 [get_ports {leds[10]}] -set_property PACKAGE_PIN R1 [get_ports {leds[11]}] - set_property IOSTANDARD LVCMOS33 [get_ports {leds[11]}] -set_property PACKAGE_PIN P5 [get_ports {leds[12]}] - set_property IOSTANDARD LVCMOS33 [get_ports {leds[12]}] -set_property PACKAGE_PIN U1 [get_ports {leds[13]}] - set_property IOSTANDARD LVCMOS33 [get_ports {leds[13]}] -set_property PACKAGE_PIN R2 [get_ports {leds[14]}] - set_property IOSTANDARD LVCMOS33 [get_ports {leds[14]}] -set_property PACKAGE_PIN P2 [get_ports {leds[15]}] - set_property IOSTANDARD LVCMOS33 [get_ports {leds[15]}] Index: new-privileged-isa/example/tb_toplevel.vhd =================================================================== --- new-privileged-isa/example/tb_toplevel.vhd (revision 57) +++ new-privileged-isa/example/tb_toplevel.vhd (nonexistent) @@ -1,58 +0,0 @@ --- Practical Test Application for the Potato Processor --- (c) Kristian Klomsten Skordal 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; - -entity tb_toplevel is -end entity tb_toplevel; - -architecture testbench of tb_toplevel is - - signal clk : std_logic; - constant clk_period : time := 10 ns; - - signal reset_n : std_logic := '0'; - signal external_interrupt : std_logic := '0'; - - signal switches : std_logic_vector(15 downto 0); - signal leds : std_logic_vector(15 downto 0); - - signal uart_rxd : std_logic := '1'; - signal uart_txd : std_logic; - -begin - - switches <= x"a0a0"; - - uut: entity work.toplevel - port map( - clk => clk, - reset_n => reset_n, - external_interrupt => external_interrupt, - switches => switches, - leds => leds, - uart_rxd => uart_rxd, - uart_txd => uart_txd - ); - - clock: process - begin - clk <= '0'; - wait for clk_period / 2; - clk <= '1'; - wait for clk_period / 2; - end process clock; - - stimulus: process - begin - wait for clk_period * 125; - reset_n <= '0'; - wait for clk_period * 3; - reset_n <= '1'; - - wait; - end process stimulus; - -end architecture testbench; Index: new-privileged-isa/example/imem_wrapper.vhd =================================================================== --- new-privileged-isa/example/imem_wrapper.vhd (revision 57) +++ new-privileged-isa/example/imem_wrapper.vhd (nonexistent) @@ -1,68 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; - -entity imem_wrapper is - port( - clk : in std_logic; - reset : in std_logic; - - -- Wishbone interface: - wb_adr_in : in std_logic_vector(12 downto 0); - wb_dat_out : out std_logic_vector(31 downto 0); - wb_cyc_in : in std_logic; - wb_stb_in : in std_logic; - wb_ack_out : out std_logic - ); -end entity imem_wrapper; - -architecture behaviour of imem_wrapper is - - type wb_state is (IDLE, READ_ACK); - signal state : wb_state := IDLE; - - signal address : std_logic_vector(10 downto 0); - signal data : std_logic_vector(31 downto 0); - - signal ack : std_logic := '0'; - -begin - - imem: entity work.instruction_rom - port map( - clka => clk, - addra => address, - douta => wb_dat_out - ); - - wb_ack_out <= ack and wb_cyc_in and wb_stb_in; - - wishbone: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - ack <= '0'; - state <= IDLE; - else - case state is - when IDLE => - if wb_cyc_in = '1' and wb_stb_in = '1' then - address <= wb_adr_in(12 downto 2); - state <= READ_ACK; - end if; - when READ_ACK => - if ack = '0' then - ack <= '1'; - elsif wb_stb_in = '0' then - ack <= '0'; - state <= IDLE; - end if; - end case; - end if; - end if; - end process wishbone; - -end architecture behaviour; Index: new-privileged-isa/example/toplevel.vhd =================================================================== --- new-privileged-isa/example/toplevel.vhd (revision 57) +++ new-privileged-isa/example/toplevel.vhd (nonexistent) @@ -1,373 +0,0 @@ --- Practical Test Application for the Potato Processor --- (c) Kristian Klomsten Skordal 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; - -entity toplevel is - port( - clk : in std_logic; -- System clock, 100 MHz - reset_n : in std_logic; -- CPU reset signal, active low - - -- External interrupt input: - external_interrupt : in std_logic; - - -- GPIO pins, must be inout to use with the GPIO module: - switches : inout std_logic_vector(15 downto 0); - leds : inout std_logic_vector(15 downto 0); - - -- UART1 (host) pins: - uart_txd : out std_logic; - uart_rxd : in std_logic - ); -end entity toplevel; - -architecture behaviour of toplevel is - signal system_clk : std_logic; - signal timer_clk : std_logic; - - -- Active high reset signal: - signal reset : std_logic; - - -- IRQs: - signal irq : std_logic_vector(7 downto 0); - signal uart_irq_rts, uart_irq_recv : std_logic; - signal timer_irq : std_logic; - - -- Processor wishbone interface: - signal p_adr_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_sel_out : std_logic_vector( 3 downto 0); - signal p_we_out : std_logic; - signal p_cyc_out, p_stb_out : std_logic; - signal p_ack_in : std_logic; - - -- Instruction memory wishbone interface: - signal imem_adr_in : std_logic_vector(12 downto 0); - signal imem_dat_out : std_logic_vector(31 downto 0); - signal imem_cyc_in, imem_stb_in : std_logic; - signal imem_ack_out : std_logic; - - -- Data memory wishbone interface: - signal dmem_adr_in : std_logic_vector(12 downto 0); - signal dmem_dat_in : std_logic_vector(31 downto 0); - signal dmem_dat_out : std_logic_vector(31 downto 0); - signal dmem_sel_in : std_logic_vector( 3 downto 0); - signal dmem_we_in : std_logic; - signal dmem_cyc_in, dmem_stb_in : std_logic; - signal dmem_ack_out : std_logic; - - -- GPIO module I (switches) wishbone interface: - signal gpio1_adr_in : std_logic_vector(1 downto 0); - signal gpio1_dat_in : std_logic_vector(31 downto 0); - signal gpio1_dat_out : std_logic_vector(31 downto 0); - signal gpio1_we_in : std_logic; - signal gpio1_cyc_in, gpio1_stb_in : std_logic; - signal gpio1_ack_out : std_logic; - - -- GPIO module II (LEDs) wishbone interface: - signal gpio2_adr_in : std_logic_vector(1 downto 0); - signal gpio2_dat_in : std_logic_vector(31 downto 0); - signal gpio2_dat_out : std_logic_vector(31 downto 0); - signal gpio2_we_in : std_logic; - signal gpio2_cyc_in, gpio2_stb_in : std_logic; - signal gpio2_ack_out : std_logic; - - -- UART module wishbone interface: - signal uart_adr_in : std_logic_vector(1 downto 0); - signal uart_dat_in : std_logic_vector(7 downto 0); - signal uart_dat_out : std_logic_vector(7 downto 0); - signal uart_we_in : std_logic; - signal uart_cyc_in, uart_stb_in : std_logic; - signal uart_ack_out : std_logic; - - -- Timer module wishbone interface: - signal timer_adr_in : std_logic_vector(1 downto 0); - signal timer_dat_in : std_logic_vector(31 downto 0); - signal timer_dat_out : std_logic_vector(31 downto 0); - signal timer_we_in : std_logic; - signal timer_cyc_in, timer_stb_in : std_logic; - signal timer_ack_out : std_logic; - - -- Dummy module interface: - signal dummy_dat_in : std_logic_vector(31 downto 0); - signal dummy_dat_out : std_logic_vector(31 downto 0); - signal dummy_we_in : std_logic; - signal dummy_cyc_in, dummy_stb_in : std_logic; - signal dummy_ack_out : std_logic; - - -- Address decoder signals: - type ad_state_type is (IDLE, BUSY); - signal ad_state : ad_state_type; - - type module_name is ( - MODULE_IMEM, MODULE_DMEM, -- Memory modules - MODULE_GPIO1, MODULE_GPIO2, -- GPIO modules - MODULE_UART, -- UART module - MODULE_TIMER, -- Timer module - MODULE_DUMMY, -- Dummy module, used for invalid addresses - MODULE_NONE -- Boring no-module mode - ); - signal active_module : module_name; - -begin - - reset <= not reset_n; - irq <= ( - 0 => external_interrupt, - 1 => uart_irq_rts, 2 => uart_irq_recv, - 5 => timer_irq, others => '0' - ); - - clkgen: entity work.clock_generator - port map( - clk => clk, - system_clk => system_clk, - timer_clk => timer_clk - ); - - processor: entity work.pp_potato - port map( - clk => system_clk, - timer_clk => timer_clk, - reset => reset, - irq => irq, - fromhost_data => (others => '0'), - fromhost_updated => '0', - tohost_data => open, - tohost_updated => open, - wb_adr_out => p_adr_out, - wb_dat_out => p_dat_out, - wb_dat_in => p_dat_in, - wb_sel_out => p_sel_out, - wb_we_out => p_we_out, - wb_cyc_out => p_cyc_out, - wb_stb_out => p_stb_out, - wb_ack_in => p_ack_in - ); - - imem: entity work.imem_wrapper - port map( - clk => system_clk, - reset => reset, - wb_adr_in => imem_adr_in, - wb_dat_out => imem_dat_out, - wb_cyc_in => imem_cyc_in, - wb_stb_in => imem_stb_in, - wb_ack_out => imem_ack_out - ); - - dmem: entity work.pp_soc_memory - generic map( - MEMORY_SIZE => 8192 - ) port map( - clk => system_clk, - reset => reset, - wb_adr_in => dmem_adr_in, - wb_dat_in => dmem_dat_in, - wb_dat_out => dmem_dat_out, - wb_sel_in => dmem_sel_in, - wb_we_in => dmem_we_in, - wb_cyc_in => dmem_cyc_in, - wb_stb_in => dmem_stb_in, - wb_ack_out => dmem_ack_out - ); - - gpio1: entity work.pp_soc_gpio - generic map( - NUM_GPIOS => 16 - ) port map( - clk => system_clk, - reset => reset, - gpio => switches, - wb_adr_in => gpio1_adr_in, - wb_dat_in => gpio1_dat_in, - wb_dat_out => gpio1_dat_out, - wb_cyc_in => gpio1_cyc_in, - wb_stb_in => gpio1_stb_in, - wb_we_in => gpio1_we_in, - wb_ack_out => gpio1_ack_out - ); - - gpio2: entity work.pp_soc_gpio - generic map( - NUM_GPIOS => 16 - ) port map( - clk => system_clk, - reset => reset, - gpio => leds, - wb_adr_in => gpio2_adr_in, - wb_dat_in => gpio2_dat_in, - wb_dat_out => gpio2_dat_out, - wb_cyc_in => gpio2_cyc_in, - wb_stb_in => gpio2_stb_in, - wb_we_in => gpio2_we_in, - wb_ack_out => gpio2_ack_out - ); - - uart1: entity work.pp_soc_uart - generic map( - FIFO_DEPTH => 64, - SAMPLE_CLK_DIVISOR => 27 -- For 50 MHz - --SAMPLE_CLK_DIVISOR => 33 -- For 60 MHz - ) port map( - clk => system_clk, - reset => reset, - txd => uart_txd, - rxd => uart_rxd, - irq_send_buffer_empty => uart_irq_rts, - irq_data_received => uart_irq_recv, - wb_adr_in => uart_adr_in, - wb_dat_in => uart_dat_in, - wb_dat_out => uart_dat_out, - wb_cyc_in => uart_cyc_in, - wb_stb_in => uart_stb_in, - wb_we_in => uart_we_in, - wb_ack_out => uart_ack_out - ); - - timer1: entity work.pp_soc_timer - port map( - clk => system_clk, - reset => reset, - irq => timer_irq, - wb_adr_in => timer_adr_in, - wb_dat_in => timer_dat_in, - wb_dat_out => timer_dat_out, - wb_cyc_in => timer_cyc_in, - wb_stb_in => timer_stb_in, - wb_we_in => timer_we_in, - wb_ack_out => timer_ack_out - ); - - dummy: entity work.pp_soc_dummy - port map( - clk => system_clk, - reset => reset, - wb_dat_in => dummy_dat_in, - wb_dat_out => dummy_dat_out, - wb_cyc_in => dummy_cyc_in, - wb_stb_in => dummy_stb_in, - wb_we_in => dummy_we_in, - wb_ack_out => dummy_ack_out - ); - - imem_cyc_in <= p_cyc_out when active_module = MODULE_IMEM else '0'; - dmem_cyc_in <= p_cyc_out when active_module = MODULE_DMEM else '0'; - gpio1_cyc_in <= p_cyc_out when active_module = MODULE_GPIO1 else '0'; - gpio2_cyc_in <= p_cyc_out when active_module = MODULE_GPIO2 else '0'; - uart_cyc_in <= p_cyc_out when active_module = MODULE_UART else '0'; - timer_cyc_in <= p_cyc_out when active_module = MODULE_TIMER else '0'; - dummy_cyc_in <= p_cyc_out when active_module = MODULE_DUMMY else '0'; - - imem_stb_in <= p_stb_out when active_module = MODULE_IMEM else '0'; - dmem_stb_in <= p_stb_out when active_module = MODULE_DMEM else '0'; - gpio1_stb_in <= p_stb_out when active_module = MODULE_GPIO1 else '0'; - gpio2_stb_in <= p_stb_out when active_module = MODULE_GPIO2 else '0'; - uart_stb_in <= p_stb_out when active_module = MODULE_UART else '0'; - timer_stb_in <= p_stb_out when active_module = MODULE_TIMER else '0'; - dummy_stb_in <= p_stb_out when active_module = MODULE_DUMMY else '0'; - - imem_adr_in <= p_adr_out(12 downto 0); - dmem_adr_in <= p_adr_out(12 downto 0); - gpio1_adr_in <= p_adr_out(3 downto 2); - gpio2_adr_in <= p_adr_out(3 downto 2); - uart_adr_in <= p_adr_out(3 downto 2); - timer_adr_in <= p_adr_out(3 downto 2); - - dmem_dat_in <= p_dat_out; - gpio1_dat_in <= p_dat_out; - gpio2_dat_in <= p_dat_out; - uart_dat_in <= p_dat_out(7 downto 0); - timer_dat_in <= p_dat_out; - dummy_dat_in <= p_dat_out; - - dmem_sel_in <= p_sel_out; - - gpio1_we_in <= p_we_out; - gpio2_we_in <= p_we_out; - dmem_we_in <= p_we_out; - uart_we_in <= p_we_out; - timer_we_in <= p_we_out; - dummy_we_in <= p_we_out; - - address_decoder: process(system_clk) - begin - if rising_edge(system_clk) then - if reset = '1' then - ad_state <= IDLE; - active_module <= MODULE_NONE; - else - case ad_state is - when IDLE => - if p_cyc_out = '1' then - if p_adr_out(31 downto 13) = b"0000000000000000000" then - active_module <= MODULE_IMEM; - ad_state <= BUSY; - elsif p_adr_out(31 downto 13) = b"0000000000000000001" then -- 0x2000 - active_module <= MODULE_DMEM; - ad_state <= BUSY; - elsif p_adr_out(31 downto 11) = b"000000000000000001000" then -- 0x4000 - active_module <= MODULE_GPIO1; - ad_state <= BUSY; - elsif p_adr_out(31 downto 11) = b"000000000000000001001" then -- 0x4800 - active_module <= MODULE_GPIO2; - ad_state <= BUSY; - elsif p_adr_out(31 downto 11) = b"000000000000000001010" then -- 0x5000 - active_module <= MODULE_UART; - ad_state <= BUSY; - elsif p_adr_out(31 downto 11) = b"000000000000000001011" then -- 0x5800 - active_module <= MODULE_TIMER; - ad_state <= BUSY; - else - active_module <= MODULE_DUMMY; - ad_state <= BUSY; - end if; - else - active_module <= MODULE_NONE; - end if; - when BUSY => - if p_cyc_out = '0' then - active_module <= MODULE_NONE; - ad_state <= IDLE; - end if; - end case; - end if; - end if; - end process address_decoder; - - module_mux: process(active_module, imem_ack_out, imem_dat_out, dmem_ack_out, dmem_dat_out, - gpio1_ack_out, gpio1_dat_out, gpio2_ack_out, gpio2_dat_out, uart_ack_out, uart_dat_out, - timer_ack_out, timer_dat_out, dummy_ack_out, dummy_dat_out) - begin - case active_module is - when MODULE_IMEM => - p_ack_in <= imem_ack_out; - p_dat_in <= imem_dat_out; - when MODULE_DMEM => - p_ack_in <= dmem_ack_out; - p_dat_in <= dmem_dat_out; - when MODULE_GPIO1 => - p_ack_in <= gpio1_ack_out; - p_dat_in <= gpio1_dat_out; - when MODULE_GPIO2 => - p_ack_in <= gpio2_ack_out; - p_dat_in <= gpio2_dat_out; - when MODULE_UART => - p_ack_in <= uart_ack_out; - p_dat_in <= (31 downto 8 => '0') & uart_dat_out; - when MODULE_TIMER => - p_ack_in <= timer_ack_out; - p_dat_in <= timer_dat_out; - when MODULE_DUMMY => - p_ack_in <= dummy_ack_out; - p_dat_in <= dummy_dat_out; - when MODULE_NONE => - p_ack_in <= '0'; - p_dat_in <= (others => '0'); - end case; - end process module_mux; - -end architecture behaviour; Index: new-privileged-isa/example/tb_imem_wrapper.vhd =================================================================== --- new-privileged-isa/example/tb_imem_wrapper.vhd (revision 57) +++ new-privileged-isa/example/tb_imem_wrapper.vhd (nonexistent) @@ -1,69 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2015 --- Report bugs and issues on - -library ieee; -use ieee.std_logic_1164.all; - -entity tb_imem_wrapper is -end entity tb_imem_wrapper; - -architecture testbench of tb_imem_wrapper is - - -- Clock signal: - signal clk : std_logic := '0'; - constant clk_period : time := 10 ns; - - -- Reset signal: - signal reset : std_logic := '1'; - - -- Wishbone signals: - signal wb_adr_in : std_logic_vector(10 downto 0); - signal wb_dat_out : std_logic_vector(31 downto 0); - signal wb_cyc_in : std_logic := '0'; - signal wb_stb_in : std_logic := '0'; - signal wb_ack_out : std_logic; - -begin - - uut: entity work.imem_wrapper - port map( - clk => clk, - reset => reset, - wb_adr_in => wb_adr_in, - wb_dat_out => wb_dat_out, - wb_cyc_in => wb_cyc_in, - wb_stb_in => wb_stb_in, - wb_ack_out => wb_ack_out - ); - - clock: process - begin - clk <= '1'; - wait for clk_period; - clk <= '0'; - wait for clk_period; - end process clock; - - stimulus: process - begin - wait for clk_period * 2; - reset <= '0'; - wait for clk_period; - - -- Read an instruction: - wb_adr_in <= (others => '0'); - wb_cyc_in <= '1'; - wb_stb_in <= '1'; - wait for clk_period; - wait until wb_ack_out = '1'; - wait for clk_period; - wb_cyc_in <= '0'; - wb_stb_in <= '0'; - - -- TODO: Make testbench automated. - - wait; - end process stimulus; - -end architecture testbench; Index: new-privileged-isa/README =================================================================== --- new-privileged-isa/README (revision 57) +++ new-privileged-isa/README (nonexistent) @@ -1,43 +0,0 @@ -# The Potato Processor - -Potato is a simple processor for use in FPGAs, implementing the RV32I subset of the RISC-V ISA specification. - -## Features - -* Supports the full RV32I (RISC-V 32-bit integer subset) ISA. -* Additionally supports the csrr\* and sret instructions from the (previous) supervisor extension (draft). -* Includes an interface for the HTIF (Host/Target interface) registers, TOHOST and FROMHOST. -* Wishbone interface. - -## Wishbone details - -The wishbone interface for the processor is provided by the pp_wb_adapter module. Its details are as follows: - -|-----------------------|---------------| -| Name | Value | -| --------------------- | ------------- | -| Wishbone revision | B4 | -| Interface type | Master | -| Address port width | 32 bits | -| Data port width | 32 bits | -| Data port granularity | 8 bits | -| Maximum operand size | 32 bits | -| Endianess | Little endian | -| Sequence of data xfer | Undefined | -|---------------------------------------| - -For all Wishbone interfaces included in this project, the Wishbone signals are prefixed with `wb` and suffixed by the -signal direction. - -## Potato Processor Quick Start - -To instantiate the processor, add the source files from the `src/` folder to your project. Use the `pp_potato` core to -instantiate a processor core with a Wishbone interface. Additional peripherals for use in Wishbone-based Potato systems -can be found in the `soc/` folder. - -Use the `pp_core` module to instantiate a processor core with a more generic interface, for instance for use with block -memories. In this instance, connect the data and instruction memory ports directly to the block RAM modules/interfaces -and set the acknowledge inputs to `'1'`. - -Interrupts are triggered when an IRQ signal is high and the corresponding mask bit is set in the control/status register. - Index: new-privileged-isa/Makefile =================================================================== --- new-privileged-isa/Makefile (revision 57) +++ new-privileged-isa/Makefile (nonexistent) @@ -1,139 +0,0 @@ -# The Potato Processor - A simple RISC-V based processor for FPGAs -# (c) Kristian Klomsten Skordal 2014 - 2015 -# Report bugs and issues on - -.PHONY: all clean checkout-riscv-tests potato.prj - -SOURCE_FILES := \ - src/pp_alu.vhd \ - src/pp_alu_mux.vhd \ - src/pp_alu_control_unit.vhd \ - src/pp_icache.vhd \ - src/pp_comparator.vhd \ - src/pp_constants.vhd \ - src/pp_control_unit.vhd \ - src/pp_core.vhd \ - src/pp_counter.vhd \ - src/pp_csr.vhd \ - src/pp_csr_unit.vhd \ - src/pp_csr_alu.vhd \ - src/pp_decode.vhd \ - src/pp_execute.vhd \ - src/pp_fetch.vhd \ - src/pp_imm_decoder.vhd \ - src/pp_memory.vhd \ - src/pp_potato.vhd \ - src/pp_register_file.vhd \ - src/pp_types.vhd \ - src/pp_utilities.vhd \ - src/pp_wb_arbiter.vhd \ - src/pp_wb_adapter.vhd \ - src/pp_writeback.vhd -TESTBENCHES := \ - testbenches/tb_processor.vhd \ - testbenches/tb_soc.vhd \ - soc/pp_soc_memory.vhd - -TOOLCHAIN_PREFIX ?= riscv64-unknown-elf - -# ISA tests to use from the riscv-tests repository: -RISCV_TESTS += \ - simple \ - add \ - addi \ - and \ - andi \ - auipc \ - beq \ - bge \ - bgeu \ - blt \ - bltu \ - bne \ - jal \ - jalr \ - j \ - or \ - ori \ - sll \ - slli \ - slt \ - slti \ - sra \ - srai \ - srl \ - srli \ - sub \ - sb \ - sh \ - sw \ - xor \ - xori \ - lui \ - lb \ - lbu \ - lh \ - lhu \ - lw \ - ma_addr \ - sbreak \ - scall - -# Local tests to run: -LOCAL_TESTS ?= \ - timer \ - sw-jal - -all: potato.prj run-tests - -potato.prj: - -$(RM) potato.prj - for file in $(SOURCE_FILES) $(TESTBENCHES); do \ - echo "vhdl work $$file" >> potato.prj; \ - done - -copy-riscv-tests: - for test in $(RISCV_TESTS); do \ - cp riscv-tests/$$test.S tests; \ - done - -compile-tests: copy-riscv-tests - test -d tests-build || mkdir tests-build - for test in $(RISCV_TESTS) $(LOCAL_TESTS); do \ - echo "Compiling test $$test..."; \ - $(TOOLCHAIN_PREFIX)-gcc -c -m32 -march=RV32I -Iriscv-tests -o tests-build/$$test.o tests/$$test.S; \ - $(TOOLCHAIN_PREFIX)-ld -m elf32lriscv -T tests.ld tests-build/$$test.o -o tests-build/$$test.elf; \ - scripts/extract_hex.sh tests-build/$$test.elf tests-build/$$test-imem.hex tests-build/$$test-dmem.hex; \ - done - -run-tests: potato.prj compile-tests - for test in $(RISCV_TESTS) $(LOCAL_TESTS); do \ - echo -ne "Running test $$test:\t"; \ - DMEM_FILENAME="empty_dmem.hex"; \ - test -f tests-build/$$test-dmem.hex && DMEM_FILENAME="tests-build/$$test-dmem.hex"; \ - xelab tb_processor -generic_top "IMEM_FILENAME=tests-build/$$test-imem.hex" -generic_top "DMEM_FILENAME=$$DMEM_FILENAME" -prj potato.prj > /dev/null; \ - xsim tb_processor -R --onfinish quit > tests-build/$$test.results; \ - cat tests-build/$$test.results | awk '/Note:/ {print}' | sed 's/Note://' | awk '/Success|Failure/ {print}'; \ - done - -run-soc-tests: potato.prj compile-tests - for test in $(RISCV_TESTS) $(LOCAL_TESTS); do \ - echo -ne "Running SOC test $$test:\t"; \ - DMEM_FILENAME="empty_dmem.hex"; \ - test -f tests-build/$$test-dmem.hex && DMEM_FILENAME="tests-build/$$test-dmem.hex"; \ - xelab tb_soc -generic_top "IMEM_FILENAME=tests-build/$$test-imem.hex" -generic_top "DMEM_FILENAME=$$DMEM_FILENAME" -prj potato.prj > /dev/null; \ - xsim tb_soc -R --onfinish quit > tests-build/$$test.results-soc; \ - cat tests-build/$$test.results-soc | awk '/Note:/ {print}' | sed 's/Note://' | awk '/Success|Failure/ {print}'; \ - done - -remove-xilinx-garbage: - -$(RM) -r xsim.dir - -$(RM) xelab.* webtalk* xsim* - -clean: remove-xilinx-garbage - for test in $(RISCV_TESTS); do $(RM) tests/$$test.S; done - -$(RM) -r tests-build - -$(RM) potato.prj - -distclean: clean - Index: new-privileged-isa/benchmarks/hello/main.c =================================================================== --- new-privileged-isa/benchmarks/hello/main.c (revision 57) +++ new-privileged-isa/benchmarks/hello/main.c (nonexistent) @@ -1,26 +0,0 @@ -// The Potato Processor Benchmark Applications -// (c) Kristian Klomsten Skordal 2015 -// Report bugs and issues on - -#include -#include "../platform.h" - -void exception_handler(uint32_t cause, void * epc, void * regbase) -{ - // Not used in this application -} - -int main(void) -{ - const char * hello_string = "Hello world\n\r"; - volatile uint32_t * uart = IO_ADDRESS(UART_BASE); - - for(int i = 0; hello_string[i] != 0; ++i) - { - while(uart[UART_STATUS >> 2] & (1 << 3)); - uart[UART_TX >> 2] = hello_string[i] & 0x000000ff; - } - - return 0; -} - Index: new-privileged-isa/benchmarks/hello/Makefile =================================================================== --- new-privileged-isa/benchmarks/hello/Makefile (revision 57) +++ new-privileged-isa/benchmarks/hello/Makefile (nonexistent) @@ -1,46 +0,0 @@ -# The Potato Processor Benchmark Applications -# (c) Kristian Klomsten Skordal 2015 -# Report bugs and issues on - -.PHONY: all clean - -TARGET_PREFIX ?= riscv64-unknown-elf -TARGET_CC := $(TARGET_PREFIX)-gcc -TARGET_LD := $(TARGET_PREFIX)-ld -TARGET_SIZE := $(TARGET_PREFIX)-size -TARGET_OBJCOPY := $(TARGET_PREFIX)-objcopy -HEXDUMP ?= hexdump - -TARGET_CFLAGS += -m32 -march=RV32I -Wall -O2 -fomit-frame-pointer \ - -ffreestanding -fno-builtin -I.. -std=gnu99 -TARGET_LDFLAGS += -m elf32lriscv -T../benchmark.ld - -OBJECTS := main.o start.o - -all: hello.coe - -hello.elf: $(OBJECTS) - $(TARGET_LD) -o hello.elf $(TARGET_LDFLAGS) $(OBJECTS) - $(TARGET_SIZE) hello.elf - -hello.bin: hello.elf - $(TARGET_OBJCOPY) -j .text -j .data -O binary hello.elf hello.bin - -hello.coe: hello.bin - echo "memory_initialization_radix=16;" > hello.coe - echo "memory_initialization_vector=" >> hello.coe - $(HEXDUMP) -v -e '1/4 "%08x\n"' hello.bin >> hello.coe - echo ";" >> hello.coe - -clean: - -$(RM) $(OBJECTS) - -$(RM) hello.elf hello.bin hello.coe - -# Object file rules: - -main.o: main.c ../platform.h ../potato.h - $(TARGET_CC) -c -o $@ $(TARGET_CFLAGS) $< - -start.o: ../start.S ../platform.h - $(TARGET_CC) -c -o $@ $(TARGET_CFLAGS) $< - Index: new-privileged-isa/benchmarks/benchmark.ld =================================================================== --- new-privileged-isa/benchmarks/benchmark.ld (revision 57) +++ new-privileged-isa/benchmarks/benchmark.ld (nonexistent) @@ -1,41 +0,0 @@ -/* - * Linker Script for the Potato Processor benchmark applications - * (c) Kristian Klomsten Skordal 2014 - 2015 -// Report bugs and issues on - */ - -/* - * The linker script is intended to be used with the "official" test platform, - * described in platform.h. - */ - -ENTRY(_start); - -SECTIONS -{ - .text 0x100 : - { - *(.init) - *(.text*) - __text_end = .; - } - - .data 0x2000 : AT(ADDR(.text) + SIZEOF(.text)) - { - __data_begin = .; - *(.rodata*) - *(.data*) - __data_end = ALIGN(4); - } - - .bss ALIGN(4): - { - __bss_begin = .; - *(.bss*) - __bss_end = ALIGN(4); - } - - __stack_top = 0x4000; -} - - Index: new-privileged-isa/benchmarks/sha256/utilities.c =================================================================== --- new-privileged-isa/benchmarks/sha256/utilities.c (revision 57) +++ new-privileged-isa/benchmarks/sha256/utilities.c (nonexistent) @@ -1,14 +0,0 @@ -// The Potato Processor Benchmark Applications -// (c) Kristian Klomsten Skordal 2015 -// Report bugs and issues on - -#include "utilities.h" - -void * memset(void * s, int c, int n) -{ - char * temp = s; - for(int i = 0; i < n; ++i) - temp[i] = c; - return s; -} - Index: new-privileged-isa/benchmarks/sha256/uart.c =================================================================== --- new-privileged-isa/benchmarks/sha256/uart.c (revision 57) +++ new-privileged-isa/benchmarks/sha256/uart.c (nonexistent) @@ -1,32 +0,0 @@ -// The Potato Processor Benchmark Applications -// (c) Kristian Klomsten Skordal 2015 -// Report bugs and issues on - -#include -#include - -#include "platform.h" -#include "uart.h" - -void uart_puts(volatile uint32_t * base, const char * s) -{ - for(int i = 0; s[i] != 0; ++i) - uart_putc(base, s[i]); -} - -void uart_putc(volatile uint32_t * base, char c) -{ - // Wait until there is room in the transmit buffer: - while(base[UART_STATUS >> 2] & (1 << 3)); - base[UART_TX >> 2] = c & 0x000000ff; -} - -void uart_puth(volatile uint32_t * base, uint32_t n) -{ - static const char * hex_digits = "0123456789abcdef"; - uart_putc(base, '0'); - uart_putc(base, 'x'); - for(int i = 28; i >= 0; i -= 4) - uart_putc(base, hex_digits[(n >> i) & 0xf]); -} - Index: new-privileged-isa/benchmarks/sha256/Makefile =================================================================== --- new-privileged-isa/benchmarks/sha256/Makefile (revision 57) +++ new-privileged-isa/benchmarks/sha256/Makefile (nonexistent) @@ -1,62 +0,0 @@ -# The Potato Processor Benchmark Applications -# (c) Kristian Klomsten Skordal 2015 -# Report bugs and issues on - -.PHONY: all clean - -TARGET_PREFIX ?= riscv64-unknown-elf -TARGET_CC := $(TARGET_PREFIX)-gcc -TARGET_LD := $(TARGET_PREFIX)-ld -TARGET_SIZE := $(TARGET_PREFIX)-size -TARGET_OBJCOPY := $(TARGET_PREFIX)-objcopy -HEXDUMP ?= hexdump - -TARGET_CFLAGS += -m32 -march=RV32I -Wall -Os -fomit-frame-pointer \ - -ffreestanding -fno-builtin -I.. -std=gnu99 -TARGET_LDFLAGS += -m elf32lriscv -T../benchmark.ld - -OBJECTS := gpio.o main.o sha256.o start.o timer.o uart.o utilities.o - -all: sha256.coe - -sha256.elf: $(OBJECTS) - $(TARGET_LD) -o sha256.elf $(TARGET_LDFLAGS) $(OBJECTS) - $(TARGET_SIZE) sha256.elf - -sha256.bin: sha256.elf - $(TARGET_OBJCOPY) -j .text -j .data -O binary sha256.elf sha256.bin - -sha256.coe: sha256.bin - echo "memory_initialization_radix=16;" > sha256.coe - echo "memory_initialization_vector=" >> sha256.coe - for i in $$(seq 0 63); do echo 00000013 >> sha256.coe; done - $(HEXDUMP) -v -e '1/4 "%08x\n"' sha256.bin >> sha256.coe - echo ";" >> sha256.coe - -clean: - -$(RM) $(OBJECTS) - -$(RM) sha256.elf sha256.bin sha256.coe - -# Object file rules: - -gpio.o: gpio.c gpio.h ../platform.h - $(TARGET_CC) -c -o $@ $(TARGET_CFLAGS) $< - -main.o: main.c gpio.h timer.h sha256.h ../platform.h ../potato.h - $(TARGET_CC) -c -o $@ $(TARGET_CFLAGS) $< - -sha256.o: sha256.c sha256.h - $(TARGET_CC) -c -o $@ $(TARGET_CFLAGS) $< - -start.o: ../start.S ../platform.h - $(TARGET_CC) -c -o $@ $(TARGET_CFLAGS) $< - -timer.o: timer.c timer.h ../platform.h - $(TARGET_CC) -c -o $@ $(TARGET_CFLAGS) $< - -uart.o: uart.c uart.h ../platform.h - $(TARGET_CC) -c -o $@ $(TARGET_CFLAGS) $< - -utilities.o: utilities.c utilities.h - $(TARGET_CC) -c -o $@ $(TARGET_CFLAGS) $< - Index: new-privileged-isa/benchmarks/sha256/sha256.h =================================================================== --- new-privileged-isa/benchmarks/sha256/sha256.h (revision 57) +++ new-privileged-isa/benchmarks/sha256/sha256.h (nonexistent) @@ -1,31 +0,0 @@ -// The Potato Processor Benchmark Applications -// (c) Kristian Klomsten Skordal 2015 -// Report bugs and issues on - -#ifndef SHA256_H -#define SHA256_H - -#include - -struct sha256_context -{ - uint32_t intermediate[8]; -}; - -// Resets a SHA256 context: -void sha256_reset(struct sha256_context * ctx); - -// Hash a block of data: -void sha256_hash_block(struct sha256_context * ctx, const uint32_t * data); - -// Pad a block of data to hash: -void sha256_pad_le_block(uint8_t * block, int block_length, uint64_t total_length); - -// Get the hash from a SHA256 context: -void sha256_get_hash(const struct sha256_context * ctx, uint8_t * hash); - -// Formats a hash for printing: -void sha256_format_hash(const uint8_t * hash, char * output); - -#endif - Index: new-privileged-isa/benchmarks/sha256/gpio.c =================================================================== --- new-privileged-isa/benchmarks/sha256/gpio.c (revision 57) +++ new-privileged-isa/benchmarks/sha256/gpio.c (nonexistent) @@ -1,23 +0,0 @@ -// The Potato Processor Benchmark Applications -// (c) Kristian Klomsten Skordal 2015 -// Report bugs and issues on - -#include "gpio.h" -#include "platform.h" - -void gpio_set_direction(volatile uint32_t * base, uint32_t direction) -{ - base[GPIO_DIR >> 2] = direction; -} - -void gpio_set_output(volatile uint32_t * base, uint32_t output) -{ - base[GPIO_OUTPUT >> 2] = output; -} - -uint32_t gpio_get_value(volatile uint32_t * base) -{ - return base[GPIO_INPUT >> 2]; -} - - Index: new-privileged-isa/benchmarks/sha256/uart.h =================================================================== --- new-privileged-isa/benchmarks/sha256/uart.h (revision 57) +++ new-privileged-isa/benchmarks/sha256/uart.h (nonexistent) @@ -1,17 +0,0 @@ -// The Potato Processor Benchmark Applications -// (c) Kristian Klomsten Skordal 2015 -// Report bugs and issues on - -#ifndef UART_H -#define UART_H - -#include - -// TODO: Implement the M extension and then write a printf function. - -void uart_puts(volatile uint32_t * base, const char * s); -void uart_putc(volatile uint32_t * base, char c); -void uart_puth(volatile uint32_t * base, uint32_t n); - -#endif - Index: new-privileged-isa/benchmarks/sha256/timer.c =================================================================== --- new-privileged-isa/benchmarks/sha256/timer.c (revision 57) +++ new-privileged-isa/benchmarks/sha256/timer.c (nonexistent) @@ -1,18 +0,0 @@ -// The Potato Processor Benchmark Applications -// (c) Kristian Klomsten Skordal 2015 -// Report bugs and issues on - -#include "platform.h" -#include "timer.h" - -void timer_set(volatile uint32_t * base, uint32_t compare) -{ - base[TIMER_COMPARE >> 2] = compare; - timer_reset(base); -} - -void timer_reset(volatile uint32_t * base) -{ - base[TIMER_CTRL >> 2] = 1 << TIMER_CTRL_RUN | 1 << TIMER_CTRL_CLEAR; -} - Index: new-privileged-isa/benchmarks/sha256/utilities.h =================================================================== --- new-privileged-isa/benchmarks/sha256/utilities.h (revision 57) +++ new-privileged-isa/benchmarks/sha256/utilities.h (nonexistent) @@ -1,11 +0,0 @@ -// The Potato Processor Benchmark Applications -// (c) Kristian Klomsten Skordal 2015 -// Report bugs and issues on - -#ifndef UTILITIES_H -#define UTILITIES_H - -void * memset(void * s, int c, int n); - -#endif - Index: new-privileged-isa/benchmarks/sha256/gpio.h =================================================================== --- new-privileged-isa/benchmarks/sha256/gpio.h (revision 57) +++ new-privileged-isa/benchmarks/sha256/gpio.h (nonexistent) @@ -1,18 +0,0 @@ -// The Potato Processor Benchmark Applications -// (c) Kristian Klomsten Skordal 2015 -// Report bugs and issues on - -#ifndef GPIO_H -#define GPIO_H - -#include - -#define DIRECTION_INPUT 0 -#define DIRECTION_OUTPUT 1 - -void gpio_set_direction(volatile uint32_t * base, uint32_t direction); -void gpio_set_output(volatile uint32_t * base, uint32_t output); -uint32_t gpio_get_value(volatile uint32_t * base); - -#endif - Index: new-privileged-isa/benchmarks/sha256/main.c =================================================================== --- new-privileged-isa/benchmarks/sha256/main.c (revision 57) +++ new-privileged-isa/benchmarks/sha256/main.c (nonexistent) @@ -1,96 +0,0 @@ -// The Potato Processor Benchmark Applications -// (c) Kristian Klomsten Skordal 2015 -// Report bugs and issues on - -#include -#include - -#include "platform.h" -#include "potato.h" - -#include "gpio.h" -#include "sha256.h" -#include "timer.h" -#include "uart.h" - -static int led_status = 0; -static volatile int hashes_per_second = 0; - -// Handle an exception/interrupt. -// Arguments: -// - cause: exception cause, see potato.h for values -// - epc: exception return address -// - regbase: base of the stored context, can be used for printing all -// registers with regbase[0] = x1 and upwards. -void exception_handler(uint32_t cause, void * epc, void * regbase) -{ - if(cause == ((1 << CAUSE_INTERRUPT_BIT) | (CAUSE_IRQ_BASE + 5))) // Timer interrupt - { - uart_puts(IO_ADDRESS(UART_BASE), "Hashes per second: "); - uart_puth(IO_ADDRESS(UART_BASE), hashes_per_second); - uart_puts(IO_ADDRESS(UART_BASE), "\n\r"); - - if(led_status == 0) - { - gpio_set_output(IO_ADDRESS(GPIO2_BASE), 1); - led_status = 1; - } else { - gpio_set_output(IO_ADDRESS(GPIO2_BASE), 0); - led_status = 0; - } - - hashes_per_second = 0; - timer_reset(IO_ADDRESS(TIMER_BASE)); - } else { - uart_puts(IO_ADDRESS(UART_BASE), "Unhandled exception!\n\r"); - uart_puts(IO_ADDRESS(UART_BASE), "Cause: "); - uart_puth(IO_ADDRESS(UART_BASE), cause); - uart_puts(IO_ADDRESS(UART_BASE), "\n\r"); - uart_puts(IO_ADDRESS(UART_BASE), "EPC: "); - uart_puth(IO_ADDRESS(UART_BASE), (uint32_t) epc); - uart_puts(IO_ADDRESS(UART_BASE), "\n\r"); - - while(1) asm volatile("nop\n"); - } -} - -int main(void) -{ - // Configure GPIOs: - gpio_set_direction(IO_ADDRESS(GPIO1_BASE), 0x0000); // Switches - gpio_set_direction(IO_ADDRESS(GPIO2_BASE), 0xffff); // LEDs - - // Set up the timer: - timer_set(IO_ADDRESS(TIMER_BASE), SYSTEM_CLK_FREQ); - - // Print a startup message: - uart_puts(IO_ADDRESS(UART_BASE), "The Potato Processor SHA256 Benchmark\n\r\n\r"); - - // Enable interrupts: - potato_enable_irq(TIMER_IRQ); - potato_enable_interrupts(); - - struct sha256_context context; - - // Prepare a block for hashing: - uint32_t block[16]; - uint8_t * block_ptr = (uint8_t *) block; - block_ptr[0] = 'a'; - block_ptr[1] = 'b'; - block_ptr[2] = 'c'; - sha256_pad_le_block(block_ptr, 3, 3); - - // Repeatedly hash the same data over and over again: - while(true) - { - uint8_t hash[32]; - - sha256_reset(&context); - sha256_hash_block(&context, block); - sha256_get_hash(&context, hash); - ++hashes_per_second; - } - - return 0; -} - Index: new-privileged-isa/benchmarks/sha256/timer.h =================================================================== --- new-privileged-isa/benchmarks/sha256/timer.h (revision 57) +++ new-privileged-isa/benchmarks/sha256/timer.h (nonexistent) @@ -1,14 +0,0 @@ -// The Potato Processor Benchmark Applications -// (c) Kristian Klomsten Skordal 2015 -// Report bugs and issues on - -#ifndef TIMER_H -#define TIMER_H - -#include - -void timer_set(volatile uint32_t * base, uint32_t compare); -void timer_reset(volatile uint32_t * base); - -#endif - Index: new-privileged-isa/benchmarks/sha256/sha256.c =================================================================== --- new-privileged-isa/benchmarks/sha256/sha256.c (revision 57) +++ new-privileged-isa/benchmarks/sha256/sha256.c (nonexistent) @@ -1,167 +0,0 @@ -// The Potato Processor Benchmark Applications -// (c) Kristian Klomsten Skordal 2015 -// Report bugs and issues on - -#include "platform.h" -#include "gpio.h" - -#include "sha256.h" - -#define htobe32(n) ((uint32_t) ((n << 24) | ((n << 8) & 0xff0000) | ((n >> 8) & 0xff00) | (n >> 24))) - -// Software SHA256 module - -static const uint32_t initial[8] = -{ - 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, - 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 -}; - -static const uint32_t constants[64] = -{ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -}; - -static uint32_t rotate_right(uint32_t x, int n) -{ - return (x >> n) | (x << (32 - n)); -} - -static uint32_t Ch(uint32_t x, uint32_t y, uint32_t z) -{ - return (x & y) ^ ((~x) & z); -} - -static uint32_t Maj(uint32_t x, uint32_t y, uint32_t z) -{ - return (x & y) ^ (x & z) ^ (y & z); -} - -static uint32_t s0(uint32_t x) -{ - return rotate_right(x, 2) ^ rotate_right(x, 13) ^ rotate_right(x, 22); -} - -static uint32_t s1(uint32_t x) -{ - return rotate_right(x, 6) ^ rotate_right(x, 11) ^ rotate_right(x, 25); -} - -static uint32_t o0(uint32_t x) -{ - return rotate_right(x, 7) ^ rotate_right(x, 18) ^ (x >> 3); -} - -static uint32_t o1(uint32_t x) -{ - return rotate_right(x, 17) ^ rotate_right(x, 19) ^ (x >> 10); -} - -static uint32_t schedule(uint32_t input, const uint32_t * W, int i) -{ - if(i < 16) - return input; - else - return o1(W[i - 2]) + W[i - 7] + o0(W[i - 15]) + W[i - 16]; -} - -static void compress(uint32_t * i, uint32_t W, uint32_t K) -{ - uint32_t a = i[0], b = i[1], c = i[2], d = i[3]; - uint32_t e = i[4], f = i[5], g = i[6], h = i[7]; - - uint32_t t1 = h + s1(e) + Ch(e, f, g) + K + W; - uint32_t t2 = s0(a) + Maj(a, b, c); - - h = g; - g = f; - f = e; - e = d + t1; - d = c; - c = b; - b = a; - a = t1 + t2; - - i[0] = a; - i[1] = b; - i[2] = c; - i[3] = d; - i[4] = e; - i[5] = f; - i[6] = g; - i[7] = h; -} - -void sha256_reset(struct sha256_context * ctx) -{ - for(int i = 0; i < 8; ++i) - ctx->intermediate[i] = initial[i]; -} - -void sha256_hash_block(struct sha256_context * ctx, const uint32_t * data) -{ - uint32_t W[64]; - uint32_t temp[8]; - - for(int i = 0; i < 8; ++i) - temp[i] = ctx->intermediate[i]; - - for(int i = 0; i < 64; ++i) - { - uint32_t v = i < 16 ? data[i] : 0; - W[i] = schedule(v, W, i); - compress(temp, W[i], constants[i]); - } - - for(int i = 0; i < 8; ++i) - ctx->intermediate[i] += temp[i]; -} - -void sha256_pad_le_block(uint8_t * block, int block_length, uint64_t total_length) -{ - block[block_length] = 0x80; // Add a one to the end of the message; - for(int i = block_length + 1; i < 64; ++i) - block[i] = 0; - - ((uint32_t *) block)[14] = total_length * 8 >> 32; - ((uint32_t *) block)[15] = total_length * 8 & 0xffffffff; - - // Convert the block to big-endian: - for(int i = 0; i < 14; ++i) - ((uint32_t *) block)[i] = htobe32(((uint32_t *) block)[i]); -} - -void sha256_get_hash(const struct sha256_context * ctx, uint8_t * hash) -{ - for(int i = 0; i < 8; ++i) - { - // Return the hash in little-endian format: - hash[i * 4 + 3] = (ctx->intermediate[i] >> 0) & 0xff; - hash[i * 4 + 2] = (ctx->intermediate[i] >> 8) & 0xff; - hash[i * 4 + 1] = (ctx->intermediate[i] >> 16) & 0xff; - hash[i * 4 + 0] = (ctx->intermediate[i] >> 24) & 0xff; - } -} - -void sha256_format_hash(const uint8_t * hash, char * output) -{ - static const char * hex_digits = "0123456789abcdef"; - for(int i = 0; i < 32; i++) - { - uint8_t h = hash[i]; - - output[i * 2 + 0] = hex_digits[(h >> 4) & 0xf]; - output[i * 2 + 1] = hex_digits[h & 0xf]; - } - - output[64] = 0; -} - - Index: new-privileged-isa/benchmarks/platform.h =================================================================== --- new-privileged-isa/benchmarks/platform.h (revision 57) +++ new-privileged-isa/benchmarks/platform.h (nonexistent) @@ -1,49 +0,0 @@ -// The Potato Processor Benchmark Applications -// (c) Kristian Klomsten Skordal 2015 -// Report bugs and issues on - -// This file contains various platform details. The default defines in this file -// correspond to the "official" test platform, the Potato SoC for the Nexys4 board. - -#ifndef PLATFORM_H -#define PLATFORM_H - -// Clock frequency in Hz: -#define SYSTEM_CLK_FREQ 50000000 - -// Macro for using the addresses below in C code: -#define IO_ADDRESS(x) ((volatile void *) x) - -// Base addresses for the various peripherals in the system: -#define IMEM_BASE 0x00000000 -#define DMEM_BASE 0x00002000 -#define GPIO1_BASE 0x00004000 -#define GPIO2_BASE 0x00004800 -#define UART_BASE 0x00005000 -#define TIMER_BASE 0x00005800 - -// IRQs: -#define EXTERNAL_IRQ 0 -#define TIMER_IRQ 5 - -// GPIO register offsets: -#define GPIO_INPUT 0 -#define GPIO_OUTPUT 4 -#define GPIO_DIR 8 - -// UART register offsets: -#define UART_TX 0 -#define UART_RX 4 -#define UART_STATUS 8 - -// Timer register offsets: -#define TIMER_CTRL 0 -#define TIMER_COMPARE 4 -#define TIMER_COUNTER 8 - -// Timer control register bits: -#define TIMER_CTRL_RUN 0 -#define TIMER_CTRL_CLEAR 1 - -#endif - Index: new-privileged-isa/benchmarks/potato.h =================================================================== --- new-privileged-isa/benchmarks/potato.h (revision 57) +++ new-privileged-isa/benchmarks/potato.h (nonexistent) @@ -1,68 +0,0 @@ -// The Potato Processor -// (c) Kristian Klomsten Skordal 2015 -// Report bugs and issues on - -#ifndef POTATO_H -#define POTATO_H - -// Exception cause values: -#define CAUSE_INSTR_MISALIGN 0x00 -#define CAUSE_INSTR_FETCH 0x01 -#define CAUSE_INVALID_INSTR 0x02 -#define CAUSE_BREAKPOINT 0x03 -#define CAUSE_LOAD_MISALIGN 0x04 -#define CAUSE_LOAD_ERROR 0x05 -#define CAUSE_STORE_MISALIGN 0x06 -#define CAUSE_STORE_ERROR 0x07 -#define CAUSE_ECALL 0x0b - -#define CAUSE_IRQ_BASE 0x10 - -// Interrupt bit in the cause register: -#define CAUSE_INTERRUPT_BIT 31 - -// Status register bit indices: -#define STATUS_IE 0 // Enable Interrupts -#define STATUS_IE1 3 // Previous value of Enable Interrupts - -#define potato_enable_interrupts() asm volatile("csrsi mstatus, 1 << %[ie_bit]\n" \ - :: [ie_bit] "i" (STATUS_IE)) -#define potato_disable_interrupts() asm volatile("csrci mstatus, 1 << %[ie_bit] | 1 << %[ie1_bit]\n" \ - :: [ie_bit] "i" (STATUS_IE), [ie1_bit] "i" (STATUS_IE1)) - -#define potato_write_host(data) \ - do { \ - register uint32_t temp = data; \ - asm volatile("csrw mtohost, %[temp]\n" \ - :: [temp] "r" (temp)); \ - } while(0); - -#define potato_enable_irq(n) \ - do { \ - register uint32_t temp = 0; \ - asm volatile( \ - "li %[temp], 1 << %[shift]\n" \ - "csrs mie, %[temp]\n" \ - :: [temp] "r" (temp), [shift] "i" (n + 24)); \ - } while(0) - -#define potato_disable_irq(n) \ - do { \ - register uint32_t temp = 0; \ - asm volatile( \ - "li %[temp], 1 << %[shift]\n" \ - "csrc mie, %[temp]\n" \ - :: [temp] "r" (temp), [shift] "i" (n + 24);) \ - } while(0) - -#define potato_get_badaddr(n) \ - do { \ - register uint32_t __temp = 0; \ - asm volatile ( \ - "csrr %[temp], mbadaddr\n" \ - : [temp] "=r" (__temp)); \ - n = __temp; \ - } while(0) - -#endif - Index: new-privileged-isa/benchmarks/start.S =================================================================== --- new-privileged-isa/benchmarks/start.S (revision 57) +++ new-privileged-isa/benchmarks/start.S (nonexistent) @@ -1,150 +0,0 @@ -// The Potato Processor Benchmark Applications -// (c) Kristian Klomsten Skordal 2015 -// Report bugs and issues on - -// This file contains startup and initialization code for the Potato benchmark -// applications. - -#include "platform.h" -#include "potato.h" - -.section .init - -.align 6 -tvec_user: // User mode is not supported by Potato - j tvec_machine -.align 6 -tvec_supervisor: // Supervisor mode is not supported by Potato - j tvec_machine -.align 6 -tvec_hypervisor: // Hypervisor mode is not supported by Potato - j tvec_machine -.align 6 -tvec_machine: - j exception_handler_wrapper - -.align 6 -.global _start -_start: - -// Copies the .data section into the data memory section: -.hidden copy_data -copy_data: - la x1, __text_end // Copy source address - la x2, __data_begin // Copy destination address - la x3, __data_end // Copy destination end address - - beq x2, x3, 2f // Skip if there is no data to copy - -1: - lw x4, (x1) - sw x4, (x2) - addi x1, x1, 4 - addi x2, x2, 4 - - bne x2, x3, 1b // Repeat as long as there is more data to copy -2: - -.hidden clear_bss -clear_bss: - la x1, __bss_begin - la x2, __bss_end - beq x1, x2, 2f // Skip if there is no .bss section - -1: - sw x0, (x1) - addi x1, x1, 4 - bne x1, x2, 1b - -2: - -.hidden call_main -call_main: - la sp, __stack_top - jal main - csrw mtohost, a0 -1: - j 1b - -.section .text - -.global exception_handler_wrapper -exception_handler_wrapper: - // Save all registers (even those that are saved by the IRQ handler - // function, to aid in debugging): - addi sp, sp, -124 - sw x1, 0(sp) - sw x2, 4(sp) - sw x3, 8(sp) - sw x4, 12(sp) - sw x5, 16(sp) - sw x6, 20(sp) - sw x7, 24(sp) - sw x8, 28(sp) - sw x9, 32(sp) - sw x10, 36(sp) - sw x11, 40(sp) - sw x12, 44(sp) - sw x13, 48(sp) - sw x14, 52(sp) - sw x15, 56(sp) - sw x16, 60(sp) - sw x17, 64(sp) - sw x18, 68(sp) - sw x19, 72(sp) - sw x20, 76(sp) - sw x21, 80(sp) - sw x22, 84(sp) - sw x23, 88(sp) - sw x24, 92(sp) - sw x25, 96(sp) - sw x26, 100(sp) - sw x27, 104(sp) - sw x28, 108(sp) - sw x29, 112(sp) - sw x30, 116(sp) - sw x31, 120(sp) - - csrr a0, mcause - csrr a1, mepc - mv a2, sp - jal exception_handler - -.hidden exception_return -exception_return: - // Restore all registers: - lw x1, 0(sp) - lw x2, 4(sp) - lw x3, 8(sp) - lw x4, 12(sp) - lw x5, 16(sp) - lw x6, 20(sp) - lw x7, 24(sp) - lw x8, 28(sp) - lw x9, 32(sp) - lw x10, 36(sp) - lw x11, 40(sp) - lw x12, 44(sp) - lw x13, 48(sp) - lw x14, 52(sp) - lw x15, 56(sp) - lw x16, 60(sp) - lw x17, 64(sp) - lw x18, 68(sp) - lw x19, 72(sp) - lw x20, 76(sp) - lw x21, 80(sp) - lw x22, 84(sp) - lw x23, 88(sp) - lw x24, 92(sp) - lw x25, 96(sp) - lw x26, 100(sp) - lw x27, 104(sp) - lw x28, 108(sp) - lw x29, 112(sp) - lw x30, 116(sp) - lw x31, 120(sp) - addi sp, sp, 124 - - eret - Index: new-privileged-isa/tests.ld =================================================================== --- new-privileged-isa/tests.ld (revision 57) +++ new-privileged-isa/tests.ld (nonexistent) @@ -1,39 +0,0 @@ -/* - * Linker Script for the Potato Processor test applications. - * (c) Kristian Klomsten Skordal 2014 - 2015 - * Report bugs and issues on - */ - -/* - * The linker script assumes that default testbench settings are used, that is, - * 2048 bytes (each) of separate instruction and data memory. - */ - -OUTPUT_ARCH(riscv); -ENTRY(_start); - -SECTIONS -{ - .text 0x100 : - { - *(.text.init) - *(.text) - } - - .data 0x1000 : - { - __data_begin = .; - *(.data*) - } - - .bss : - { - __bss_begin = .; - *(.bss*) - __bss_end = .; - } - __data_end = .; - - __stack_top = 0x2000; -} - Index: new-privileged-isa/tests/sw-jal.S =================================================================== --- new-privileged-isa/tests/sw-jal.S (revision 57) +++ new-privileged-isa/tests/sw-jal.S (nonexistent) @@ -1,46 +0,0 @@ -# The Potato Processor - A simple RISC-V based processor for FPGAs -# (c) Kristian Klomsten Skordal 2014 - 2015 -# Report bugs and issues on - -#include "riscv_test.h" -#include "test_macros.h" - -.section .text -RVTEST_RV32M -RVTEST_CODE_BEGIN - -test_1: - li TESTNUM, 1 - - la ra, test_failed - la sp, temp - sw ra, 0(sp) - jal ra, test_cmp - -1: - j fail - j pass - -test_cmp: - la t0, 1b - bne ra, t0, fail - addi ra, ra, 4 - ret - -TEST_PASSFAIL -RVTEST_CODE_END - -test_failed: - RVTEST_FAIL - -.section .data -RVTEST_DATA_BEGIN - TEST_DATA - -# Allocate a 32-bit word to store some data into -#.section .data -temp: - .word 0x00000000 - -RVTEST_DATA_END - Index: new-privileged-isa/tests/timer.S =================================================================== --- new-privileged-isa/tests/timer.S (revision 57) +++ new-privileged-isa/tests/timer.S (nonexistent) @@ -1,56 +0,0 @@ -# The Potato Processor - A simple RISC-V based processor for FPGAs -# (c) Kristian Klomsten Skordal 2014 - 2015 -# Report bugs and issues on - -# Simplified timer interrupt test. - -#include "riscv_test.h" -#include "test_macros.h" - -#define TIMER_DELTA_T 10 -#define MIE_STIE MIP_STIP - -RVTEST_RV32M -RVTEST_CODE_BEGIN - - li s8, 0 # Number of timer interrupts taken - li s9, 10 # Number of timer interrupts to wait for - - # Set the time of the next timer interrupt: - csrr a0, mtime - addi a0, a0, TIMER_DELTA_T - csrw mtimecmp, a0 - - # Enable the timer interrupt: - li a0, (1 << 7) - csrs mie, a0 - csrs mstatus, MSTATUS_IE - -wait_for_count: - # TODO: wfi not yet supported - j wait_for_count - -mtvec_handler: - li t0, (1 << 31) + 1 # Interrupt bit set + timer interrupt exception code - - csrr t1, mcause - bne t0, t1, fail # Fail if not timer interrupt - - addi s8, s8, 1 - beq s8, s9, pass # Pass the test if the correct number of interrupts have been taken - - # Reset the timer: - csrr a0, mtime - addi a0, a0, TIMER_DELTA_T - csrw mtimecmp, a0 - - eret - -TEST_PASSFAIL -RVTEST_CODE_END - -.data -RVTEST_DATA_BEGIN - TEST_DATA -RVTEST_DATA_END - Index: new-privileged-isa/LICENSE =================================================================== --- new-privileged-isa/LICENSE (revision 57) +++ new-privileged-isa/LICENSE (nonexistent) @@ -1,12 +0,0 @@ -Copyright (c) 2015, Kristian Klomsten Skordal -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Index: new-privileged-isa =================================================================== --- new-privileged-isa (revision 57) +++ new-privileged-isa (nonexistent)
new-privileged-isa Property changes : Deleted: svn:mergeinfo ## -0,1 +0,0 ## Reverse-merged /potato/branches/cache-playground:r23-44

powered by: WebSVN 2.1.0

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