diff --git a/fpga/mw_soc_memory.vhdl b/fpga/mw_soc_memory.vhdl new file mode 100644 index 0000000..1c6fdc1 --- /dev/null +++ b/fpga/mw_soc_memory.vhdl @@ -0,0 +1,108 @@ +-- Based on: +-- The Potato Processor - A simple processor for FPGAs +-- (c) Kristian Klomsten Skordal 2014 - 2015 + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use std.textio.all; + +library work; +use work.wishbone_types.all; + +use work.pp_utilities.all; + +--! @brief Simple memory module for use in Wishbone-based systems. +entity mw_soc_memory is + generic( + MEMORY_SIZE : natural := 4096; --! Memory size in bytes. + RAM_INIT_FILE : string + ); + port( + clk : in std_logic; + rst : in std_logic; + + -- Wishbone interface: + wishbone_in : in wishbone_master_out; + wishbone_out : out wishbone_slave_out + ); +end entity mw_soc_memory; + +architecture behaviour of mw_soc_memory is + signal wb_adr_in : std_logic_vector(log2(MEMORY_SIZE) - 1 downto 0); + type ram_t is array(0 to (MEMORY_SIZE / 8) - 1) of std_logic_vector(63 downto 0); + + impure function init_ram(name : STRING) return ram_t is + file ram_file : text open read_mode is name; + variable ram_line : line; + variable temp_word : std_logic_vector(63 downto 0); + variable temp_ram : ram_t := (others => (others => '0')); + begin + for i in 0 to (MEMORY_SIZE/8)-1 loop + exit when endfile(ram_file); + readline(ram_file, ram_line); + hread(ram_line, temp_word); + temp_ram(i) := temp_word; + end loop; + + return temp_ram; + end function; + + signal memory : ram_t := init_ram(RAM_INIT_FILE); + + attribute ram_style : string; + attribute ram_style of memory : signal is "block"; + + attribute ram_decomp : string; + attribute ram_decomp of memory : signal is "power"; + + type state_type is (IDLE, ACK); + signal state : state_type; + + signal read_ack : std_logic; + +begin + + wb_adr_in <= wishbone_in.adr(log2(MEMORY_SIZE) - 1 downto 0); + + wishbone_out.ack <= read_ack and wishbone_in.stb; + + memory_0: process(clk) + begin + if rising_edge(clk) then + if rst = '1' then + read_ack <= '0'; + state <= IDLE; + else + if wishbone_in.cyc = '1' then + case state is + when IDLE => + if wishbone_in.stb = '1' and wishbone_in.we = '1' then + for i in 0 to 7 loop + if wishbone_in.sel(i) = '1' then + memory(to_integer(unsigned(wb_adr_in(wb_adr_in'left downto 3))))(((i + 1) * 8) - 1 downto i * 8) + <= wishbone_in.dat(((i + 1) * 8) - 1 downto i * 8); + end if; + end loop; + read_ack <= '1'; + state <= ACK; + elsif wishbone_in.stb = '1' then + wishbone_out.dat <= memory(to_integer(unsigned(wb_adr_in(wb_adr_in'left downto 3)))); + read_ack <= '1'; + state <= ACK; + end if; + when ACK => + if wishbone_in.stb = '0' then + read_ack <= '0'; + state <= IDLE; + end if; + end case; + else + state <= IDLE; + read_ack <= '0'; + end if; + end if; + end if; + end process; + +end architecture behaviour; diff --git a/fpga/pp_soc_memory.vhd b/fpga/pp_soc_memory.vhd deleted file mode 100644 index de39ec8..0000000 --- a/fpga/pp_soc_memory.vhd +++ /dev/null @@ -1,107 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use std.textio.all; - -use work.pp_utilities.all; - ---! @brief Simple memory module for use in Wishbone-based systems. -entity pp_soc_memory is - generic( - MEMORY_SIZE : natural := 4096; --! Memory size in bytes. - RAM_INIT_FILE : string - ); - port( - clk : in std_logic; - reset : in std_logic; - - -- Wishbone interface: - wb_adr_in : in std_logic_vector(log2(MEMORY_SIZE) - 1 downto 0); - wb_dat_in : in std_logic_vector(63 downto 0); - wb_dat_out : out std_logic_vector(63 downto 0); - wb_cyc_in : in std_logic; - wb_stb_in : in std_logic; - wb_sel_in : in std_logic_vector( 7 downto 0); - wb_we_in : in std_logic; - wb_ack_out : out std_logic - ); -end entity pp_soc_memory; - -architecture behaviour of pp_soc_memory is - type ram_t is array(0 to (MEMORY_SIZE / 8) - 1) of std_logic_vector(63 downto 0); - - impure function init_ram(name : STRING) return ram_t is - file ram_file : text open read_mode is name; - variable ram_line : line; - variable temp_word : std_logic_vector(63 downto 0); - variable temp_ram : ram_t := (others => (others => '0')); - begin - for i in 0 to (MEMORY_SIZE/8)-1 loop - exit when endfile(ram_file); - readline(ram_file, ram_line); - hread(ram_line, temp_word); - temp_ram(i) := temp_word; - end loop; - - return temp_ram; - end function; - - signal memory : ram_t := init_ram(RAM_INIT_FILE); - - attribute ram_style : string; - attribute ram_style of memory : signal is "block"; - - attribute ram_decomp : string; - attribute ram_decomp of memory : signal is "power"; - - type state_type is (IDLE, ACK); - signal state : state_type; - - signal read_ack : std_logic; - -begin - - wb_ack_out <= read_ack and wb_stb_in; - - memory_0: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - read_ack <= '0'; - state <= IDLE; - else - if wb_cyc_in = '1' then - case state is - when IDLE => - if wb_stb_in = '1' and wb_we_in = '1' then - for i in 0 to 7 loop - if wb_sel_in(i) = '1' then - memory(to_integer(unsigned(wb_adr_in(wb_adr_in'left downto 3))))(((i + 1) * 8) - 1 downto i * 8) - <= wb_dat_in(((i + 1) * 8) - 1 downto i * 8); - end if; - end loop; - read_ack <= '1'; - state <= ACK; - elsif wb_stb_in = '1' then - wb_dat_out <= memory(to_integer(unsigned(wb_adr_in(wb_adr_in'left downto 3)))); - read_ack <= '1'; - state <= ACK; - end if; - when ACK => - if wb_stb_in = '0' then - read_ack <= '0'; - state <= IDLE; - end if; - end case; - else - state <= IDLE; - read_ack <= '0'; - end if; - end if; - end if; - end process; - -end architecture behaviour; diff --git a/fpga/soc.vhdl b/fpga/soc.vhdl index 42f7d18..73907a2 100644 --- a/fpga/soc.vhdl +++ b/fpga/soc.vhdl @@ -46,14 +46,9 @@ architecture behaviour of soc is signal uart0_ack_out : std_logic; -- Main memory signals: - signal main_memory_adr_in : std_logic_vector(positive(ceil(log2(real(MEMORY_SIZE))))-1 downto 0); - signal main_memory_dat_in : std_logic_vector(63 downto 0); - signal main_memory_dat_out : std_logic_vector(63 downto 0); - signal main_memory_cyc_in : std_logic; - signal main_memory_stb_in : std_logic; - signal main_memory_sel_in : std_logic_vector(7 downto 0); - signal main_memory_we_in : std_logic; - signal main_memory_ack_out : std_logic; + signal wb_bram_in : wishbone_master_out; + signal wb_bram_out : wishbone_slave_out; + constant mem_adr_bits : positive := positive(ceil(log2(real(MEMORY_SIZE)))); begin @@ -82,8 +77,7 @@ begin ); -- Wishbone slaves address decoder & mux - slave_intercon: process(wb_master_out, - main_memory_ack_out, main_memory_dat_out, + slave_intercon: process(wb_master_out, wb_bram_out, uart0_ack_out, uart0_dat_out) -- Selected slave type slave_type is (SLAVE_UART, @@ -102,13 +96,13 @@ begin end if; -- Wishbone muxing. Defaults: - main_memory_cyc_in <= '0'; + wb_bram_in <= wb_master_out; + wb_bram_in.cyc <= '0'; uart0_cyc_in <= '0'; case slave is when SLAVE_MEMORY => - main_memory_cyc_in <= wb_master_out.cyc; - wb_master_in.ack <= main_memory_ack_out; - wb_master_in.dat <= main_memory_dat_out; + wb_bram_in.cyc <= wb_master_out.cyc; + wb_master_in <= wb_bram_out; when SLAVE_UART => uart0_cyc_in <= wb_master_out.cyc; wb_master_in.ack <= uart0_ack_out; @@ -147,27 +141,16 @@ begin uart0_stb_in <= wb_master_out.stb; -- BRAM Memory slave - main_memory: entity work.pp_soc_memory + bram0: entity work.mw_soc_memory generic map( MEMORY_SIZE => MEMORY_SIZE, RAM_INIT_FILE => RAM_INIT_FILE ) port map( clk => system_clk, - reset => rst, - wb_adr_in => main_memory_adr_in, - wb_dat_in => main_memory_dat_in, - wb_dat_out => main_memory_dat_out, - wb_cyc_in => main_memory_cyc_in, - wb_stb_in => main_memory_stb_in, - wb_sel_in => main_memory_sel_in, - wb_we_in => main_memory_we_in, - wb_ack_out => main_memory_ack_out + rst => rst, + wishbone_in => wb_bram_in, + wishbone_out => wb_bram_out ); - main_memory_adr_in <= wb_master_out.adr(main_memory_adr_in'range); - main_memory_dat_in <= wb_master_out.dat; - main_memory_we_in <= wb_master_out.we; - main_memory_sel_in <= wb_master_out.sel; - main_memory_stb_in <= wb_master_out.stb; end architecture behaviour; diff --git a/microwatt.core b/microwatt.core index 02500ad..f1bd8f0 100644 --- a/microwatt.core +++ b/microwatt.core @@ -32,7 +32,7 @@ filesets: soc: files: - fpga/pp_fifo.vhd - - fpga/pp_soc_memory.vhd + - fpga/mw_soc_memory.vhdl - fpga/soc_reset.vhdl - fpga/pp_soc_uart.vhd - fpga/pp_utilities.vhd