ECPIX-5: Add litedram support
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>pull/428/head
parent
8e9ec4d1b7
commit
2e8dc3f449
@ -0,0 +1,34 @@
|
|||||||
|
# Based on orangecrab-85-0.2.yml and arty.yml
|
||||||
|
|
||||||
|
{
|
||||||
|
"cpu": "None", # CPU type (ex vexriscv, serv, None)
|
||||||
|
"device": "LFE5UM5G-85F-8BG554I",
|
||||||
|
"memtype": "DDR3", # DRAM type
|
||||||
|
|
||||||
|
"cmd_latency": 0,
|
||||||
|
"sdram_module": "MT41K256M16", # SDRAM modules of the board or SO-DIMM
|
||||||
|
"sdram_module_nb": 2, # Number of byte groups
|
||||||
|
"sdram_rank_nb": 1, # Number of ranks
|
||||||
|
"sdram_phy": "ECP5DDRPHY", # Type of FPGA PHY
|
||||||
|
|
||||||
|
# Electrical ---------------------------------------------------------------
|
||||||
|
"rtt_nom": "60ohm", # Nominal termination. (Default)
|
||||||
|
"rtt_wr": "60ohm", # Write termination. (Default)
|
||||||
|
"ron": "34ohm", # Output driver impedance. (Default)
|
||||||
|
|
||||||
|
# Frequency ----------------------------------------------------------------
|
||||||
|
"input_clk_freq": 100e6, # Input clock frequency
|
||||||
|
"sys_clk_freq": 50e6, # System clock frequency (DDR_clk = 4 x sys_clk)
|
||||||
|
"init_clk_freq": 50e6, # ?
|
||||||
|
|
||||||
|
# Core ---------------------------------------------------------------------
|
||||||
|
"cmd_buffer_depth": 16, # Depth of the command buffer
|
||||||
|
|
||||||
|
# User Ports ---------------------------------------------------------------
|
||||||
|
"user_ports": {
|
||||||
|
"native_0": {
|
||||||
|
"type": "native",
|
||||||
|
"block_until_ready": False,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
@ -0,0 +1,123 @@
|
|||||||
|
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_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;
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue