1
0
mirror of https://github.com/antonblanchard/microwatt.git synced 2026-01-11 23:43:15 +00:00
Paul Mackerras ca4eb46aea Make wishbone addresses be in units of doublewords or words
This makes the 64-bit wishbone buses have the address expressed in
units of doublewords (64 bits), and similarly for the 32-bit buses the
address is in units of words (32 bits).  This is to comply with the
wishbone spec.  Previously the addresses on the wishbone buses were in
units of bytes regardless of the bus data width, which is not correct
and caused problems with interfacing with externally-generated logic.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
2021-09-15 18:18:09 +10:00

124 lines
4.2 KiB
VHDL

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.utils.all;
entity dram_init_mem is
generic (
EXTRA_PAYLOAD_FILE : string := "";
EXTRA_PAYLOAD_SIZE : integer := 0
);
port (
clk : in std_ulogic;
wb_in : in wb_io_master_out;
wb_out : out wb_io_slave_out
);
end entity dram_init_mem;
architecture rtl of dram_init_mem is
constant INIT_RAM_SIZE : integer := 24576;
constant RND_PAYLOAD_SIZE : integer := round_up(EXTRA_PAYLOAD_SIZE, 8);
constant TOTAL_RAM_SIZE : integer := INIT_RAM_SIZE + RND_PAYLOAD_SIZE;
constant INIT_RAM_ABITS : integer := log2ceil(TOTAL_RAM_SIZE-1);
constant INIT_RAM_FILE : string := "litedram/generated/sim/litedram_core.init";
type ram_t is array(0 to (TOTAL_RAM_SIZE / 4) - 1) of std_logic_vector(31 downto 0);
-- XXX FIXME: Have a single init function called twice with
-- an offset as argument
procedure init_load_payload(ram: inout ram_t; filename: string) is
file payload_file : text open read_mode is filename;
variable ram_line : line;
variable temp_word : std_logic_vector(63 downto 0);
begin
for i in 0 to RND_PAYLOAD_SIZE-1 loop
exit when endfile(payload_file);
readline(payload_file, ram_line);
hread(ram_line, temp_word);
ram((INIT_RAM_SIZE/4) + i*2) := temp_word(31 downto 0);
ram((INIT_RAM_SIZE/4) + i*2+1) := temp_word(63 downto 32);
end loop;
assert endfile(payload_file) report "Payload too big !" severity failure;
end procedure;
impure function init_load_ram(name : string) return ram_t is
file ram_file : text open read_mode is name;
variable temp_word : std_logic_vector(63 downto 0);
variable temp_ram : ram_t := (others => (others => '0'));
variable ram_line : line;
begin
report "Payload size:" & integer'image(EXTRA_PAYLOAD_SIZE) &
" rounded to:" & integer'image(RND_PAYLOAD_SIZE);
report "Total RAM size:" & integer'image(TOTAL_RAM_SIZE) &
" bytes using " & integer'image(INIT_RAM_ABITS) &
" address bits";
for i in 0 to (INIT_RAM_SIZE/8)-1 loop
exit when endfile(ram_file);
readline(ram_file, ram_line);
hread(ram_line, temp_word);
temp_ram(i*2) := temp_word(31 downto 0);
temp_ram(i*2+1) := temp_word(63 downto 32);
end loop;
if RND_PAYLOAD_SIZE /= 0 then
init_load_payload(temp_ram, EXTRA_PAYLOAD_FILE);
end if;
return temp_ram;
end function;
impure function init_zero return ram_t is
variable temp_ram : ram_t := (others => (others => '0'));
begin
return temp_ram;
end function;
impure function initialize_ram(filename: string) return ram_t is
begin
report "Opening file " & filename;
if filename'length = 0 then
return init_zero;
else
return init_load_ram(filename);
end if;
end function;
signal init_ram : ram_t := initialize_ram(INIT_RAM_FILE);
attribute ram_style : string;
attribute ram_style of init_ram: signal is "block";
signal obuf : std_ulogic_vector(31 downto 0);
signal oack : std_ulogic;
begin
init_ram_0: process(clk)
variable adr : integer;
begin
if rising_edge(clk) then
oack <= '0';
if (wb_in.cyc and wb_in.stb) = '1' then
adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS - 3 downto 0))));
if wb_in.we = '0' then
obuf <= init_ram(adr);
else
for i in 0 to 3 loop
if wb_in.sel(i) = '1' then
init_ram(adr)(((i + 1) * 8) - 1 downto i * 8) <=
wb_in.dat(((i + 1) * 8) - 1 downto i * 8);
end if;
end loop;
end if;
oack <= '1';
end if;
wb_out.ack <= oack;
wb_out.dat <= obuf;
end if;
end process;
wb_out.stall <= '0';
end architecture rtl;