litedram: Add support for booting without BRAM

This adds an option to disable the main BRAM and instead copy a
payload stashed along with the init code in the secondary BRAM
into DRAM and boot from there

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
jtag-port
Benjamin Herrenschmidt 5 years ago
parent 6fe077910b
commit bf1b98b958

@ -7,33 +7,52 @@ use work.common.all;
use work.wishbone_types.all; use work.wishbone_types.all;


entity core_dram_tb is entity core_dram_tb is
generic (
MEMORY_SIZE : natural := (384*1024);
MAIN_RAM_FILE : string := "main_ram.bin";
DRAM_INIT_FILE : string := "";
DRAM_INIT_SIZE : natural := 16#c000#
);
end core_dram_tb; end core_dram_tb;


architecture behave of core_dram_tb is architecture behave of core_dram_tb is
signal clk, rst: std_logic; signal clk, rst: std_logic;
signal system_clk, soc_rst : std_ulogic; signal system_clk, soc_rst : std_ulogic;


-- testbench signals -- testbench signals
constant clk_period : time := 10 ns; constant clk_period : time := 10 ns;


-- Sim DRAM -- Sim DRAM
signal wb_dram_in : wishbone_master_out; signal wb_dram_in : wishbone_master_out;
signal wb_dram_out : wishbone_slave_out; signal wb_dram_out : wishbone_slave_out;
signal wb_dram_ctrl_in : wb_io_master_out; signal wb_dram_ctrl_in : wb_io_master_out;
signal wb_dram_ctrl_out : wb_io_slave_out; signal wb_dram_ctrl_out : wb_io_slave_out;
signal wb_dram_is_csr : std_ulogic; signal wb_dram_is_csr : std_ulogic;
signal wb_dram_is_init : std_ulogic; signal wb_dram_is_init : std_ulogic;
signal core_alt_reset : std_ulogic; signal core_alt_reset : std_ulogic;

-- ROM size
function get_rom_size return natural is
begin
if MEMORY_SIZE = 0 then
return DRAM_INIT_SIZE;
else
return 0;
end if;
end function;

constant ROM_SIZE : natural := get_rom_size;
begin begin


soc0: entity work.soc soc0: entity work.soc
generic map( generic map(
SIM => true, SIM => true,
MEMORY_SIZE => (384*1024), MEMORY_SIZE => MEMORY_SIZE,
RAM_INIT_FILE => "main_ram.bin", RAM_INIT_FILE => MAIN_RAM_FILE,
RESET_LOW => false, RESET_LOW => false,
HAS_DRAM => true, HAS_DRAM => true,
DRAM_SIZE => 256 * 1024 * 1024, DRAM_SIZE => 256 * 1024 * 1024,
DRAM_INIT_SIZE => ROM_SIZE,
CLK_FREQ => 100000000 CLK_FREQ => 100000000
) )
port map( port map(
@ -50,48 +69,50 @@ begin
alt_reset => core_alt_reset alt_reset => core_alt_reset
); );


dram: entity work.litedram_wrapper dram: entity work.litedram_wrapper
generic map( generic map(
DRAM_ABITS => 24, DRAM_ABITS => 24,
DRAM_ALINES => 1 DRAM_ALINES => 1,
) PAYLOAD_FILE => DRAM_INIT_FILE,
port map( PAYLOAD_SIZE => ROM_SIZE
clk_in => clk, )
rst => rst, port map(
system_clk => system_clk, clk_in => clk,
system_reset => soc_rst, rst => rst,
core_alt_reset => core_alt_reset, system_clk => system_clk,
pll_locked => open, system_reset => soc_rst,

core_alt_reset => core_alt_reset,
wb_in => wb_dram_in, pll_locked => open,
wb_out => wb_dram_out,
wb_ctrl_in => wb_dram_ctrl_in, wb_in => wb_dram_in,
wb_ctrl_out => wb_dram_ctrl_out, wb_out => wb_dram_out,
wb_ctrl_is_csr => wb_dram_is_csr, wb_ctrl_in => wb_dram_ctrl_in,
wb_ctrl_is_init => wb_dram_is_init, wb_ctrl_out => wb_dram_ctrl_out,

wb_ctrl_is_csr => wb_dram_is_csr,
serial_tx => open, wb_ctrl_is_init => wb_dram_is_init,
serial_rx => '1',

serial_tx => open,
init_done => open, serial_rx => '1',
init_error => open,

init_done => open,
ddram_a => open, init_error => open,
ddram_ba => open,
ddram_ras_n => open, ddram_a => open,
ddram_cas_n => open, ddram_ba => open,
ddram_we_n => open, ddram_ras_n => open,
ddram_cs_n => open, ddram_cas_n => open,
ddram_dm => open, ddram_we_n => open,
ddram_dq => open, ddram_cs_n => open,
ddram_dqs_p => open, ddram_dm => open,
ddram_dqs_n => open, ddram_dq => open,
ddram_clk_p => open, ddram_dqs_p => open,
ddram_clk_n => open, ddram_dqs_n => open,
ddram_cke => open, ddram_clk_p => open,
ddram_odt => open, ddram_clk_n => open,
ddram_reset_n => open ddram_cke => open,
); ddram_odt => open,
ddram_reset_n => open
);


clk_process: process clk_process: process
begin begin

@ -10,11 +10,12 @@ use work.wishbone_types.all;


entity toplevel is entity toplevel is
generic ( generic (
MEMORY_SIZE : positive := 16384; MEMORY_SIZE : integer := 16384;
RAM_INIT_FILE : string := "firmware.hex"; RAM_INIT_FILE : string := "firmware.hex";
RESET_LOW : boolean := true; RESET_LOW : boolean := true;
CLK_FREQUENCY : positive := 100000000; CLK_FREQUENCY : positive := 100000000;
USE_LITEDRAM : boolean := false; USE_LITEDRAM : boolean := false;
NO_BRAM : boolean := false;
DISABLE_FLATTEN_CORE : boolean := false DISABLE_FLATTEN_CORE : boolean := false
); );
port( port(
@ -85,6 +86,28 @@ architecture behaviour of toplevel is


-- Dumb PWM for the LEDs, those RGB LEDs are too bright otherwise -- Dumb PWM for the LEDs, those RGB LEDs are too bright otherwise
signal pwm_counter : std_ulogic_vector(8 downto 0); signal pwm_counter : std_ulogic_vector(8 downto 0);

-- Fixup various memory sizes based on generics
function get_bram_size return natural is
begin
if USE_LITEDRAM and NO_BRAM then
return 0;
else
return MEMORY_SIZE;
end if;
end function;

function get_payload_size return natural is
begin
if USE_LITEDRAM and NO_BRAM then
return MEMORY_SIZE;
else
return 0;
end if;
end function;
constant BRAM_SIZE : natural := get_bram_size;
constant PAYLOAD_SIZE : natural := get_payload_size;
begin begin


uart_pmod_rts_n <= '0'; uart_pmod_rts_n <= '0';
@ -92,13 +115,14 @@ begin
-- Main SoC -- Main SoC
soc0: entity work.soc soc0: entity work.soc
generic map( generic map(
MEMORY_SIZE => MEMORY_SIZE, MEMORY_SIZE => BRAM_SIZE,
RAM_INIT_FILE => RAM_INIT_FILE, RAM_INIT_FILE => RAM_INIT_FILE,
RESET_LOW => RESET_LOW, RESET_LOW => RESET_LOW,
SIM => false, SIM => false,
CLK_FREQ => CLK_FREQUENCY, CLK_FREQ => CLK_FREQUENCY,
HAS_DRAM => USE_LITEDRAM, HAS_DRAM => USE_LITEDRAM,
DRAM_SIZE => 256 * 1024 * 1024, DRAM_SIZE => 256 * 1024 * 1024,
DRAM_INIT_SIZE => PAYLOAD_SIZE,
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE
) )
port map ( port map (
@ -159,7 +183,7 @@ begin
); );
ddram_clk_dummy <= '0'; ddram_clk_dummy <= '0';


end generate; end generate;


has_dram: if USE_LITEDRAM generate has_dram: if USE_LITEDRAM generate
signal dram_init_done : std_ulogic; signal dram_init_done : std_ulogic;
@ -189,7 +213,9 @@ begin
dram: entity work.litedram_wrapper dram: entity work.litedram_wrapper
generic map( generic map(
DRAM_ABITS => 24, DRAM_ABITS => 24,
DRAM_ALINES => 14 DRAM_ALINES => 14,
PAYLOAD_FILE => RAM_INIT_FILE,
PAYLOAD_SIZE => PAYLOAD_SIZE
) )
port map( port map(
clk_in => ext_clk, clk_in => ext_clk,

@ -10,11 +10,12 @@ use work.wishbone_types.all;


entity toplevel is entity toplevel is
generic ( generic (
MEMORY_SIZE : positive := 16384; MEMORY_SIZE : integer := 16384;
RAM_INIT_FILE : string := "firmware.hex"; RAM_INIT_FILE : string := "firmware.hex";
RESET_LOW : boolean := true; RESET_LOW : boolean := true;
CLK_FREQUENCY : positive := 100000000; CLK_FREQUENCY : positive := 100000000;
USE_LITEDRAM : boolean := false; USE_LITEDRAM : boolean := false;
NO_BRAM : boolean := false;
DISABLE_FLATTEN_CORE : boolean := false DISABLE_FLATTEN_CORE : boolean := false
); );
port( port(
@ -70,18 +71,40 @@ architecture behaviour of toplevel is
-- Control/status -- Control/status
signal core_alt_reset : std_ulogic; signal core_alt_reset : std_ulogic;


-- Fixup various memory sizes based on generics
function get_bram_size return natural is
begin
if USE_LITEDRAM and NO_BRAM then
return 0;
else
return MEMORY_SIZE;
end if;
end function;

function get_payload_size return natural is
begin
if USE_LITEDRAM and NO_BRAM then
return MEMORY_SIZE;
else
return 0;
end if;
end function;
constant BRAM_SIZE : natural := get_bram_size;
constant PAYLOAD_SIZE : natural := get_payload_size;
begin begin


-- Main SoC -- Main SoC
soc0: entity work.soc soc0: entity work.soc
generic map( generic map(
MEMORY_SIZE => MEMORY_SIZE, MEMORY_SIZE => BRAM_SIZE,
RAM_INIT_FILE => RAM_INIT_FILE, RAM_INIT_FILE => RAM_INIT_FILE,
RESET_LOW => RESET_LOW, RESET_LOW => RESET_LOW,
SIM => false, SIM => false,
CLK_FREQ => CLK_FREQUENCY, CLK_FREQ => CLK_FREQUENCY,
HAS_DRAM => USE_LITEDRAM, HAS_DRAM => USE_LITEDRAM,
DRAM_SIZE => 512 * 1024 * 1024, DRAM_SIZE => 512 * 1024 * 1024,
DRAM_INIT_SIZE => PAYLOAD_SIZE,
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE
) )
port map ( port map (
@ -171,7 +194,9 @@ begin
dram: entity work.litedram_wrapper dram: entity work.litedram_wrapper
generic map( generic map(
DRAM_ABITS => 25, DRAM_ABITS => 25,
DRAM_ALINES => 15 DRAM_ALINES => 15,
PAYLOAD_FILE => RAM_INIT_FILE,
PAYLOAD_SIZE => PAYLOAD_SIZE
) )
port map( port map(
clk_in => ext_clk, clk_in => ext_clk,

@ -23,6 +23,7 @@
#define SYS_REG_INFO 0x08 #define SYS_REG_INFO 0x08
#define SYS_REG_INFO_HAS_UART (1ull << 0) #define SYS_REG_INFO_HAS_UART (1ull << 0)
#define SYS_REG_INFO_HAS_DRAM (1ull << 1) #define SYS_REG_INFO_HAS_DRAM (1ull << 1)
#define SYS_REG_INFO_HAS_BRAM (1ull << 2)
#define SYS_REG_BRAMINFO 0x10 #define SYS_REG_BRAMINFO 0x10
#define SYS_REG_DRAMINFO 0x18 #define SYS_REG_DRAMINFO 0x18
#define SYS_REG_CLKINFO 0x20 #define SYS_REG_CLKINFO 0x20
@ -30,6 +31,7 @@
#define SYS_REG_CTRL_DRAM_AT_0 (1ull << 0) #define SYS_REG_CTRL_DRAM_AT_0 (1ull << 0)
#define SYS_REG_CTRL_CORE_RESET (1ull << 1) #define SYS_REG_CTRL_CORE_RESET (1ull << 1)
#define SYS_REG_CTRL_SOC_RESET (1ull << 2) #define SYS_REG_CTRL_SOC_RESET (1ull << 2)
#define SYS_REG_DRAMINITINFO 0x30


/* /*
* Register definitions for the potato UART * Register definitions for the potato UART

@ -6,7 +6,8 @@ import pathlib


class LiteDRAMGenerator(Generator): class LiteDRAMGenerator(Generator):
def run(self): def run(self):
board = self.config.get('board') board = self.config.get('board')
payload = self.config.get('payload')


# Collect a bunch of directory path # Collect a bunch of directory path
script_dir = os.path.dirname(sys.argv[0]) script_dir = os.path.dirname(sys.argv[0])

@ -10,6 +10,9 @@ entity litedram_wrapper is
generic ( generic (
DRAM_ABITS : positive; DRAM_ABITS : positive;
DRAM_ALINES : positive; DRAM_ALINES : positive;
-- Pseudo-ROM payload
PAYLOAD_SIZE : natural;
PAYLOAD_FILE : string;
-- Debug -- Debug
LITEDRAM_TRACE : boolean := false LITEDRAM_TRACE : boolean := false
); );
@ -144,6 +147,10 @@ begin


-- Init code BRAM memory slave -- Init code BRAM memory slave
init_ram_0: entity work.dram_init_mem init_ram_0: entity work.dram_init_mem
generic map(
EXTRA_PAYLOAD_FILE => PAYLOAD_FILE,
EXTRA_PAYLOAD_SIZE => PAYLOAD_SIZE
)
port map( port map(
clk => system_clk, clk => system_clk,
wb_in => wb_init_in, wb_in => wb_init_in,

@ -5,66 +5,117 @@ use std.textio.all;


library work; library work;
use work.wishbone_types.all; use work.wishbone_types.all;
use work.utils.all;


entity dram_init_mem is entity dram_init_mem is
generic (
EXTRA_PAYLOAD_FILE : string := "";
EXTRA_PAYLOAD_SIZE : integer := 0
);
port ( port (
clk : in std_ulogic; clk : in std_ulogic;
wb_in : in wb_io_master_out; wb_in : in wb_io_master_out;
wb_out : out wb_io_slave_out wb_out : out wb_io_slave_out
); );
end entity dram_init_mem; end entity dram_init_mem;


architecture rtl of dram_init_mem is architecture rtl of dram_init_mem is


constant INIT_RAM_SIZE : integer := 16384; constant INIT_RAM_SIZE : integer := 16384;
constant INIT_RAM_ABITS :integer := 14; constant RND_PAYLOAD_SIZE : integer := round_up(EXTRA_PAYLOAD_SIZE, 8);
constant INIT_RAM_FILE : string := "litedram_core.init"; constant TOTAL_RAM_SIZE : integer := INIT_RAM_SIZE + RND_PAYLOAD_SIZE;
constant INIT_RAM_ABITS : integer := log2ceil(TOTAL_RAM_SIZE);
constant INIT_RAM_FILE : string := "litedram_core.init";


type ram_t is array(0 to (INIT_RAM_SIZE / 4) - 1) of std_logic_vector(31 downto 0); 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 impure function init_load_ram(name : string) return ram_t is
file ram_file : text open read_mode is name; file ram_file : text open read_mode is name;
variable temp_word : std_logic_vector(63 downto 0); variable temp_word : std_logic_vector(63 downto 0);
variable temp_ram : ram_t := (others => (others => '0')); variable temp_ram : ram_t := (others => (others => '0'));
variable ram_line : line; variable ram_line : line;
begin begin
for i in 0 to (INIT_RAM_SIZE/8)-1 loop report "Payload size:" & integer'image(EXTRA_PAYLOAD_SIZE) &
exit when endfile(ram_file); " rounded to:" & integer'image(RND_PAYLOAD_SIZE);
readline(ram_file, ram_line); report "Total RAM size:" & integer'image(TOTAL_RAM_SIZE) &
hread(ram_line, temp_word); " bytes using " & integer'image(INIT_RAM_ABITS) &
temp_ram(i*2) := temp_word(31 downto 0); " address bits";
temp_ram(i*2+1) := temp_word(63 downto 32); for i in 0 to (INIT_RAM_SIZE/8)-1 loop
end loop; exit when endfile(ram_file);
return temp_ram; 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; end function;


signal init_ram : ram_t := init_load_ram(INIT_RAM_FILE); 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 : string;
attribute ram_style of init_ram: signal is "block"; attribute ram_style of init_ram: signal is "block";


signal obuf : std_ulogic_vector(31 downto 0);
signal oack : std_ulogic;
begin begin


init_ram_0: process(clk) init_ram_0: process(clk)
variable adr : integer; variable adr : integer;
begin begin
if rising_edge(clk) then if rising_edge(clk) then
wb_out.ack <= '0'; oack <= '0';
if (wb_in.cyc and wb_in.stb) = '1' then if (wb_in.cyc and wb_in.stb) = '1' then
adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS-1 downto 2)))); adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS-1 downto 2))));
if wb_in.we = '0' then if wb_in.we = '0' then
wb_out.dat <= init_ram(adr); obuf <= init_ram(adr);
else else
for i in 0 to 3 loop for i in 0 to 3 loop
if wb_in.sel(i) = '1' then if wb_in.sel(i) = '1' then
init_ram(adr)(((i + 1) * 8) - 1 downto i * 8) <= init_ram(adr)(((i + 1) * 8) - 1 downto i * 8) <=
wb_in.dat(((i + 1) * 8) - 1 downto i * 8); wb_in.dat(((i + 1) * 8) - 1 downto i * 8);
end if; end if;
end loop; end loop;
end if; end if;
wb_out.ack <= '1'; oack <= '1';
end if; end if;
end if; wb_out.ack <= oack;
wb_out.dat <= obuf;
end if;
end process; end process;


wb_out.stall <= '0'; wb_out.stall <= '0';

@ -54,12 +54,18 @@ void main(void)
printf("UART "); printf("UART ");
if (ftr & SYS_REG_INFO_HAS_DRAM) if (ftr & SYS_REG_INFO_HAS_DRAM)
printf("DRAM "); printf("DRAM ");
if (ftr & SYS_REG_INFO_HAS_BRAM)
printf("BRAM ");
printf("\n"); printf("\n");
val = readq(SYSCON_BASE + SYS_REG_BRAMINFO); if (ftr & SYS_REG_INFO_HAS_BRAM) {
printf(" BRAM: %lld KB\n", val / 1024); val = readq(SYSCON_BASE + SYS_REG_BRAMINFO);
printf(" BRAM: %lld KB\n", val / 1024);
}
if (ftr & SYS_REG_INFO_HAS_DRAM) { if (ftr & SYS_REG_INFO_HAS_DRAM) {
val = readq(SYSCON_BASE + SYS_REG_DRAMINFO); val = readq(SYSCON_BASE + SYS_REG_DRAMINFO);
printf(" DRAM: %lld MB\n", val / (1024 * 1024)); printf(" DRAM: %lld MB\n", val / (1024 * 1024));
val = readq(SYSCON_BASE + SYS_REG_DRAMINITINFO);
printf(" DRAM INIT: %lld KB\n", val / 1024);
} }
val = readq(SYSCON_BASE + SYS_REG_CLKINFO); val = readq(SYSCON_BASE + SYS_REG_CLKINFO);
printf(" CLK: %lld MHz\n", val / 1000000); printf(" CLK: %lld MHz\n", val / 1000000);
@ -70,5 +76,15 @@ void main(void)
MIGEN_GIT_SHA1, LITEX_GIT_SHA1); MIGEN_GIT_SHA1, LITEX_GIT_SHA1);
sdrinit(); sdrinit();
} }
printf("Booting from BRAM...\n"); if (ftr & SYS_REG_INFO_HAS_BRAM)
printf("Booting from BRAM...\n");
else {
void *s = (void *)(DRAM_INIT_BASE + 0x4000);
void *d = (void *)DRAM_BASE;
int sz = (0x10000 - 0x4000);
printf("Copying payload to DRAM...\n");
memcpy(d, s, sz);
printf("Booting from DRAM...\n");
flush_cpu_icache();
}
} }

@ -5,8 +5,13 @@ use std.textio.all;


library work; library work;
use work.wishbone_types.all; use work.wishbone_types.all;
use work.utils.all;


entity dram_init_mem is entity dram_init_mem is
generic (
EXTRA_PAYLOAD_FILE : string := "";
EXTRA_PAYLOAD_SIZE : integer := 0
);
port ( port (
clk : in std_ulogic; clk : in std_ulogic;
wb_in : in wb_io_master_out; wb_in : in wb_io_master_out;
@ -16,11 +21,30 @@ end entity dram_init_mem;


architecture rtl of dram_init_mem is architecture rtl of dram_init_mem is


constant INIT_RAM_SIZE : integer := 16384; constant INIT_RAM_SIZE : integer := 16384;
constant INIT_RAM_ABITS :integer := 14; constant RND_PAYLOAD_SIZE : integer := round_up(EXTRA_PAYLOAD_SIZE, 8);
constant INIT_RAM_FILE : string := "litedram_core.init"; constant TOTAL_RAM_SIZE : integer := INIT_RAM_SIZE + RND_PAYLOAD_SIZE;
constant INIT_RAM_ABITS : integer := log2ceil(TOTAL_RAM_SIZE);
constant INIT_RAM_FILE : string := "litedram_core.init";


type ram_t is array(0 to (INIT_RAM_SIZE / 4) - 1) of std_logic_vector(31 downto 0); 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 impure function init_load_ram(name : string) return ram_t is
file ram_file : text open read_mode is name; file ram_file : text open read_mode is name;
@ -28,6 +52,11 @@ architecture rtl of dram_init_mem is
variable temp_ram : ram_t := (others => (others => '0')); variable temp_ram : ram_t := (others => (others => '0'));
variable ram_line : line; variable ram_line : line;
begin 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 for i in 0 to (INIT_RAM_SIZE/8)-1 loop
exit when endfile(ram_file); exit when endfile(ram_file);
readline(ram_file, ram_line); readline(ram_file, ram_line);
@ -35,25 +64,45 @@ architecture rtl of dram_init_mem is
temp_ram(i*2) := temp_word(31 downto 0); temp_ram(i*2) := temp_word(31 downto 0);
temp_ram(i*2+1) := temp_word(63 downto 32); temp_ram(i*2+1) := temp_word(63 downto 32);
end loop; end loop;
if RND_PAYLOAD_SIZE /= 0 then
init_load_payload(temp_ram, EXTRA_PAYLOAD_FILE);
end if;
return temp_ram; return temp_ram;
end function; end function;


signal init_ram : ram_t := init_load_ram(INIT_RAM_FILE); 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 : string;
attribute ram_style of init_ram: signal is "block"; attribute ram_style of init_ram: signal is "block";


signal obuf : std_ulogic_vector(31 downto 0);
signal oack : std_ulogic;
begin begin


init_ram_0: process(clk) init_ram_0: process(clk)
variable adr : integer; variable adr : integer;
begin begin
if rising_edge(clk) then if rising_edge(clk) then
wb_out.ack <= '0'; oack <= '0';
if (wb_in.cyc and wb_in.stb) = '1' then if (wb_in.cyc and wb_in.stb) = '1' then
adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS-1 downto 2)))); adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS-1 downto 2))));
if wb_in.we = '0' then if wb_in.we = '0' then
wb_out.dat <= init_ram(adr); obuf <= init_ram(adr);
else else
for i in 0 to 3 loop for i in 0 to 3 loop
if wb_in.sel(i) = '1' then if wb_in.sel(i) = '1' then
@ -62,8 +111,10 @@ begin
end if; end if;
end loop; end loop;
end if; end if;
wb_out.ack <= '1'; oack <= '1';
end if; end if;
wb_out.ack <= oack;
wb_out.dat <= obuf;
end if; end if;
end process; end process;



File diff suppressed because it is too large Load Diff

@ -1,5 +1,5 @@
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
// Auto-generated by Migen (0d16e03) & LiteX (564d731a) on 2020-05-22 17:57:16 // Auto-generated by Migen (0d16e03) & LiteX (564d731a) on 2020-05-26 20:37:38
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
module litedram_core( module litedram_core(
input wire clk, input wire clk,

@ -5,66 +5,117 @@ use std.textio.all;


library work; library work;
use work.wishbone_types.all; use work.wishbone_types.all;
use work.utils.all;


entity dram_init_mem is entity dram_init_mem is
generic (
EXTRA_PAYLOAD_FILE : string := "";
EXTRA_PAYLOAD_SIZE : integer := 0
);
port ( port (
clk : in std_ulogic; clk : in std_ulogic;
wb_in : in wb_io_master_out; wb_in : in wb_io_master_out;
wb_out : out wb_io_slave_out wb_out : out wb_io_slave_out
); );
end entity dram_init_mem; end entity dram_init_mem;


architecture rtl of dram_init_mem is architecture rtl of dram_init_mem is


constant INIT_RAM_SIZE : integer := 16384; constant INIT_RAM_SIZE : integer := 16384;
constant INIT_RAM_ABITS :integer := 14; constant RND_PAYLOAD_SIZE : integer := round_up(EXTRA_PAYLOAD_SIZE, 8);
constant INIT_RAM_FILE : string := "litedram_core.init"; constant TOTAL_RAM_SIZE : integer := INIT_RAM_SIZE + RND_PAYLOAD_SIZE;
constant INIT_RAM_ABITS : integer := log2ceil(TOTAL_RAM_SIZE);
constant INIT_RAM_FILE : string := "litedram_core.init";


type ram_t is array(0 to (INIT_RAM_SIZE / 4) - 1) of std_logic_vector(31 downto 0); 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 impure function init_load_ram(name : string) return ram_t is
file ram_file : text open read_mode is name; file ram_file : text open read_mode is name;
variable temp_word : std_logic_vector(63 downto 0); variable temp_word : std_logic_vector(63 downto 0);
variable temp_ram : ram_t := (others => (others => '0')); variable temp_ram : ram_t := (others => (others => '0'));
variable ram_line : line; variable ram_line : line;
begin begin
for i in 0 to (INIT_RAM_SIZE/8)-1 loop report "Payload size:" & integer'image(EXTRA_PAYLOAD_SIZE) &
exit when endfile(ram_file); " rounded to:" & integer'image(RND_PAYLOAD_SIZE);
readline(ram_file, ram_line); report "Total RAM size:" & integer'image(TOTAL_RAM_SIZE) &
hread(ram_line, temp_word); " bytes using " & integer'image(INIT_RAM_ABITS) &
temp_ram(i*2) := temp_word(31 downto 0); " address bits";
temp_ram(i*2+1) := temp_word(63 downto 32); for i in 0 to (INIT_RAM_SIZE/8)-1 loop
end loop; exit when endfile(ram_file);
return temp_ram; 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; end function;


signal init_ram : ram_t := init_load_ram(INIT_RAM_FILE); 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 : string;
attribute ram_style of init_ram: signal is "block"; attribute ram_style of init_ram: signal is "block";


signal obuf : std_ulogic_vector(31 downto 0);
signal oack : std_ulogic;
begin begin


init_ram_0: process(clk) init_ram_0: process(clk)
variable adr : integer; variable adr : integer;
begin begin
if rising_edge(clk) then if rising_edge(clk) then
wb_out.ack <= '0'; oack <= '0';
if (wb_in.cyc and wb_in.stb) = '1' then if (wb_in.cyc and wb_in.stb) = '1' then
adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS-1 downto 2)))); adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS-1 downto 2))));
if wb_in.we = '0' then if wb_in.we = '0' then
wb_out.dat <= init_ram(adr); obuf <= init_ram(adr);
else else
for i in 0 to 3 loop for i in 0 to 3 loop
if wb_in.sel(i) = '1' then if wb_in.sel(i) = '1' then
init_ram(adr)(((i + 1) * 8) - 1 downto i * 8) <= init_ram(adr)(((i + 1) * 8) - 1 downto i * 8) <=
wb_in.dat(((i + 1) * 8) - 1 downto i * 8); wb_in.dat(((i + 1) * 8) - 1 downto i * 8);
end if; end if;
end loop; end loop;
end if; end if;
wb_out.ack <= '1'; oack <= '1';
end if; end if;
end if; wb_out.ack <= oack;
wb_out.dat <= obuf;
end if;
end process; end process;


wb_out.stall <= '0'; wb_out.stall <= '0';

File diff suppressed because it is too large Load Diff

@ -1,5 +1,5 @@
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
// Auto-generated by Migen (0d16e03) & LiteX (564d731a) on 2020-05-22 17:57:18 // Auto-generated by Migen (0d16e03) & LiteX (564d731a) on 2020-05-26 20:37:40
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
module litedram_core( module litedram_core(
input wire clk, input wire clk,

@ -5,66 +5,118 @@ use std.textio.all;


library work; library work;
use work.wishbone_types.all; use work.wishbone_types.all;
use work.utils.all;


entity dram_init_mem is entity dram_init_mem is
generic (
EXTRA_PAYLOAD_FILE : string := "";
EXTRA_PAYLOAD_SIZE : integer := 0
);
port ( port (
clk : in std_ulogic; clk : in std_ulogic;
wb_in : in wb_io_master_out; wb_in : in wb_io_master_out;
wb_out : out wb_io_slave_out wb_out : out wb_io_slave_out
); );
end entity dram_init_mem; end entity dram_init_mem;


architecture rtl of dram_init_mem is architecture rtl of dram_init_mem is


constant INIT_RAM_SIZE : integer := 16384; constant INIT_RAM_SIZE : integer := 16384;
constant INIT_RAM_ABITS :integer := 14; constant RND_PAYLOAD_SIZE : integer := round_up(EXTRA_PAYLOAD_SIZE, 8);
constant INIT_RAM_FILE : string := "litedram/generated/sim/litedram_core.init"; constant TOTAL_RAM_SIZE : integer := INIT_RAM_SIZE + RND_PAYLOAD_SIZE;
constant INIT_RAM_ABITS : integer := log2ceil(TOTAL_RAM_SIZE);
constant INIT_RAM_FILE : string := "litedram/generated/sim/litedram_core.init";


type ram_t is array(0 to (INIT_RAM_SIZE / 4) - 1) of std_logic_vector(31 downto 0); 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 impure function init_load_ram(name : string) return ram_t is
file ram_file : text open read_mode is name; file ram_file : text open read_mode is name;
variable temp_word : std_logic_vector(63 downto 0); file payload_file : text open read_mode is EXTRA_PAYLOAD_FILE;
variable temp_ram : ram_t := (others => (others => '0')); variable temp_word : std_logic_vector(63 downto 0);
variable ram_line : line; variable temp_ram : ram_t := (others => (others => '0'));
variable ram_line : line;
begin begin
for i in 0 to (INIT_RAM_SIZE/8)-1 loop report "Payload size:" & integer'image(EXTRA_PAYLOAD_SIZE) &
exit when endfile(ram_file); " rounded to:" & integer'image(RND_PAYLOAD_SIZE);
readline(ram_file, ram_line); report "Total RAM size:" & integer'image(TOTAL_RAM_SIZE) &
hread(ram_line, temp_word); " bytes using " & integer'image(INIT_RAM_ABITS) &
temp_ram(i*2) := temp_word(31 downto 0); " address bits";
temp_ram(i*2+1) := temp_word(63 downto 32); for i in 0 to (INIT_RAM_SIZE/8)-1 loop
end loop; exit when endfile(ram_file);
return temp_ram; 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
procedure init_load_payload(ram: inout ram_t; filename: string) is
end if;
return temp_ram;
end function; end function;


signal init_ram : ram_t := init_load_ram(INIT_RAM_FILE); 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 : string;
attribute ram_style of init_ram: signal is "block"; attribute ram_style of init_ram: signal is "block";


signal obuf : std_ulogic_vector(31 downto 0);
signal oack : std_ulogic;
begin begin


init_ram_0: process(clk) init_ram_0: process(clk)
variable adr : integer; variable adr : integer;
begin begin
if rising_edge(clk) then if rising_edge(clk) then
wb_out.ack <= '0'; oack <= '0';
if (wb_in.cyc and wb_in.stb) = '1' then if (wb_in.cyc and wb_in.stb) = '1' then
adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS-1 downto 2)))); adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS-1 downto 2))));
if wb_in.we = '0' then if wb_in.we = '0' then
wb_out.dat <= init_ram(adr); obuf <= init_ram(adr);
else else
for i in 0 to 3 loop for i in 0 to 3 loop
if wb_in.sel(i) = '1' then if wb_in.sel(i) = '1' then
init_ram(adr)(((i + 1) * 8) - 1 downto i * 8) <= init_ram(adr)(((i + 1) * 8) - 1 downto i * 8) <=
wb_in.dat(((i + 1) * 8) - 1 downto i * 8); wb_in.dat(((i + 1) * 8) - 1 downto i * 8);
end if; end if;
end loop; end loop;
end if; end if;
wb_out.ack <= '1'; oack <= '1';
end if; end if;
end if; wb_out.ack <= oack;
wb_out.dat <= obuf;
end if;
end process; end process;


wb_out.stall <= '0'; wb_out.stall <= '0';

@ -7,7 +7,7 @@ a64b5a7d14004a39
6421f000782107c6 6421f000782107c6
3d80000060213f00 3d80000060213f00
798c07c6618c0000 798c07c6618c0000
618c108c658cf000 618c10a4658cf000
4e8004217d8903a6 4e8004217d8903a6
0000000048000002 0000000048000002
0000000000000000 0000000000000000
@ -510,7 +510,7 @@ a64b5a7d14004a39
0000000000000000 0000000000000000
0000000000000000 0000000000000000
0000000000000000 0000000000000000
384295003c4c0001 384296003c4c0001
fbc1fff07c0802a6 fbc1fff07c0802a6
f8010010fbe1fff8 f8010010fbe1fff8
3be10020f821fe91 3be10020f821fe91
@ -519,61 +519,83 @@ f8c101a838800140
38c101987c651b78 38c101987c651b78
7fe3fb78f8e101b0 7fe3fb78f8e101b0
f92101c0f90101b8 f92101c0f90101b8
48000c89f94101c8 48000da5f94101c8
7c7e1b7860000000 7c7e1b7860000000
4800080d7fe3fb78 480008bd7fe3fb78
3821017060000000 3821017060000000
480012487fc3f378 480013647fc3f378
0100000000000000 0100000000000000
4e80002000000280 4e80002000000280
0000000000000000 0000000000000000
7c0007ac00000000
4e8000204c00012c
0000000000000000
3c4c000100000000 3c4c000100000000
7c0802a638429474 7c0802a63842955c
7d908026fbe1fff8 7d800026fbe1fff8
f801001091810008 91810008f8010010
48000719f821ff91 480007b1f821ff91
3c62ffff60000000 3c62ffff60000000
4bffff4d38637dc8 4bffff3538637de8
548400023880ffff 548400023880ffff
7c8026ea7c0004ac 7c8026ea7c0004ac
3fe0c0003c62ffff 3fe0c0003c62ffff
63ff000838637de8 63ff000838637e08
3c62ffff4bffff29 3c62ffff4bffff11
38637e087bff0020 38637e287bff0020
7c0004ac4bffff19 7c0004ac4bffff01
73e900017fe0feea 73e900017fe0feea
3c62ffff41820010 3c62ffff41820010
4bfffefd38637e20 4bfffee538637e40
4e00000073e90002 4d80000073e90002
3c62ffff41820010 3c62ffff41820010
4bfffee538637e28 4bfffecd38637e48
3bff7fc83fe2ffff 4e00000073e90004
4bfffed57fe3fb78 3c62ffff41820010
608400103c80c000 4bfffeb538637e50
7c0004ac78840020 3be2804860000000
3c62ffff7c8026ea 4bfffea57fe3fb78
38637e307884b282 3c80c00041920028
419200284bfffeb1 7884002060840010
608400183c80c000 7c8026ea7c0004ac
7884b2823c62ffff
4bfffe7d38637e58
3c80c000418e004c
7884002060840018
7c8026ea7c0004ac
788465023c62ffff
4bfffe5538637e78
608400303c80c000
7c0004ac78840020 7c0004ac78840020
3c62ffff7c8026ea 3c62ffff7c8026ea
38637e5078846502 38637e987884b282
3d20c0004bfffe89 3d20c0004bfffe31
7929002061290020 7929002061290020
7d204eea7c0004ac 7d204eea7c0004ac
3c62ffff3c80000f 3c62ffff3c80000f
38637e7060844240 38637eb860844240
4bfffe5d7c892392 4bfffe057c892392
4bfffe557fe3fb78 4bfffdfd7fe3fb78
3ca2ffff41920028 3ca2ffff418e0028
3c62ffff3c82ffff 3c62ffff3c82ffff
38847ea038a57e90 38847ee838a57ed8
4bfffe3538637ea8 4bfffddd38637ef0
6000000048000469 60000000480004c1
38637ed83c62ffff 3c62ffff41920020
382100704bfffe21 4bfffdc538637f20
7d90812081810008 8181000838210070
00000000480010c0 480011807d818120
38637f383c62ffff
3c80f0004bfffda9
6084400038a0ffff
7884002054a50422
480008553c604000
3c62ffff60000000
4bfffd7d38637f58
e801001038210070
ebe1fff881810008
7d8181207c0803a6
000000004bfffde4
0000018003000000 0000018003000000
612908083d20c010 612908083d20c010
7c0004ac79290020 7c0004ac79290020
@ -583,26 +605,26 @@ f801001091810008
4e8000207d20572a 4e8000207d20572a
0000000000000000 0000000000000000
3c4c000100000000 3c4c000100000000
7c0802a6384292bc 7c0802a63842930c
614a08003d40c010 614a08003d40c010
794a002039200001 794a002039200001
f821ffa1f8010010 f821ffa1f8010010
7d20572a7c0004ac 7d20572a7c0004ac
38637fa83c62ffff 3862802860000000
600000004bfffd91 600000004bfffce1
e801001038210060 e801001038210060
4e8000207c0803a6 4e8000207c0803a6
0100000000000000 0100000000000000
3c4c000100000080 3c4c000100000080
7c0802a638429264 7c0802a6384292b4
6129000c3d204000 6129000c3d204000
3fc0aaaa48000f91 3fc0aaaa48000ffd
f821ff713f804000 f821ff713f804000
63deaaaa3fa04000 63deaaaa3fa04000
639c00043fe04000 639c00043fe04000
93df000063bd0008 93df000063bd0008
93dd000093dc0000 93dd000093dc0000
4bfffd9993c90000 4bfffce993c90000
813f000060000000 813f000060000000
7d29f278815c0000 7d29f278815c0000
7d2900347f8af000 7d2900347f8af000
@ -622,7 +644,7 @@ f821ff713f804000
93dd000093dc0000 93dd000093dc0000
3d20400093c90000 3d20400093c90000
93c900006129000c 93c900006129000c
600000004bfffcfd 600000004bfffc4d
7f89f000813c0000 7f89f000813c0000
3bff0001419e000c 3bff0001419e000c
813d00007fff07b4 813d00007fff07b4
@ -638,7 +660,7 @@ f821ff713f804000
3bff0001419e0028 3bff0001419e0028
3c62ffff7fff07b4 3c62ffff7fff07b4
7fe4fb7838a00100 7fe4fb7838a00100
4bfffc0538637ef0 4bfffb5538637f70
4800000c60000000 4800000c60000000
409effe02fbf0000 409effe02fbf0000
3ce0802039000004 3ce0802039000004
@ -648,7 +670,7 @@ f821ff713f804000
7d2900d0792907e0 7d2900d0792907e0
7d293838394a0004 7d293838394a0004
912afffc7d294278 912afffc7d294278
4bfffc294200ffe4 4bfffb794200ffe4
3900000460000000 3900000460000000
7d0903a63ce08020 7d0903a63ce08020
3d40400060e70003 3d40400060e70003
@ -662,7 +684,7 @@ f821ff713f804000
2fbe00004200ffd4 2fbe00004200ffd4
3c62ffff419e001c 3c62ffff419e001c
7fc4f37838a00004 7fc4f37838a00004
4bfffb4538637f18 4bfffa9538637f98
3d20400060000000 3d20400060000000
6129000839400000 6129000839400000
914900003ba00000 914900003ba00000
@ -672,7 +694,7 @@ f821ff713f804000
9149000061290010 9149000061290010
394000033d204000 394000033d204000
9149000061290014 9149000061290014
600000004bfffb6d 600000004bfffabd
3940000039200004 3940000039200004
3d2a10007d2903a6 3d2a10007d2903a6
8129000879291764 8129000879291764
@ -682,12 +704,12 @@ f821ff713f804000
2fbd00004200ffdc 2fbd00004200ffdc
3c62ffff419e001c 3c62ffff419e001c
7fa4eb7838a00004 7fa4eb7838a00004
4bfffaa538637f40 4bfff9f538637fc0
7ffefa1460000000 7ffefa1460000000
7fffea143bc00000 7fffea143bc00000
409e00a42f9f0000 409e00a42f9f0000
38637f683c62ffff 38637fe83c62ffff
600000004bfffa81 600000004bfff9d1
3f8040007f5602a6 3f8040007f5602a6
639c00043f604000 639c00043f604000
3fa0400039200001 3fa0400039200001
@ -696,7 +718,7 @@ f821ff713f804000
63de000c39200002 63de000c39200002
39200003913d0000 39200003913d0000
7ff602a6913e0000 7ff602a6913e0000
600000004bfffaad 600000004bfff9fd
815b00007d3602a6 815b00007d3602a6
815d0000815c0000 815d0000815c0000
7cb602a6815e0000 7cb602a6815e0000
@ -704,17 +726,17 @@ f821ff713f804000
7ca42b967d3fd050 7ca42b967d3fd050
3c62ffff7c844b96 3c62ffff7c844b96
788404a078a504a0 788404a078a504a0
3bc0000138637f78 3bc0000138637ff8
600000004bfff9f1 600000004bfff941
7fc3f37838210090 7fc3f37838210090
0000000048000c68 0000000048000cd4
0000068001000000 0000068001000000
38428ec83c4c0001 38428f183c4c0001
3c62ffff7c0802a6 600000007c0802a6
48000bf538637fd0 48000c6138628050
3f60c010f821ff71 3f60c010f821ff71
637b10003be00000 637b10003be00000
4bfff9a57b7b0020 4bfff8f57b7b0020
7c0004ac60000000 7c0004ac60000000
3f40c0107fe0df2a 3f40c0107fe0df2a
7b5a0020635a1008 7b5a0020635a1008
@ -753,38 +775,38 @@ f821ff713f804000
4082001c2c230000 4082001c2c230000
7f80df2a7c0004ac 7f80df2a7c0004ac
7f80d72a7c0004ac 7f80d72a7c0004ac
48000af438210090 48000b6038210090
7f80df2a7c0004ac 7f80df2a7c0004ac
4bffffec38600001 4bffffec38600001
0100000000000000 0100000000000000
3c4c000100000680 3c4c000100000680
3d20c00038428d44 3d20c00038428d94
6129200060000000 6129200060000000
f922803879290020 f92280b879290020
612900203d20c000 612900203d20c000
7c0004ac79290020 7c0004ac79290020
3d40001c7d204eea 3d40001c7d204eea
7d295392614a2000 7d295392614a2000
394a0018e9428038 394a0018e94280b8
7c0004ac3929ffff 7c0004ac3929ffff
4e8000207d2057ea 4e8000207d2057ea
0000000000000000 0000000000000000
3c4c000100000000 3c4c000100000000
6000000038428ce4 6000000038428d34
39290010e9228038 39290010e92280b8
7d204eea7c0004ac 7d204eea7c0004ac
4082ffe871290008 4082ffe871290008
e94280385469063e e94280b85469063e
7d2057ea7c0004ac 7d2057ea7c0004ac
000000004e800020 000000004e800020
0000000000000000 0000000000000000
38428ca03c4c0001 38428cf03c4c0001
fbc1fff07c0802a6 fbc1fff07c0802a6
3bc3fffffbe1fff8 3bc3fffffbe1fff8
f821ffd1f8010010 f821ffd1f8010010
2fbf00008ffe0001 2fbf00008ffe0001
38210030409e0010 38210030409e0010
48000a2038600000 48000a8c38600000
409e000c2b9f000a 409e000c2b9f000a
4bffff813860000d 4bffff813860000d
4bffff797fe3fb78 4bffff797fe3fb78
@ -834,283 +856,297 @@ f924000039290002
392900014e800020 392900014e800020
000000004bffffe8 000000004bffffe8
0000000000000000 0000000000000000
2b8900193923ff9f 3900000078aae8c2
3863ffe04d9d0020 7d2903a6392a0001
4e8000207c6307b4 78a9e8c242000030
1d29fff8792a1f24
7c8452147d035214
392000007ca92a14
7d4903a639450001
4e80002042000018
7d23412a7d24402a
4bffffc439080008
7d4849ae7d4448ae
4bffffdc39290001
0000000000000000
3923ff9f00000000
4d9d00202b890019
7c6307b43863ffe0
000000004e800020
0000000000000000 0000000000000000
3c4c000100000000 38428aa03c4c0001
7c0802a638428abc 3d2037367c0802a6
7d9080263d203736 612935347d908026
792907c661293534 65293332792907c6
9181000865293332 6129313091810008
480007d961293130 f821ffa1480007d9
7c7d1b78f821ffa1 7cde33787c7d1b78
3be000007cde3378 f92100203be00000
3d206665f9210020 612964633d206665
792907c661296463 65296261792907c6
6129393865296261 f921002861293938
7ca92b78f9210028 2fa900007ca92b78
409e00802fa90000 2fbf0000409e0080
409e00082fbf0000 3be00001409e0008
7fbf20403be00001 386000007fbf2040
419d005838600000 2e270000419d0058
3b9fffff2e270000 7f65f3923b9fffff
7d3bf1d27f65f392 7ca928507d3bf1d2
7ca12a147ca92850 886500207ca12a14
4192001088650020 4bffff4141920010
600000004bffff41 5463063e60000000
2fbb00005463063e e93d00002fbb0000
7f65db78e93d0000 7c69e1ae7f65db78
3b9cffff7c69e1ae 409effc83b9cffff
e93d0000409effc8 38600001e93d0000
7fe9fa1438600001 fbfd00007fe9fa14
38210060fbfd0000 8181000838210060
7d90812081810008 480007747d908120
2b9e001048000774 409e00142b9e0010
7929e102409e0014 3bff00017929e102
7fff07b43bff0001 4bffff687fff07b4
7d29f3924bffff68 4bfffff07d29f392
000000004bfffff0 0300000000000000
0000058003000000 3c4c000100000580
384289b03c4c0001 7c0802a638428994
480006e97c0802a6 f821ffb1480006e9
eb630000f821ffb1 7c7f1b78eb630000
7c9c23787c7f1b78 7cbd2b787c9c2378
3bc000007cbd2b78 7fa3eb783bc00000
4bfffe797fa3eb78 600000004bfffe0d
7fa3f04060000000 409d00147fa3f040
e95f0000409d0014 7d3b5050e95f0000
7fa9e0407d3b5050 419c00107fa9e040
38210050419c0010 3860000138210050
480006f038600001 7d3df0ae480006f0
3bde00017d3df0ae 992a00003bde0001
e93f0000992a0000 39290001e93f0000
f93f000039290001 4bffffb8f93f0000
000000004bffffb8
0000058001000000
384289303c4c0001
480006617c0802a6
7c7d1b78f821ffa1
7ca32b787c9b2378
38a0000a38800000
eb5d00007cde3378
7d1943787cfc3b78
4bfffcb57d3f4b78
3940000060000000
2fbe00007c6307b4
2faa0000409e006c
39400001409e0008
7f8348007d3f5214
409d00447d2a07b4
2f8300007c6a1850
3929000178690020
3d408000419c0010
409e00087f835000
2c29000139200001
418200143929ffff
7d5a3850e8fd0000
419c00307faad840
3860000038210060
2b9c001048000604
7bdee102409e0014
7d4a07b4394a0001
7fdee3924bffff7c
9b2700004bfffff0
394a0001e95d0000
4bffffa8f95d0000
0100000000000000 0100000000000000
3c4c000100000780 3c4c000100000580
7c0802a638428834 7c0802a638428914
f821fed148000539 f821ffa148000661
f86100607c741b79 7c9b23787c7d1b78
4182006838600000 388000007ca32b78
419e00602fa40000 7cde337838a0000a
3e42ffff39210040 7cfc3b78eb5d0000
3b4100203ac4ffff 7d3f4b787d194378
60000000f9210070 600000004bfffc49
392280303ae00000 7c6307b439400000
3ba100603a527fe8 409e006c2fbe0000
89250000f9210078 409e00082faa0000
2fa90000ebc10060 7d3f521439400001
7ff4f050419e0010 7d2a07b47f834800
419c00207fbfb040 7c6a1850409d0044
993e000039200000 786900202f830000
7e941850e8610060 419c001039290001
382101307e8307b4 7f8350003d408000
2b89002548000508 39200001409e0008
409e048839450001 3929ffff2c290001
8925000038e00000 e8fd000041820014
f8a10068e9010070 7faad8407d5a3850
7d2741ae7cea07b4 38210060419c0030
8d25000139070001 4800060438600000
2b8900647d0807b4 409e00142b9c0010
2b890069419e0058 394a00017bdee102
2b890075419e0050 4bffff7c7d4a07b4
2b890078419e0048 4bfffff07fdee392
2b890058419e0040 e95d00009b270000
2b890070419e0038 f95d0000394a0001
2b890063419e0030 000000004bffffa8
2b890073419e0028 0000078001000000
2b890025419e0020 384288183c4c0001
2b89004f419e0018 480005397c0802a6
2b89006f419e0010 7c741b79f821fed1
409eff8838e70001 38600000f8610060
2b890025394a0002 2fa4000041820068
7d1a42147d4a07b4 39210040419e0060
992800207d5a5214 3ac4ffff60000000
409e00209aea0020 f92100703b410020
f9210060393e0001 3ae0000060000000
993e000039200025 3a428068392280b0
38a90002e9210068 f92100783ba10060
892100414bffff04 ebc1006089250000
3a2600087fffb050
3a600030eb660000
3929ffd23b010042
4082039c712900fd
3b2000043aa00000
3a0000013b800000
7ddb00d039e0002d
2b89006c48000108
88f8000138d80001
419d0118419e033c
419e02402b890063
2b89004f419d0038
2b890058419e01e8
3949ffd0419e0188
2b8a0009554a063e
395c0001419d00c4
993c00207f81e214
480000b0795c0020
419e03042b890068
419e000c2b890069
409effc82b890064
7d41e2142b890075
7f6adb789aea0020
57291838419e0034
7e0948363929ffff
418200207f694839
e921006099e80000
f921006039290001
7d52482a7b291f24
e88100607dca5038
38e0000a7d465378
7f45d378f9410080
7e689b7839200000
7c9e20507fa3eb78
4bfffc9d7c84f850
e9410080e8810060
38c0000a7ea7ab78
7d4553787c9e2050
7fa3eb787c84f850
3b1800014bfffaed
e901006089380000
419e00102fa90000 419e00102fa90000
7fbf50407d5e4050 7fbfb0407ff4f050
7e268b78419dfee4 39200000419c0020
2b8900734bfffe90 e8610060993e0000
419d006c419e016c 7e8307b47e941850
419e00d42b89006f 4800050838210130
409efef02b890070 394500012b890025
38e000107d21e214 38e00000409e0488
7c8af8507f66db78 e901007089250000
390000209ae90020 7cea07b4f8a10068
7f45d37839200002 390700017d2741ae
4bfffc0d7fa3eb78 7d0807b48d250001
e8a10078e8810060 419e00582b890064
7c9e20507fa3eb78 419e00502b890069
4bfffb757c84f850 419e00482b890075
7ea7ab78e8810060 419e00402b890078
7f65db7838c00010 419e00382b890058
4bffff5c7c9e2050 419e00302b890070
419e00182b890078 419e00282b890063
419e01cc2b89007a 419e00202b890073
4bfffeb82b890075 419e00182b890025
7d21e2143aa00001 419e00102b89004f
7c8af85038e00010 38e700012b89006f
9ae900207e689b78 394a0002409eff88
7f45d3787b291f24 7d4a07b42b890025
7d72482a7fa3eb78 7d5a52147d1a4214
7f6b583839200000 9aea002099280020
f96100807d665b78 393e0001409e0020
e88100604bfffb89 39200025f9210060
e9210068993e0000
4bffff0438a90002
7fffb05089210041
eb6600003a260008
3b0100423a600030
712900fd3929ffd2
3aa000004082039c
3b8000003b200004
39e0002d3a000001
480001087ddb00d0
38d800012b89006c
419e033c88f80001
2b890063419d0118
419d0038419e0240
419e01e82b89004f
419e01882b890058
554a063e3949ffd0
419d00c42b8a0009
7f81e214395c0001
795c0020993c0020
2b890068480000b0
2b890069419e0304
2b890064419e000c
2b890075409effc8
9aea00207d41e214
419e00347f6adb78
3929ffff57291838
7f6948397e094836
99e8000041820020
39290001e9210060
7b291f24f9210060
7dca50387d52482a
7d465378e8810060
f941008038e0000a
392000007f45d378
7fa3eb787e689b78
7c84f8507c9e2050
e88100604bfffc9d
7ea7ab78e9410080
7c9e205038c0000a
7c84f8507d455378
4bfffaed7fa3eb78
893800003b180001
2fa90000e9010060
7d5e4050419e0010
419dfee47fbf5040
4bfffe907e268b78
419e016c2b890073
2b89006f419d006c
2b890070419e00d4
7d21e214409efef0
7f66db7838e00010
9ae900207c8af850
3920000239000020
7fa3eb787f45d378
e88100604bfffc0d
7fa3eb78e8a10078
7c84f8507c9e2050
e88100604bfffb75
38c000107ea7ab78 38c000107ea7ab78
e96100807c9e2050 7c9e20507f65db78
4bfffeec7d655b78 2b8900784bffff5c
38e000087d21e214 2b89007a419e0018
2b890075419e01cc
3aa000014bfffeb8
38e000107d21e214
7e689b787c8af850 7e689b787c8af850
7b291f249ae90020 7b291f249ae90020
7fa3eb787f45d378 7fa3eb787f45d378
392000007d72482a 392000007d72482a
7d665b787f6b5838 7d665b787f6b5838
4bfffb35f9610080 4bfffb89f9610080
7ea7ab78e8810060 7ea7ab78e8810060
7c9e205038c00008 7c9e205038c00010
7d21e2144bffffac 7d655b78e9610080
38e0000a39000020 7d21e2144bfffeec
9ae9002038c00001 7c8af85038e00008
392000007f45d378 9ae900207e689b78
7fa3eb787c8af850 7f45d3787b291f24
e92100604bfffaf9 7d72482a7fa3eb78
e92100609b690000 7f6b583839200000
f921006039290001 f96100807d665b78
7d21e2144bfffe6c e88100604bfffb35
f901009038a0000a 38c000087ea7ab78
38800000f9410088 4bffffac7c9e2050
9ae900207f43d378 390000207d21e214
600000004bfff7a9 38c0000138e0000a
7f63db78f8610080 7f45d3789ae90020
600000004bfff8cd 7c8af85039200000
7fa91840e9210080 4bfffaf97fa3eb78
7c634850409d0040 9b690000e9210060
e9010090e9410088 39290001e9210060
392300012fa30000 4bfffe6cf9210060
409e00087d4af850 38a0000a7d21e214
2c29000139200001 f9410088f9010090
3929ffffe8c10060 7f43d37838800000
7ce8305041820010 4bfff73d9ae90020
419d00207faa3840 f861008060000000
7f65db78e8810060 4bfff8617f63db78
7c9e20507fa3eb78 e921008060000000
4bfff9cd7c84f850 409d00407fa91840
38e000204bfffdd4 e94100887c634850
e8e1006098e60000 2fa30000e9010090
f8e1006038e70001 7d4af85039230001
2b87006c4bffffb4 39200001409e0008
409efdb03b200008 e8c100602c290001
4bfffda87cd83378 418200103929ffff
3b2000022b870068 7faa38407ce83050
7cd83378409efd9c e8810060419d0020
4bfffd903b200001 7fa3eb787f65db78
4bfffd883b200008 7c84f8507c9e2050
3b0100413a600020 4bfffdd44bfff9cd
993e00004bfffc60 98e6000038e00020
e92100607d455378 38e70001e8e10060
f921006039290001 4bffffb4f8e10060
000000004bfffb24 3b2000082b87006c
0000128001000000 7cd83378409efdb0
f9e1ff78f9c1ff70 2b8700684bfffda8
fa21ff88fa01ff80 409efd9c3b200002
fa61ff98fa41ff90 3b2000017cd83378
faa1ffa8fa81ffa0 3b2000084bfffd90
fae1ffb8fac1ffb0 3a6000204bfffd88
fb21ffc8fb01ffc0 4bfffc603b010041
fb61ffd8fb41ffd0 7d455378993e0000
fba1ffe8fb81ffe0 39290001e9210060
fbe1fff8fbc1fff0 4bfffb24f9210060
4e800020f8010010 0100000000000000
e9e1ff78e9c1ff70 f9c1ff7000001280
ea21ff88ea01ff80 fa01ff80f9e1ff78
ea61ff98ea41ff90 fa41ff90fa21ff88
eaa1ffa8ea81ffa0 fa81ffa0fa61ff98
eae1ffb8eac1ffb0 fac1ffb0faa1ffa8
eb21ffc8eb01ffc0 fb01ffc0fae1ffb8
eb61ffd8eb41ffd0 fb41ffd0fb21ffc8
e8010010eb81ffe0 fb81ffe0fb61ffd8
7c0803a6eba1ffe8 fbc1fff0fba1ffe8
ebe1fff8ebc1fff0 f8010010fbe1fff8
ebc1fff04e800020 e9c1ff704e800020
ebe1fff8e8010010 ea01ff80e9e1ff78
4e8000207c0803a6 ea41ff90ea21ff88
ea81ffa0ea61ff98
eac1ffb0eaa1ffa8
eb01ffc0eae1ffb8
eb41ffd0eb21ffc8
eb81ffe0eb61ffd8
eba1ffe8e8010010
ebc1fff07c0803a6
4e800020ebe1fff8
e8010010ebc1fff0
7c0803a6ebe1fff8
000000004e800020
6d6f636c65570a0a 6d6f636c65570a0a
63694d206f742065 63694d206f742065
2120747461776f72 2120747461776f72
@ -1124,6 +1160,7 @@ ebe1fff8e8010010
0000000000000000 0000000000000000
0000002054524155 0000002054524155
000000204d415244 000000204d415244
000000204d415242
2020202020202020 2020202020202020
203a4d4152422020 203a4d4152422020
0a424b20646c6c25 0a424b20646c6c25
@ -1132,6 +1169,10 @@ ebe1fff8e8010010
203a4d4152442020 203a4d4152442020
0a424d20646c6c25 0a424d20646c6c25
0000000000000000 0000000000000000
4152442020202020
203a54494e49204d
0a424b20646c6c25
0000000000000000
2020202020202020 2020202020202020
203a4b4c43202020 203a4b4c43202020
7a484d20646c6c25 7a484d20646c6c25
@ -1148,6 +1189,13 @@ ebe1fff8e8010010
20676e69746f6f42 20676e69746f6f42
415242206d6f7266 415242206d6f7266
0000000a2e2e2e4d 0000000a2e2e2e4d
20676e6979706f43
2064616f6c796170
2e4d415244206f74
00000000000a2e2e
20676e69746f6f42
415244206d6f7266
0000000a2e2e2e4d
20747365746d654d 20747365746d654d
6c69616620737562 6c69616620737562
252f6425203a6465 252f6425203a6465

@ -1,5 +1,5 @@
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
// Auto-generated by Migen (0d16e03) & LiteX (564d731a) on 2020-05-22 17:57:20 // Auto-generated by Migen (0d16e03) & LiteX (564d731a) on 2020-05-26 20:37:42
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
module litedram_core( module litedram_core(
input wire clk, input wire clk,

@ -130,6 +130,7 @@ targets:
- ram_init_file - ram_init_file
- use_litedram=true - use_litedram=true
- disable_flatten_core - disable_flatten_core
- no_bram
generate: [dram_nexys_video] generate: [dram_nexys_video]
tools: tools:
vivado: {part : xc7a200tsbg484-1} vivado: {part : xc7a200tsbg484-1}
@ -156,6 +157,7 @@ targets:
- ram_init_file - ram_init_file
- use_litedram=true - use_litedram=true
- disable_flatten_core - disable_flatten_core
- no_bram
generate: [dram_arty] generate: [dram_arty]
tools: tools:
vivado: {part : xc7a35ticsg324-1L} vivado: {part : xc7a35ticsg324-1L}
@ -182,6 +184,7 @@ targets:
- ram_init_file - ram_init_file
- use_litedram=true - use_litedram=true
- disable_flatten_core - disable_flatten_core
- no_bram
generate: [dram_arty] generate: [dram_arty]
tools: tools:
vivado: {part : xc7a100ticsg324-1L} vivado: {part : xc7a100ticsg324-1L}
@ -219,7 +222,7 @@ generate:
parameters: parameters:
memory_size: memory_size:
datatype : int datatype : int
description : On-chip memory size (bytes) description : On-chip memory size (bytes). If no_bram is set, this is the size carved out for the DRAM payload
paramtype : generic paramtype : generic
default : 16384 default : 16384


@ -256,3 +259,9 @@ parameters:
description : Use liteDRAM description : Use liteDRAM
paramtype : generic paramtype : generic
default : false default : false

no_bram:
datatype : bool
description : No internal block RAM (only DRAM and init code carrying payload)
paramtype : generic
default : false

@ -26,14 +26,15 @@ use work.wishbone_types.all;


entity soc is entity soc is
generic ( generic (
MEMORY_SIZE : positive; MEMORY_SIZE : natural;
RAM_INIT_FILE : string; RAM_INIT_FILE : string;
RESET_LOW : boolean; RESET_LOW : boolean;
CLK_FREQ : positive; CLK_FREQ : positive;
SIM : boolean; SIM : boolean;
DISABLE_FLATTEN_CORE : boolean := false; DISABLE_FLATTEN_CORE : boolean := false;
HAS_DRAM : boolean := false; HAS_DRAM : boolean := false;
DRAM_SIZE : integer := 0 DRAM_SIZE : integer := 0;
DRAM_INIT_SIZE : integer := 0
); );
port( port(
rst : in std_ulogic; rst : in std_ulogic;
@ -105,7 +106,6 @@ architecture behaviour of soc is
-- Main memory signals: -- Main memory signals:
signal wb_bram_in : wishbone_master_out; signal wb_bram_in : wishbone_master_out;
signal wb_bram_out : wishbone_slave_out; signal wb_bram_out : wishbone_slave_out;
constant mem_adr_bits : positive := positive(ceil(log2(real(MEMORY_SIZE))));


-- DMI debug bus signals -- DMI debug bus signals
signal dmi_addr : std_ulogic_vector(7 downto 0); signal dmi_addr : std_ulogic_vector(7 downto 0);
@ -466,6 +466,7 @@ begin
HAS_DRAM => HAS_DRAM, HAS_DRAM => HAS_DRAM,
BRAM_SIZE => MEMORY_SIZE, BRAM_SIZE => MEMORY_SIZE,
DRAM_SIZE => DRAM_SIZE, DRAM_SIZE => DRAM_SIZE,
DRAM_INIT_SIZE => DRAM_INIT_SIZE,
CLK_FREQ => CLK_FREQ CLK_FREQ => CLK_FREQ
) )
port map( port map(
@ -516,17 +517,25 @@ begin
); );


-- BRAM Memory slave -- BRAM Memory slave
bram0: entity work.wishbone_bram_wrapper bram: if MEMORY_SIZE /= 0 generate
generic map( bram0: entity work.wishbone_bram_wrapper
MEMORY_SIZE => MEMORY_SIZE, generic map(
RAM_INIT_FILE => RAM_INIT_FILE MEMORY_SIZE => MEMORY_SIZE,
) RAM_INIT_FILE => RAM_INIT_FILE
port map( )
clk => system_clk, port map(
rst => rst_bram, clk => system_clk,
wishbone_in => wb_bram_in, rst => rst_bram,
wishbone_out => wb_bram_out wishbone_in => wb_bram_in,
); wishbone_out => wb_bram_out
);
end generate;

no_bram: if MEMORY_SIZE = 0 generate
wb_bram_out.ack <= wb_bram_in.cyc and wb_bram_in.stb;
wb_bram_out.dat <= x"FFFFFFFFFFFFFFFF";
wb_bram_out.stall <= wb_bram_in.cyc and not wb_bram_out.ack;
end generate;


-- DMI(debug bus) <-> JTAG bridge -- DMI(debug bus) <-> JTAG bridge
dtm: entity work.dmi_dtm dtm: entity work.dmi_dtm

@ -8,12 +8,13 @@ use work.wishbone_types.all;


entity syscon is entity syscon is
generic ( generic (
SIG_VALUE : std_ulogic_vector(63 downto 0) := x"f00daa5500010001"; SIG_VALUE : std_ulogic_vector(63 downto 0) := x"f00daa5500010001";
CLK_FREQ : integer; CLK_FREQ : integer;
HAS_UART : boolean; HAS_UART : boolean;
HAS_DRAM : boolean; HAS_DRAM : boolean;
BRAM_SIZE : integer; BRAM_SIZE : integer;
DRAM_SIZE : integer DRAM_SIZE : integer;
DRAM_INIT_SIZE : integer
); );
port ( port (
clk : in std_ulogic; clk : in std_ulogic;
@ -36,12 +37,13 @@ architecture behaviour of syscon is
constant SYS_REG_BITS : positive := 3; constant SYS_REG_BITS : positive := 3;


-- Register addresses (matches wishbone addr downto 3, ie, 8 bytes per reg) -- Register addresses (matches wishbone addr downto 3, ie, 8 bytes per reg)
constant SYS_REG_SIG : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000"; constant SYS_REG_SIG : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000";
constant SYS_REG_INFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "001"; constant SYS_REG_INFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "001";
constant SYS_REG_BRAMINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "010"; constant SYS_REG_BRAMINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "010";
constant SYS_REG_DRAMINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "011"; constant SYS_REG_DRAMINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "011";
constant SYS_REG_CLKINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "100"; constant SYS_REG_CLKINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "100";
constant SYS_REG_CTRL : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "101"; constant SYS_REG_CTRL : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "101";
constant SYS_REG_DRAMINITINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "110";


-- Muxed reg read signal -- Muxed reg read signal
signal reg_out : std_ulogic_vector(63 downto 0); signal reg_out : std_ulogic_vector(63 downto 0);
@ -49,6 +51,7 @@ architecture behaviour of syscon is
-- INFO register bits -- INFO register bits
constant SYS_REG_INFO_HAS_UART : integer := 0; constant SYS_REG_INFO_HAS_UART : integer := 0;
constant SYS_REG_INFO_HAS_DRAM : integer := 1; constant SYS_REG_INFO_HAS_DRAM : integer := 1;
constant SYS_REG_INFO_HAS_BRAM : integer := 2;


-- BRAMINFO contains the BRAM size in the bottom 52 bits -- BRAMINFO contains the BRAM size in the bottom 52 bits
-- DRAMINFO contains the DRAM size if any in the bottom 52 bits -- DRAMINFO contains the DRAM size if any in the bottom 52 bits
@ -69,14 +72,16 @@ architecture behaviour of syscon is
signal reg_info : std_ulogic_vector(63 downto 0); signal reg_info : std_ulogic_vector(63 downto 0);
signal reg_braminfo : std_ulogic_vector(63 downto 0); signal reg_braminfo : std_ulogic_vector(63 downto 0);
signal reg_draminfo : std_ulogic_vector(63 downto 0); signal reg_draminfo : std_ulogic_vector(63 downto 0);
signal reg_dramiinfo : std_ulogic_vector(63 downto 0);
signal reg_clkinfo : std_ulogic_vector(63 downto 0); signal reg_clkinfo : std_ulogic_vector(63 downto 0);
signal info_has_dram : std_ulogic; signal info_has_dram : std_ulogic;
signal info_has_bram : std_ulogic;
signal info_has_uart : std_ulogic; signal info_has_uart : std_ulogic;
signal info_clk : std_ulogic_vector(39 downto 0); signal info_clk : std_ulogic_vector(39 downto 0);
begin begin


-- Generated output signals -- Generated output signals
dram_at_0 <= reg_ctrl(SYS_REG_CTRL_DRAM_AT_0); dram_at_0 <= '1' when BRAM_SIZE = 0 else reg_ctrl(SYS_REG_CTRL_DRAM_AT_0);
soc_reset <= reg_ctrl(SYS_REG_CTRL_SOC_RESET); soc_reset <= reg_ctrl(SYS_REG_CTRL_SOC_RESET);
core_reset <= reg_ctrl(SYS_REG_CTRL_CORE_RESET); core_reset <= reg_ctrl(SYS_REG_CTRL_CORE_RESET);


@ -87,13 +92,17 @@ begin
-- Info register is hard wired -- Info register is hard wired
info_has_uart <= '1' when HAS_UART else '0'; info_has_uart <= '1' when HAS_UART else '0';
info_has_dram <= '1' when HAS_DRAM else '0'; info_has_dram <= '1' when HAS_DRAM else '0';
info_has_bram <= '1' when BRAM_SIZE /= 0 else '0';
info_clk <= std_ulogic_vector(to_unsigned(CLK_FREQ, 40)); info_clk <= std_ulogic_vector(to_unsigned(CLK_FREQ, 40));
reg_info <= (0 => info_has_uart, reg_info <= (0 => info_has_uart,
1 => info_has_dram, 1 => info_has_dram,
2 => info_has_bram,
others => '0'); others => '0');
reg_braminfo <= x"000" & std_ulogic_vector(to_unsigned(BRAM_SIZE, 52)); reg_braminfo <= x"000" & std_ulogic_vector(to_unsigned(BRAM_SIZE, 52));
reg_draminfo <= x"000" & std_ulogic_vector(to_unsigned(DRAM_SIZE, 52)) when HAS_DRAM reg_draminfo <= x"000" & std_ulogic_vector(to_unsigned(DRAM_SIZE, 52)) when HAS_DRAM
else (others => '0'); else (others => '0');
reg_dramiinfo <= x"000" & std_ulogic_vector(to_unsigned(DRAM_INIT_SIZE, 52)) when HAS_DRAM
else (others => '0');
reg_clkinfo <= (39 downto 0 => info_clk, reg_clkinfo <= (39 downto 0 => info_clk,
others => '0'); others => '0');


@ -107,6 +116,7 @@ begin
reg_info when SYS_REG_INFO, reg_info when SYS_REG_INFO,
reg_braminfo when SYS_REG_BRAMINFO, reg_braminfo when SYS_REG_BRAMINFO,
reg_draminfo when SYS_REG_DRAMINFO, reg_draminfo when SYS_REG_DRAMINFO,
reg_dramiinfo when SYS_REG_DRAMINITINFO,
reg_clkinfo when SYS_REG_CLKINFO, reg_clkinfo when SYS_REG_CLKINFO,
reg_ctrl_out when SYS_REG_CTRL, reg_ctrl_out when SYS_REG_CTRL,
(others => '0') when others; (others => '0') when others;
@ -136,6 +146,11 @@ begin
if reg_ctrl(SYS_REG_CTRL_CORE_RESET) = '1' then if reg_ctrl(SYS_REG_CTRL_CORE_RESET) = '1' then
reg_ctrl(SYS_REG_CTRL_CORE_RESET) <= '0'; reg_ctrl(SYS_REG_CTRL_CORE_RESET) <= '0';
end if; end if;

-- If BRAM doesn't exist, force DRAM at 0
if BRAM_SIZE = 0 then
reg_ctrl(SYS_REG_CTRL_DRAM_AT_0) <= '1';
end if;
end if; end if;
end if; end if;
end process; end process;

@ -7,7 +7,7 @@ package utils is
function log2(i : natural) return integer; function log2(i : natural) return integer;
function log2ceil(i : natural) return integer; function log2ceil(i : natural) return integer;
function ispow2(i : integer) return boolean; function ispow2(i : integer) return boolean;

function round_up(i : integer; s : integer) return integer;
end utils; end utils;


package body utils is package body utils is
@ -43,5 +43,9 @@ package body utils is
end if; end if;
end function; end function;


function round_up(i : integer; s : integer) return integer is
begin
return ((i + (s - 1)) / s) * s;
end function;
end utils; end utils;



Loading…
Cancel
Save