URL
https://opencores.org/ocsvn/potato/potato/trunk
Subversion Repositories potato
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 45 to Rev 46
- ↔ Reverse comparison
Rev 45 → Rev 46
/potato/branches/cache-playground/example/README
File deleted
/potato/branches/cache-playground/README
File deleted
/potato/branches/cache-playground/Makefile
File deleted
/potato/branches/cache-playground/benchmarks/start.S
File deleted
/potato/branches/cache-playground/tests.ld
File deleted
/potato/branches/cache-playground/tests/sw-jal.S
File deleted
/potato/branches/cache-playground/tests/scall.S
File deleted
/potato/branches/cache-playground/tests/sbreak.S
File deleted
/potato/branches/cache-playground/LICENSE
File deleted
/potato/branches/cache-playground/empty_dmem.hex
File deleted
/potato/branches/cache-playground/riscv-tests/addi.S
File deleted
/potato/branches/cache-playground/riscv-tests/slt.S
File deleted
/potato/branches/cache-playground/riscv-tests/sb.S
File deleted
/potato/branches/cache-playground/riscv-tests/bltu.S
File deleted
/potato/branches/cache-playground/riscv-tests/jal.S
File deleted
/potato/branches/cache-playground/riscv-tests/beq.S
File deleted
/potato/branches/cache-playground/riscv-tests/sh.S
File deleted
/potato/branches/cache-playground/riscv-tests/andi.S
File deleted
/potato/branches/cache-playground/riscv-tests/or.S
File deleted
/potato/branches/cache-playground/riscv-tests/xori.S
File deleted
/potato/branches/cache-playground/riscv-tests/bgeu.S
File deleted
/potato/branches/cache-playground/riscv-tests/add.S
File deleted
/potato/branches/cache-playground/riscv-tests/j.S
File deleted
/potato/branches/cache-playground/riscv-tests/sw.S
File deleted
/potato/branches/cache-playground/riscv-tests/sub.S
File deleted
/potato/branches/cache-playground/riscv-tests/lb.S
File deleted
/potato/branches/cache-playground/riscv-tests/and.S
File deleted
/potato/branches/cache-playground/riscv-tests/slli.S
File deleted
/potato/branches/cache-playground/riscv-tests/lh.S
File deleted
/potato/branches/cache-playground/riscv-tests/bne.S
File deleted
/potato/branches/cache-playground/riscv-tests/xor.S
File deleted
/potato/branches/cache-playground/riscv-tests/srli.S
File deleted
/potato/branches/cache-playground/riscv-tests/slti.S
File deleted
/potato/branches/cache-playground/riscv-tests/blt.S
File deleted
/potato/branches/cache-playground/riscv-tests/lw.S
File deleted
/potato/branches/cache-playground/riscv-tests/lbu.S
File deleted
/potato/branches/cache-playground/riscv-tests/sra.S
File deleted
/potato/branches/cache-playground/riscv-tests/jalr.S
File deleted
/potato/branches/cache-playground/riscv-tests/lhu.S
File deleted
/potato/branches/cache-playground/riscv-tests/ori.S
File deleted
/potato/branches/cache-playground/riscv-tests/sll.S
File deleted
/potato/branches/cache-playground/riscv-tests/README
File deleted
/potato/branches/cache-playground/riscv-tests/bge.S
File deleted
/potato/branches/cache-playground/riscv-tests/srai.S
File deleted
/potato/branches/cache-playground/riscv-tests/srl.S
File deleted
potato/branches/cache-playground/scripts/extract_hex.sh
Property changes :
Deleted: svn:executable
## -1 +0,0 ##
-*
\ No newline at end of property
Index: potato/branches/cache-playground/testbenches/tb_soc_gpio.vhd
===================================================================
--- potato/branches/cache-playground/testbenches/tb_soc_gpio.vhd (revision 45)
+++ potato/branches/cache-playground/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: potato/branches/cache-playground/testbenches/tb_soc.vhd
===================================================================
--- potato/branches/cache-playground/testbenches/tb_soc.vhd (revision 45)
+++ potato/branches/cache-playground/testbenches/tb_soc.vhd (nonexistent)
@@ -1,296 +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 := 2048; --! Size of the instruction memory in bytes.
- DMEM_SIZE : natural := 2048; --! Size of the data memory in bytes.
- IMEM_FILENAME : string := "imem_testfile.hex"; --! File containing the contents of instruction memory.
- 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;
-
- -- 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
- port map(
- clk => clk,
- reset => processor_reset,
- 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 : natural := IMEM_SIZE;
- begin
- if not initialized then
- -- Read the instruction memory file:
- for i in 0 to IMEM_SIZE loop
- exit when endfile(imem_file);
-
- readline(imem_file, input_line);
- hread(input_line, input_value);
-
- init_adr_out <= std_logic_vector(to_unsigned(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 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 + (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;
-
- 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: potato/branches/cache-playground/testbenches/tb_soc_timer.vhd
===================================================================
--- potato/branches/cache-playground/testbenches/tb_soc_timer.vhd (revision 45)
+++ potato/branches/cache-playground/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: potato/branches/cache-playground/testbenches/tb_soc_memory.vhd
===================================================================
--- potato/branches/cache-playground/testbenches/tb_soc_memory.vhd (revision 45)
+++ potato/branches/cache-playground/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: potato/branches/cache-playground/testbenches/tb_processor.vhd
===================================================================
--- potato/branches/cache-playground/testbenches/tb_processor.vhd (revision 45)
+++ potato/branches/cache-playground/testbenches/tb_processor.vhd (nonexistent)
@@ -1,291 +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 := 2048; --! Size of the instruction memory in bytes.
- DMEM_SIZE : natural := 2048; --! Size of the data memory in bytes.
- IMEM_FILENAME : string := "imem_testfile.hex"; --! File containing the contents of instruction memory.
- DMEM_FILENAME : string := "dmem_testfile.hex" --! File containing the contents of data memory.
- );
-end entity tb_processor;
-
-architecture testbench of tb_processor is
-
- -- Processor component prototype:
- component pp_core is
- port(
- -- Common inputs:
- clk : in std_logic; --! Processor clock
- reset : in std_logic; --! Reset signal
- timer_clk : in std_logic; --! Timer clock input
-
- -- 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 input
- );
- end component pp_core;
-
- -- Clock signal:
- signal clk : std_logic := '0';
- constant clk_period : time := 10 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_SIZE - 1;
- constant DMEM_BASE : natural := IMEM_SIZE;
- constant DMEM_END : natural := IMEM_SIZE + DMEM_SIZE - 1;
-
- -- 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: pp_core
- port map(
- clk => clk,
- reset => reset,
- timer_clk => 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;
-
- --! 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 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 => -- Reserved for possible future 64 bit support
- 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 => -- Reserved for possible future 64 bit support
- 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: potato/branches/cache-playground/testbenches/tb_soc_uart.vhd
===================================================================
--- potato/branches/cache-playground/testbenches/tb_soc_uart.vhd (revision 45)
+++ potato/branches/cache-playground/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: potato/branches/cache-playground/src/pp_csr_unit.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_csr_unit.vhd (revision 45)
+++ potato/branches/cache-playground/src/pp_csr_unit.vhd (nonexistent)
@@ -1,223 +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;
-
-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;
-
- -- 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;
-
- -- Registers needed for exception handling, always read:
- status_out : out csr_status_register;
- evec_out : out std_logic_vector(31 downto 0)
- );
-end entity pp_csr_unit;
-
-architecture behaviour of pp_csr_unit is
-
- -- Implemented 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);
-
- -- Implemented registers:
- signal sup0, sup1 : std_logic_vector(31 downto 0) := (others => '0');
- signal epc, evec : std_logic_vector(31 downto 0) := (others => '0');
- signal badvaddr : std_logic_vector(31 downto 0) := (others => '0');
- signal cause : csr_exception_cause;
-
- -- HTIF FROMHOST register:
- signal fromhost: std_logic_vector(31 downto 0);
-
- -- Status register:
- signal status_register : csr_status_register;
-
-begin
-
- read_writeable <= csr_is_writeable(read_address);
-
- --! 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_TOHOST then
- tohost_data <= write_data_in;
- tohost_updated <= '1';
- else
- tohost_updated <= '0';
- end if;
- end if;
- end if;
- end process htif_tohost;
-
- write: process(clk)
- begin
- if rising_edge(clk) then
- if reset = '1' then
- status_register <= CSR_SR_DEFAULT;
- else
- if exception_context_write = '1' then
- status_register <= exception_context.status;
- cause <= exception_context.cause;
- badvaddr <= exception_context.badvaddr;
- end if;
-
- if write_mode /= CSR_WRITE_NONE then
- case write_address is
- when CSR_STATUS =>
- if exception_context_write = '0' then
- status_register <= to_csr_status_register(write_data_in);
- end if;
- when CSR_EPC =>
- epc <= write_data_in;
- when CSR_EVEC =>
- evec <= write_data_in;
- when CSR_SUP0 =>
- sup0 <= write_data_in;
- when CSR_SUP1 =>
- sup1 <= write_data_in;
- when others =>
- -- Ignore writes to invalid or read-only registers
- end case;
- end if;
- end if;
- end if;
- end process write;
-
- status_out <= exception_context.status when exception_context_write = '1' else status_register;
-
- read: process(clk)
- begin
- if rising_edge(clk) then
- --if exception_context_write = '1' then
- -- status_out <= exception_context.status;
- --else
- -- status_out <= status_register;
- --end if;
-
- if write_mode /= CSR_WRITE_NONE and write_address = CSR_EVEC then
- evec_out <= write_data_in;
- else
- evec_out <= evec;
- 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
-
- -- Status and control registers:
- when CSR_STATUS => -- Status register
- read_data_out <= to_std_logic_vector(status_register);
- when CSR_HARTID => -- Processor ID
- read_data_out <= PROCESSOR_ID;
- when CSR_FROMHOST => -- Fromhost data
- read_data_out <= fromhost;
- when CSR_EPC | CSR_EPC_SRET => -- Exception PC value
- read_data_out <= epc;
- when CSR_EVEC => -- Exception handler address
- read_data_out <= evec;
- when CSR_CAUSE => -- Exception cause
- read_data_out <= to_std_logic_vector(cause);
- when CSR_BADVADDR => -- Load/store address responsible for the exception
- read_data_out <= badvaddr;
-
- -- Supporting registers:
- when CSR_SUP0 =>
- read_data_out <= sup0;
- when CSR_SUP1 =>
- read_data_out <= sup1;
-
- -- Timers and counters:
- 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: potato/branches/cache-playground/src/pp_csr.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_csr.vhd (revision 45)
+++ potato/branches/cache-playground/src/pp_csr.vhd (nonexistent)
@@ -1,144 +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(4 downto 0);
-
- 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"00000";
- constant CSR_CAUSE_INSTR_FETCH : csr_exception_cause := b"00001";
- constant CSR_CAUSE_INVALID_INSTR : csr_exception_cause := b"00010";
- constant CSR_CAUSE_SYSCALL : csr_exception_cause := b"00110";
- constant CSR_CAUSE_BREAKPOINT : csr_exception_cause := b"00111";
- constant CSR_CAUSE_LOAD_MISALIGN : csr_exception_cause := b"01000";
- constant CSR_CAUSE_STORE_MISALIGN : csr_exception_cause := b"01001";
- constant CSR_CAUSE_LOAD_ERROR : csr_exception_cause := b"01010";
- constant CSR_CAUSE_STORE_ERROR : csr_exception_cause := b"01011";
- constant CSR_CAUSE_FROMHOST : csr_exception_cause := b"11110";
- constant CSR_CAUSE_NONE : csr_exception_cause := b"11111";
-
- constant CSR_CAUSE_IRQ_BASE : csr_exception_cause := b"10000";
-
- -- Control register IDs, specified in the immediate of csr* instructions:
- constant CSR_STATUS : csr_address := x"50a";
- constant CSR_HARTID : csr_address := x"50b";
- constant CSR_SUP0 : csr_address := x"500";
- constant CSR_SUP1 : csr_address := x"501";
- constant CSR_BADVADDR : csr_address := x"503";
- constant CSR_TOHOST : csr_address := x"51e";
- constant CSR_FROMHOST : csr_address := x"51f";
- 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_EPC : csr_address := x"502";
- constant CSR_EVEC : csr_address := x"508";
- constant CSR_CAUSE : csr_address := x"509";
-
- -- Values used as control register IDs in SRET, SCALL and SBREAK:
- constant CSR_EPC_SRET : csr_address := x"800";
-
- -- Status register bit indices:
- constant CSR_SR_S : natural := 0;
- constant CSR_SR_PS : natural := 1;
- constant CSR_SR_EI : natural := 2;
- constant CSR_SR_PEI : natural := 3;
-
- -- Status register in Potato:
- -- * Bit 0, S: Supervisor mode, always 1
- -- * Bit 1, PS: Previous supervisor mode bit, always 1
- -- * Bit 2, EI: Enable interrupts bit
- -- * Bit 3, PEI: Previous enable interrupts bit
- -- * Bits 23 downto 16, IM: Interrupt mask
- -- * Bits 31 downto 24, PIM: Previous interrupt mask
-
- -- Status register record:
- type csr_status_register is
- record
- ei, pei : std_logic;
- im, pim : std_logic_vector(7 downto 0);
- end record;
-
- -- Exception context; this record contains all state that is stored
- -- when an exception is taken.
- type csr_exception_context is
- record
- status : csr_status_register;
- cause : csr_exception_cause;
- badvaddr : std_logic_vector(31 downto 0);
- end record;
-
- -- Reset value of the status register:
- constant CSR_SR_DEFAULT : csr_status_register := (ei => '0', pei => '0', im => x"00", pim => x"00");
-
- -- Converts a status register record into an std_logic_vector:
- function to_std_logic_vector(input : in csr_status_register)
- return std_logic_vector;
-
- -- Converts an std_logic_vector into a status register record:
- function to_csr_status_register(input : in std_logic_vector(31 downto 0))
- return csr_status_register;
-
- --! Checks if a control register is writeable.
- function csr_is_writeable(csr : in csr_address) return boolean;
-
-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 downto 5 => '0') & input;
- end function to_std_logic_vector;
-
- function to_std_logic_vector(input : in csr_status_register)
- return std_logic_vector is
- begin
- return input.pim & input.im & (15 downto 4 => '0') & input.pei & input.ei & '1' & '1';
- end function to_std_logic_vector;
-
- function to_csr_status_register(input : in std_logic_vector(31 downto 0))
- return csr_status_register
- is
- variable retval : csr_status_register;
- begin
- retval.ei := input(CSR_SR_EI);
- retval.pei := input(CSR_SR_PEI);
- retval.im := input(23 downto 16);
- retval.pim := input(31 downto 24);
- return retval;
- end function to_csr_status_register;
-
- function csr_is_writeable(csr : in csr_address) return boolean is
- begin
- case csr is
- when CSR_FROMHOST | CSR_CYCLE | CSR_CYCLEH | CSR_HARTID
- | CSR_TIME | CSR_TIMEH | CSR_INSTRET | CSR_INSTRETH
- | CSR_CAUSE | CSR_BADVADDR =>
- return false;
- when others =>
- return true;
- end case;
- end function csr_is_writeable;
-
-end package body pp_csr;
Index: potato/branches/cache-playground/src/pp_csr_alu.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_csr_alu.vhd (revision 45)
+++ potato/branches/cache-playground/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: potato/branches/cache-playground/src/pp_core.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_core.vhd (revision 45)
+++ potato/branches/cache-playground/src/pp_core.vhd (nonexistent)
@@ -1,446 +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"00000000" --! 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 status : csr_status_register;
- signal evec : std_logic_vector(31 downto 0);
-
- -- 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,
- 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,
- status_out => status,
- evec_out => evec
- );
-
- 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,
- 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,
- status_in => status,
- evec_in => evec,
- evec_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: potato/branches/cache-playground/src/pp_fetch.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_fetch.vhd (revision 45)
+++ potato/branches/cache-playground/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) := x"00000000"
- );
- 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: potato/branches/cache-playground/src/pp_execute.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_execute.vhd (revision 45)
+++ potato/branches/cache-playground/src/pp_execute.vhd (nonexistent)
@@ -1,519 +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;
-
- -- IRQ input:
- irq : in std_logic_vector(7 downto 0);
-
- -- 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:
- status_in : in csr_status_register;
- evec_in : in std_logic_vector(31 downto 0);
- evec_out : out 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 sr : csr_status_register;
- signal evec, evec_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_vaddr : 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 <= (
- status => exception_context_forwarded.status,
- cause => exception_cause,
- badvaddr => exception_vaddr
- ) 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;
-
- evec_out <= evec_forwarded;
- exception_taken <= (decode_exception or to_std_logic(exception_cause /= CSR_CAUSE_NONE) or irq_asserted) and not stall;
-
- irq_asserted <= to_std_logic(exception_context_forwarded.status.ei = '1' and
- (irq and exception_context_forwarded.status.im) /= x"00");
-
- rs1_data <= rs1_data_in;
- rs2_data <= rs2_data_in;
-
- dmem_address <= alu_result;
- dmem_data_out <= rs2_forwarded;
- dmem_write_req <= '1' when mem_op = MEMOP_TYPE_STORE else '0';
- dmem_read_req <= '1' when memop_is_load(mem_op) 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;
-
- -- Status register;
- sr <= status_in;
-
- -- Exception vector base:
- evec <= evec_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)
- variable temp : std_logic_vector(3 downto 0);
- begin
- temp := (others => '0');
-
- for i in 0 to 7 loop
- if irq(i) = '1' and exception_context_forwarded.status.im(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)
- begin
- if irq_asserted = '1' then
- exception_cause <= std_logic_vector(unsigned(CSR_CAUSE_IRQ_BASE) + unsigned(irq_asserted_num));
- 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_vaddr: process(instr_misaligned, data_misaligned, jump_target, alu_result)
- begin
- if instr_misaligned = '1' then
- exception_vaddr <= jump_target;
- elsif data_misaligned = '1' then
- exception_vaddr <= alu_result;
- else
- exception_vaddr <= (others => '0');
- end if;
- end process find_exception_vaddr;
-
- 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; -- Will be the EPC value in the case of SRET
- 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_CAUSE and mem_exception = '1' then
- csr_value_forwarded <= to_std_logic_vector(mem_exception_context.cause);
- elsif csr_addr = CSR_STATUS and mem_exception = '1' then
- csr_value_forwarded <= to_std_logic_vector(mem_exception_context.status);
- elsif csr_addr = CSR_BADVADDR and mem_exception = '1' then
- csr_value_forwarded <= mem_exception_context.badvaddr;
- 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_CAUSE and wb_exception = '1' then
- csr_value_forwarded <= to_std_logic_vector(wb_exception_context.cause);
- elsif csr_addr = CSR_STATUS and wb_exception = '1' then
- csr_value_forwarded <= to_std_logic_vector(wb_exception_context.status);
- elsif csr_addr = CSR_BADVADDR and wb_exception = '1' then
- csr_value_forwarded <= wb_exception_context.badvaddr;
- 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;
-
- evec_forward: process(mem_csr_write, mem_csr_addr, mem_csr_value,
- wb_csr_write, wb_csr_addr, wb_csr_value, evec)
- begin
- if mem_csr_write /= CSR_WRITE_NONE and mem_csr_addr = CSR_EVEC then
- evec_forwarded <= mem_csr_value;
- elsif wb_csr_write /= CSR_WRITE_NONE and wb_csr_addr = CSR_EVEC then
- evec_forwarded <= wb_csr_value;
- else
- evec_forwarded <= evec;
- end if;
- end process evec_forward;
-
- exception_ctx_forward: process(mem_exception, wb_exception, mem_exception_context, wb_exception_context,
- exception_cause, exception_vaddr, mem_csr_write, mem_csr_addr, mem_csr_value,
- wb_csr_write, wb_csr_addr, wb_csr_value, sr)
- begin
- if mem_exception = '1' then
- exception_context_forwarded <= mem_exception_context;
- elsif mem_csr_write /= CSR_WRITE_NONE and mem_csr_addr = CSR_STATUS then
- exception_context_forwarded <= (
- status => to_csr_status_register(mem_csr_value),
- cause => mem_exception_context.cause,
- badvaddr => mem_exception_context.badvaddr);
- elsif wb_exception = '1' then
- exception_context_forwarded <= wb_exception_context;
- elsif wb_csr_write /= CSR_WRITE_NONE and wb_csr_addr = CSR_STATUS then
- exception_context_forwarded <= (
- status => to_csr_status_register(wb_csr_value),
- cause => wb_exception_context.cause,
- badvaddr => wb_exception_context.badvaddr);
- else
- exception_context_forwarded.status <= sr;
- exception_context_forwarded.cause <= exception_cause;
- exception_context_forwarded.badvaddr <= exception_vaddr;
- 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: potato/branches/cache-playground/src/pp_types.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_types.vhd (revision 45)
+++ potato/branches/cache-playground/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: potato/branches/cache-playground/src/pp_potato.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_potato.vhd (revision 45)
+++ potato/branches/cache-playground/src/pp_potato.vhd (nonexistent)
@@ -1,149 +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"00000000" --! Address of the first instruction to execute.
- );
- port(
- 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 => 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: potato/branches/cache-playground/src/pp_comparator.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_comparator.vhd (revision 45)
+++ potato/branches/cache-playground/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: potato/branches/cache-playground/src/pp_imm_decoder.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_imm_decoder.vhd (revision 45)
+++ potato/branches/cache-playground/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: potato/branches/cache-playground/src/pp_memory.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_memory.vhd (revision 45)
+++ potato/branches/cache-playground/src/pp_memory.vhd (nonexistent)
@@ -1,161 +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_EPC;
- 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.status <= (
- pim => exception_context_in.status.im,
- im => (others => '0'),
- pei => exception_context_in.status.ei,
- ei => '0'
- );
- exception_context_out.cause <= exception_context_in.cause;
- exception_context_out.badvaddr <= exception_context_in.badvaddr;
- elsif branch = BRANCH_SRET then
- exception_context_out.status <= (
- pim => exception_context_in.status.pim,
- im => exception_context_in.status.pim,
- pei => exception_context_in.status.pei,
- ei => exception_context_in.status.pei
- );
- exception_context_out.cause <= CSR_CAUSE_NONE;
- exception_context_out.badvaddr <= (others => '0');
- else
- exception_context_out.status <= exception_context_in.status;
- exception_context_out.cause <= CSR_CAUSE_NONE;
- exception_context_out.badvaddr <= (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: potato/branches/cache-playground/src/pp_wb_adapter.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_wb_adapter.vhd (revision 45)
+++ potato/branches/cache-playground/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;
potato/branches/cache-playground/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
Index: potato/branches/cache-playground/src/pp_alu_mux.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_alu_mux.vhd (revision 45)
+++ potato/branches/cache-playground/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: potato/branches/cache-playground/src/pp_utilities.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_utilities.vhd (revision 45)
+++ potato/branches/cache-playground/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: potato/branches/cache-playground/src/pp_writeback.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_writeback.vhd (revision 45)
+++ potato/branches/cache-playground/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: potato/branches/cache-playground/src/pp_constants.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_constants.vhd (revision 45)
+++ potato/branches/cache-playground/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: potato/branches/cache-playground/src/pp_icache.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_icache.vhd (revision 45)
+++ potato/branches/cache-playground/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: potato/branches/cache-playground/src/pp_control_unit.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_control_unit.vhd (revision 45)
+++ potato/branches/cache-playground/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 std_logic_vector(4 downto 0);
-
- -- 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 : std_logic_vector(4 downto 0);
- 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_SYSCALL;
- branch <= BRANCH_NONE;
- elsif funct12 = x"001" then
- exception <= '1';
- exception_cause <= CSR_CAUSE_BREAKPOINT;
- branch <= BRANCH_NONE;
- elsif funct12 = x"800" 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: potato/branches/cache-playground/src/pp_counter.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_counter.vhd (revision 45)
+++ potato/branches/cache-playground/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: potato/branches/cache-playground/src/pp_alu_control_unit.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_alu_control_unit.vhd (revision 45)
+++ potato/branches/cache-playground/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: potato/branches/cache-playground/src/pp_wb_arbiter.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_wb_arbiter.vhd (revision 45)
+++ potato/branches/cache-playground/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: potato/branches/cache-playground/src/pp_alu.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_alu.vhd (revision 45)
+++ potato/branches/cache-playground/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: potato/branches/cache-playground/src/pp_register_file.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_register_file.vhd (revision 45)
+++ potato/branches/cache-playground/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: potato/branches/cache-playground/src/pp_fifo.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_fifo.vhd (revision 45)
+++ potato/branches/cache-playground/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: potato/branches/cache-playground/src/pp_decode.vhd
===================================================================
--- potato/branches/cache-playground/src/pp_decode.vhd (revision 45)
+++ potato/branches/cache-playground/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_SRET then
- csr_addr <= CSR_EPC;
- 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: potato/branches/cache-playground
===================================================================
--- potato/branches/cache-playground (revision 45)
+++ potato/branches/cache-playground (nonexistent)
potato/branches/cache-playground
Property changes :
Deleted: svn:mergeinfo
## -0,1 +0,0 ##
Reverse-merged /potato/trunk:r26