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/tests.ld
File deleted
/new-privileged-isa/tests/sw-jal.S
File deleted
/new-privileged-isa/tests/timer.S
File deleted
/new-privileged-isa/LICENSE
File deleted
/new-privileged-isa/empty_dmem.hex
File deleted
/new-privileged-isa/soc/pp_soc_timer.vhd
File deleted
/new-privileged-isa/soc/pp_soc_memory.vhd
File deleted
/new-privileged-isa/soc/pp_soc_dummy.vhd
File deleted
/new-privileged-isa/soc/pp_soc_uart.vhd
File deleted
/new-privileged-isa/soc/pp_soc_gpio.vhd
File deleted
/new-privileged-isa/riscv-tests/auipc.S
File deleted
/new-privileged-isa/riscv-tests/and.S
File deleted
/new-privileged-isa/riscv-tests/slli.S
File deleted
/new-privileged-isa/riscv-tests/lh.S
File deleted
/new-privileged-isa/riscv-tests/bne.S
File deleted
/new-privileged-isa/riscv-tests/xor.S
File deleted
/new-privileged-isa/riscv-tests/test_macros.h
File deleted
/new-privileged-isa/riscv-tests/srli.S
File deleted
/new-privileged-isa/riscv-tests/riscv_test.h
File deleted
/new-privileged-isa/riscv-tests/encoding.h
File deleted
/new-privileged-isa/riscv-tests/slti.S
File deleted
/new-privileged-isa/riscv-tests/hwacha_xcpt.h
File deleted
/new-privileged-isa/riscv-tests/blt.S
File deleted
/new-privileged-isa/riscv-tests/lw.S
File deleted
/new-privileged-isa/riscv-tests/lbu.S
File deleted
/new-privileged-isa/riscv-tests/sra.S
File deleted
/new-privileged-isa/riscv-tests/ma_addr.S
File deleted
/new-privileged-isa/riscv-tests/jalr.S
File deleted
/new-privileged-isa/riscv-tests/lhu.S
File deleted
/new-privileged-isa/riscv-tests/ori.S
File deleted
/new-privileged-isa/riscv-tests/sll.S
File deleted
/new-privileged-isa/riscv-tests/README
File deleted
/new-privileged-isa/riscv-tests/bge.S
File deleted
/new-privileged-isa/riscv-tests/srai.S
File deleted
/new-privileged-isa/riscv-tests/srl.S
File deleted
/new-privileged-isa/riscv-tests/addi.S
File deleted
/new-privileged-isa/riscv-tests/slt.S
File deleted
/new-privileged-isa/riscv-tests/sb.S
File deleted
/new-privileged-isa/riscv-tests/bltu.S
File deleted
/new-privileged-isa/riscv-tests/jal.S
File deleted
/new-privileged-isa/riscv-tests/sbreak.S
File deleted
/new-privileged-isa/riscv-tests/beq.S
File deleted
/new-privileged-isa/riscv-tests/sh.S
File deleted
/new-privileged-isa/riscv-tests/andi.S
File deleted
/new-privileged-isa/riscv-tests/or.S
File deleted
/new-privileged-isa/riscv-tests/LICENSE
File deleted
/new-privileged-isa/riscv-tests/xori.S
File deleted
/new-privileged-isa/riscv-tests/bgeu.S
File deleted
/new-privileged-isa/riscv-tests/add.S
File deleted
/new-privileged-isa/riscv-tests/j.S
File deleted
/new-privileged-isa/riscv-tests/sw.S
File deleted
/new-privileged-isa/riscv-tests/simple.S
File deleted
/new-privileged-isa/riscv-tests/lui.S
File deleted
/new-privileged-isa/riscv-tests/sub.S
File deleted
/new-privileged-isa/riscv-tests/lb.S
File deleted
/new-privileged-isa/riscv-tests/scall.S
File deleted
/new-privileged-isa/scripts/extract_hex.sh
File deleted
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_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/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/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/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/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/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/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/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/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/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/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
===================================================================
--- 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