Merge pull request #177 from antonblanchard/litedram

LiteDRAM fixes from Ben
jtag-port
Anton Blanchard 4 years ago committed by GitHub
commit 6d36ef93d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -164,11 +164,13 @@ _clean:

clean: _clean
make -f scripts/mw_debug/Makefile clean
make -f hello_world/Makefile clean

distclean: _clean
rm -f *~ fpga/~
rm -f *~ fpga/*~ lib/*~ console/*~ include/*~
rm -rf litedram/build
rm -f litedram/extras/*~
rm -f litedram/gen-src/*~
rm -f litedram/gen-src/sdram_init/*~
make -f scripts/mw_debug/Makefile distclean
make -f hello_world/Makefile distclean

@ -97,7 +97,19 @@ architecture behave of core is
signal complete: std_ulogic;
signal terminate: std_ulogic;
signal core_rst: std_ulogic;
signal icache_rst: std_ulogic;
signal icache_inv: std_ulogic;

-- Delayed/Latched resets and alt_reset
signal rst_fetch1 : std_ulogic := '1';
signal rst_fetch2 : std_ulogic := '1';
signal rst_icache : std_ulogic := '1';
signal rst_dcache : std_ulogic := '1';
signal rst_dec1 : std_ulogic := '1';
signal rst_dec2 : std_ulogic := '1';
signal rst_ex1 : std_ulogic := '1';
signal rst_ls1 : std_ulogic := '1';
signal rst_dbg : std_ulogic := '1';
signal alt_reset_d : std_ulogic;

signal sim_cr_dump: std_ulogic;

@ -142,6 +154,22 @@ begin

core_rst <= dbg_core_rst or rst;

resets: process(clk)
begin
if rising_edge(clk) then
rst_fetch1 <= core_rst;
rst_fetch2 <= core_rst;
rst_icache <= core_rst or dbg_icache_rst or ex1_icache_inval;
rst_dcache <= core_rst;
rst_dec1 <= core_rst;
rst_dec2 <= core_rst;
rst_ex1 <= core_rst;
rst_ls1 <= core_rst;
rst_dbg <= rst;
alt_reset_d <= alt_reset;
end if;
end process;

fetch1_0: entity work.fetch1
generic map (
RESET_ADDRESS => (others => '0'),
@ -149,8 +177,8 @@ begin
)
port map (
clk => clk,
rst => core_rst,
alt_reset_in => alt_reset,
rst => rst_fetch1,
alt_reset_in => alt_reset_d,
stall_in => fetch1_stall_in,
flush_in => flush,
stop_in => dbg_core_stop,
@ -169,7 +197,7 @@ begin
)
port map(
clk => clk,
rst => icache_rst,
rst => rst_icache,
i_in => fetch1_to_icache,
i_out => icache_to_fetch2,
m_in => mmu_to_icache,
@ -179,12 +207,10 @@ begin
wishbone_in => wishbone_insn_in
);

icache_rst <= rst or dbg_icache_rst or ex1_icache_inval;

fetch2_0: entity work.fetch2
port map (
clk => clk,
rst => core_rst,
rst => rst_fetch2,
stall_in => fetch2_stall_in,
flush_in => flush,
i_in => icache_to_fetch2,
@ -196,7 +222,7 @@ begin
decode1_0: entity work.decode1
port map (
clk => clk,
rst => core_rst,
rst => rst_dec1,
stall_in => decode1_stall_in,
flush_in => flush,
f_in => fetch2_to_decode1,
@ -211,7 +237,7 @@ begin
)
port map (
clk => clk,
rst => core_rst,
rst => rst_dec2,
stall_in => decode2_stall_in,
stall_out => decode2_stall_out,
flush_in => flush,
@ -261,7 +287,7 @@ begin
)
port map (
clk => clk,
rst => core_rst,
rst => rst_ex1,
flush_out => flush,
stall_out => ex1_stall_out,
e_in => decode2_to_execute1,
@ -278,7 +304,7 @@ begin
loadstore1_0: entity work.loadstore1
port map (
clk => clk,
rst => core_rst,
rst => rst_ls1,
l_in => execute1_to_loadstore1,
e_out => loadstore1_to_execute1,
l_out => loadstore1_to_writeback,
@ -309,7 +335,7 @@ begin
)
port map (
clk => clk,
rst => core_rst,
rst => rst_dcache,
d_in => loadstore1_to_dcache,
d_out => dcache_to_loadstore1,
m_in => mmu_to_dcache,
@ -332,7 +358,7 @@ begin
debug_0: entity work.core_debug
port map (
clk => clk,
rst => rst,
rst => rst_dbg,
dmi_addr => dmi_addr,
dmi_din => dmi_din,
dmi_dout => dmi_dout,

@ -78,7 +78,7 @@ begin
prev_op <= FIFO_POP;
else
if push = '1' and pop = '1' then
prev_op <= FIFO_POP;
-- Keep the same value for prev_op
elsif push = '1' then
prev_op <= FIFO_PUSH;
elsif pop = '1' then

@ -111,6 +111,7 @@ architecture behaviour of pp_soc_uart is

signal rxd2 : std_logic := '1';
signal rxd3 : std_logic := '1';
signal txd2 : std_ulogic := '1';
begin

irq <= (irq_recv_enable and (not recv_buffer_empty))
@ -123,9 +124,12 @@ begin
-- Add a few FFs on the RX input to avoid metastability issues
process (clk) is
begin
rxd3 <= rxd2;
rxd2 <= rxd;
if rising_edge(clk) then
rxd3 <= rxd2;
rxd2 <= rxd;
end if;
end process;
txd <= txd2;

uart_receive: process(clk)
begin
@ -202,7 +206,7 @@ begin
begin
if rising_edge(clk) then
if reset = '1' then
txd <= '1';
txd2 <= '1';
tx_state <= IDLE;
send_buffer_pop <= '0';
tx_current_bit <= 0;
@ -210,26 +214,26 @@ begin
case tx_state is
when IDLE =>
if send_buffer_empty = '0' and uart_tx_clk = '1' then
txd <= '0';
txd2 <= '0';
send_buffer_pop <= '1';
tx_current_bit <= 0;
tx_state <= TRANSMIT;
elsif uart_tx_clk = '1' then
txd <= '1';
txd2 <= '1';
end if;
when TRANSMIT =>
if send_buffer_pop = '1' then
send_buffer_pop <= '0';
elsif uart_tx_clk = '1' and tx_current_bit = 7 then
txd <= tx_byte(tx_current_bit);
txd2 <= tx_byte(tx_current_bit);
tx_state <= STOPBIT;
elsif uart_tx_clk = '1' then
txd <= tx_byte(tx_current_bit);
txd2 <= tx_byte(tx_current_bit);
tx_current_bit <= tx_current_bit + 1;
end if;
when STOPBIT =>
if uart_tx_clk = '1' then
txd <= '1';
txd2 <= '1';
tx_state <= IDLE;
end if;
end case;

@ -1,10 +1,11 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity soc_reset is
generic (
PLL_RESET_CLOCKS : integer := 32;
SOC_RESET_CLOCKS : integer := 32;
PLL_RESET_BITS : integer := 5;
SOC_RESET_BITS : integer := 5;
RESET_LOW : boolean := true
);
port (
@ -20,26 +21,38 @@ entity soc_reset is
end soc_reset;

architecture rtl of soc_reset is
signal ext_rst_n : std_ulogic;
signal rst_n : std_ulogic;
signal pll_rst_reg : std_ulogic_vector(PLL_RESET_CLOCKS downto 0) := (others => '1');
signal soc_rst_reg : std_ulogic_vector(SOC_RESET_CLOCKS downto 0) := (others => '1');
signal ext_rst0_n : std_ulogic;
signal ext_rst1_n : std_ulogic := '0';
signal ext_rst2_n : std_ulogic := '0';
signal rst0_n : std_ulogic;
signal rst1_n : std_ulogic := '0';
signal rst2_n : std_ulogic := '0';
signal pll_rst_cnt : std_ulogic_vector(PLL_RESET_BITS downto 0) := (others => '0');
signal soc_rst_cnt : std_ulogic_vector(SOC_RESET_BITS downto 0) := (others => '0');
begin
ext_rst_n <= ext_rst_in when RESET_LOW else not ext_rst_in;
rst_n <= ext_rst_n and pll_locked_in;
ext_rst0_n <= ext_rst_in when RESET_LOW else not ext_rst_in;
rst0_n <= ext_rst0_n and pll_locked_in and not pll_rst_out;

-- PLL reset is active high
pll_rst_out <= pll_rst_reg(0);
pll_rst_out <= not pll_rst_cnt(pll_rst_cnt'left);
-- Pass active high reset around
rst_out <= soc_rst_reg(0);
rst_out <= not soc_rst_cnt(soc_rst_cnt'left);

-- Wait for external clock to become stable before starting the PLL
-- By the time the FPGA has been loaded the clock should be well and
-- truly stable, but lets give it a few cycles to be sure.
--
-- [BenH] Some designs seem to require a lot more..
pll_reset_0 : process(ext_clk)
begin
if (rising_edge(ext_clk)) then
pll_rst_reg <= '0' & pll_rst_reg(pll_rst_reg'length-1 downto 1);
ext_rst1_n <= ext_rst0_n;
ext_rst2_n <= ext_rst1_n;
if (ext_rst2_n = '0') then
pll_rst_cnt <= (others => '0');
elsif (pll_rst_cnt(pll_rst_cnt'left) = '0') then
pll_rst_cnt <= std_ulogic_vector(unsigned(pll_rst_cnt) + 1);
end if;
end if;
end process;

@ -49,10 +62,12 @@ begin
soc_reset_0 : process(pll_clk)
begin
if (rising_edge(pll_clk)) then
if (rst_n = '0') then
soc_rst_reg <= (others => '1');
else
soc_rst_reg <= '0' & soc_rst_reg(soc_rst_reg'length-1 downto 1);
rst1_n <= rst0_n;
rst2_n <= rst1_n;
if (rst2_n = '0') then
soc_rst_cnt <= (others => '0');
elsif (soc_rst_cnt(soc_rst_cnt'left) = '0') then
soc_rst_cnt <= std_ulogic_vector(unsigned(soc_rst_cnt) + 1);
end if;
end if;
end process;

@ -12,16 +12,14 @@ architecture behave of soc_reset_tb is
signal ext_rst_in : std_ulogic;

signal pll_rst_out : std_ulogic;
signal pll_rst_out_expected : std_ulogic;
signal rst_out : std_ulogic;
signal rst_out_expected : std_ulogic;

constant clk_period : time := 10 ns;

type test_vector is record
pll_locked_in : std_ulogic;
ext_rst_in : std_ulogic;
pll_rst_out : std_ulogic;
pll_rst_out : std_ulogic;
rst_out : std_ulogic;
end record;

@ -32,6 +30,8 @@ architecture behave of soc_reset_tb is
('0', '1', '1', '1'),
('0', '1', '1', '1'),
('0', '1', '1', '1'),
('0', '1', '1', '1'),
('0', '1', '1', '1'),
-- Reset is removed from the PLL
('0', '1', '0', '1'),
('0', '1', '0', '1'),
@ -41,15 +41,27 @@ architecture behave of soc_reset_tb is
('1', '1', '0', '1'),
('1', '1', '0', '1'),
('1', '1', '0', '1'),
('1', '1', '0', '1'),
('1', '1', '0', '1'),
-- Finally SOC comes out of reset
('1', '1', '0', '0'),
('1', '1', '0', '0'),

-- PLL locked, reset button pressed
('1', '0', '0', '1'),
('1', '0', '0', '1'),
('1', '0', '0', '1'),
('1', '0', '0', '0'),
('1', '0', '0', '0'),
('1', '0', '0', '0'),
('1', '0', '1', '1'),
-- PLL locked, reset button released
('1', '1', '1', '1'),
('1', '1', '1', '1'),
('1', '1', '1', '1'),
('1', '1', '1', '1'),
('1', '1', '1', '1'),
('1', '1', '1', '1'),
('1', '1', '0', '1'),
('1', '1', '0', '1'),
('1', '1', '0', '1'),
('1', '1', '0', '1'),
('1', '1', '0', '1'),
('1', '1', '0', '1'),
@ -59,8 +71,8 @@ architecture behave of soc_reset_tb is
begin
soc_reset_0: entity work.soc_reset
generic map (
PLL_RESET_CLOCKS => 4,
SOC_RESET_CLOCKS => 4,
PLL_RESET_BITS => 2,
SOC_RESET_BITS => 2,
RESET_LOW => true
)
port map (
@ -83,17 +95,29 @@ begin
end process clock;

stim: process
variable tv : test_vector;
begin
-- skew us a bit
wait for clk_period/4;

for i in test_vectors'range loop
(pll_locked_in, ext_rst_in, pll_rst_out_expected, rst_out_expected) <= test_vectors(i);
tv := test_vectors(i);

pll_locked_in <= tv.pll_locked_in;
ext_rst_in <= tv.ext_rst_in;

--report "pll_locked_in " & std_ulogic'image(pll_locked_in);
--report "ext_rst_in " & std_ulogic'image(ext_rst_in);
--report "pll_rst_out " & std_ulogic'image(pll_rst_out);
--report "rst_out" & std_ulogic'image(rst_out);
report " ** STEP " & integer'image(i);
report "pll_locked_in " & std_ulogic'image(pll_locked_in);
report "ext_rst_in " & std_ulogic'image(ext_rst_in);
report "pll_rst_out " & std_ulogic'image(pll_rst_out);
report "rst_out" & std_ulogic'image(rst_out);

assert pll_rst_out_expected = pll_rst_out report "pll_rst_out bad";
assert rst_out_expected = rst_out report "rst_out bad";
assert tv.pll_rst_out = pll_rst_out report
"pll_rst_out bad exp=" & std_ulogic'image(tv.pll_rst_out) &
" got=" & std_ulogic'image(pll_rst_out);
assert tv.rst_out = rst_out report
"rst_out bad exp=" & std_ulogic'image(tv.rst_out) &
" got=" & std_ulogic'image(rst_out);

wait for clk_period;
end loop;

@ -68,7 +68,7 @@ architecture behaviour of toplevel is
-- DRAM wishbone connection
signal wb_dram_in : wishbone_master_out;
signal wb_dram_out : wishbone_slave_out;
signal wb_dram_csr : std_ulogic;
signal wb_dram_ctrl : std_ulogic;
signal wb_dram_init : std_ulogic;

-- Control/status
@ -104,7 +104,7 @@ begin
uart0_rxd => uart_main_rx,
wb_dram_in => wb_dram_in,
wb_dram_out => wb_dram_out,
wb_dram_csr => wb_dram_csr,
wb_dram_ctrl => wb_dram_ctrl,
wb_dram_init => wb_dram_init,
alt_reset => core_alt_reset
);
@ -158,8 +158,7 @@ begin
has_dram: if USE_LITEDRAM generate
signal dram_init_done : std_ulogic;
signal dram_init_error : std_ulogic;
signal soc_rst_0 : std_ulogic;
signal soc_rst_1 : std_ulogic;
signal dram_sys_rst : std_ulogic;
begin

-- Eventually dig out the frequency from the generator
@ -168,15 +167,17 @@ begin

reset_controller: entity work.soc_reset
generic map(
RESET_LOW => RESET_LOW
RESET_LOW => RESET_LOW,
PLL_RESET_BITS => 18,
SOC_RESET_BITS => 1
)
port map(
ext_clk => ext_clk,
pll_clk => system_clk,
pll_locked_in => system_clk_locked,
pll_locked_in => '1',
ext_rst_in => ext_rst,
pll_rst_out => pll_rst,
rst_out => soc_rst_0
rst_out => open
);

dram: entity work.litedram_wrapper
@ -188,13 +189,13 @@ begin
clk_in => ext_clk,
rst => pll_rst,
system_clk => system_clk,
system_reset => soc_rst_1,
system_reset => soc_rst,
core_alt_reset => core_alt_reset,
pll_locked => system_clk_locked,

wb_in => wb_dram_in,
wb_out => wb_dram_out,
wb_is_csr => wb_dram_csr,
wb_is_ctrl => wb_dram_ctrl,
wb_is_init => wb_dram_init,

serial_tx => uart_pmod_tx,
@ -223,7 +224,6 @@ begin
led0_b_pwm <= not dram_init_done;
led0_r_pwm <= dram_init_error;
led0_g_pwm <= dram_init_done and not dram_init_error;
soc_rst <= soc_rst_0 or soc_rst_1;

end generate;


@ -60,7 +60,7 @@ architecture behaviour of toplevel is
-- DRAM wishbone connection
signal wb_dram_in : wishbone_master_out;
signal wb_dram_out : wishbone_slave_out;
signal wb_dram_csr : std_ulogic;
signal wb_dram_ctrl : std_ulogic;
signal wb_dram_init : std_ulogic;

-- Control/status
@ -87,7 +87,7 @@ begin
uart0_rxd => uart_main_rx,
wb_dram_in => wb_dram_in,
wb_dram_out => wb_dram_out,
wb_dram_csr => wb_dram_csr,
wb_dram_ctrl => wb_dram_ctrl,
wb_dram_init => wb_dram_init,
alt_reset => core_alt_reset
);
@ -140,8 +140,7 @@ begin
has_dram: if USE_LITEDRAM generate
signal dram_init_done : std_ulogic;
signal dram_init_error : std_ulogic;
signal soc_rst_0 : std_ulogic;
signal soc_rst_1 : std_ulogic;
signal dram_sys_rst : std_ulogic;
begin

-- Eventually dig out the frequency from the generator
@ -150,15 +149,17 @@ begin

reset_controller: entity work.soc_reset
generic map(
RESET_LOW => RESET_LOW
RESET_LOW => RESET_LOW,
PLL_RESET_BITS => 18,
SOC_RESET_BITS => 1
)
port map(
ext_clk => ext_clk,
pll_clk => system_clk,
pll_locked_in => system_clk_locked,
pll_locked_in => '1',
ext_rst_in => ext_rst,
pll_rst_out => pll_rst,
rst_out => soc_rst_0
rst_out => open
);

dram: entity work.litedram_wrapper
@ -170,12 +171,12 @@ begin
clk_in => ext_clk,
rst => pll_rst,
system_clk => system_clk,
system_reset => soc_rst_1,
system_reset => soc_rst,
pll_locked => system_clk_locked,

wb_in => wb_dram_in,
wb_out => wb_dram_out,
wb_is_csr => wb_dram_csr,
wb_is_ctrl => wb_dram_ctrl,
wb_is_init => wb_dram_init,

serial_tx => open,
@ -203,7 +204,6 @@ begin

led0 <= dram_init_done and not dram_init_error;
led1 <= dram_init_error; -- Make it blink ?
soc_rst <= soc_rst_0 or soc_rst_1;

end generate;
end architecture behaviour;

@ -29,3 +29,6 @@ hello_world.hex: hello_world.bin

clean:
@rm -f *.o hello_world.elf hello_world.bin hello_world.hex
distclean: clean
rm -f *~


@ -6,4 +6,7 @@ void potato_uart_irq_dis(void);
int getchar(void);
int putchar(int c);
int puts(const char *str);

#ifndef __USE_LIBC
size_t strlen(const char *s);
#endif

@ -31,4 +31,7 @@
#define POTATO_CONSOLE_CLOCK_DIV 0x18
#define POTATO_CONSOLE_IRQ_EN 0x20

/* Definition for the LiteDRAM control registers */
#define DRAM_CTRL_BASE 0xc0100000

#endif /* __MICROWATT_SOC_H */

@ -120,6 +120,7 @@ int puts(const char *str)
return 0;
}

#ifndef __USE_LIBC
size_t strlen(const char *s)
{
size_t len = 0;
@ -129,3 +130,4 @@ size_t strlen(const char *s)

return len;
}
#endif

@ -37,7 +37,5 @@
},

# CSR Port -----------------------------------------------------------------
"csr_expose": "False", # expose access to CSR (I/O) ports
"csr_align" : 32, # CSR alignment
"csr_base" : 0xc0100000 # For cpu=None only
"csr_base" : 0xc0100000, # For cpu=None only
}

@ -104,8 +104,7 @@ def generate_one(t, mw_init):
# Override values for mw_init
if mw_init:
core_config["cpu"] = None
core_config["csr_expose"] = True
core_config["csr_align"] = 64
core_config["csr_alignment"] = 64

# Generate core
if core_config["sdram_phy"] in [litedram_phys.ECP5DDRPHY]:

@ -37,6 +37,5 @@
},

# CSR Port -----------------------------------------------------------------
"csr_expose": "False", # expose access to CSR (I/O) ports
"csr_align" : 32, # 64-bit alignment
"csr_base" : 0xc0100000, # For cpu=None only
}

@ -21,7 +21,7 @@ OBJCOPY = $(CROSS_COMPILE)objcopy

#### Flags

CPPFLAGS = -nostdinc
CPPFLAGS = -nostdinc -D__USE_LIBC
CPPFLAGS += -I$(SRC_DIR)/libc/include -I$(LXSRC_DIR) -I$(LXINC_DIR) -I$(GENINC_DIR) -I$(SRC_DIR)/include -I$(SRC_DIR)/../../../include
CPPFLAGS += -isystem $(shell $(CC) -print-file-name=include)
CFLAGS = -Os -g -Wall -std=c99 -m64 -mabi=elfv2 -msoft-float -mno-string -mno-multiple -mno-vsx -mno-altivec -mlittle-endian -fno-stack-protector -mstrict-align -ffreestanding -fdata-sections -ffunction-sections -fno-delete-null-pointer-checks
@ -36,7 +36,7 @@ define Q
endef
else
define Q
@echo " [$1] $(3)"
@echo " [$1] " $(shell basename $3)
@$(2)
endef
endif

@ -1,9 +1,18 @@
static inline void flush_cpu_dcache(void) { }
static inline void flush_l2_cache(void) { }
#ifndef __SYSTEM_H
#define __SYSTEM_H

#include "microwatt_soc.h"
#include "io.h"

#define CSR_ACCESSORS_DEFINED
#define CSR_BASE DRAM_CTRL_BASE
#define CONFIG_CPU_NOP "nop"

#define CONFIG_CPU_NOP "nop"
#define CONFIG_CLOCK_FREQUENCY 100000000
extern void flush_cpu_dcache(void);
extern void flush_cpu_icache(void);
static inline void flush_l2_cache(void) { }

/* Fake timer stuff. LiteX should abstract this */
static inline void timer0_en_write(int e) { }
static inline void timer0_reload_write(int r) { }
static inline void timer0_load_write(int l) { }
@ -15,3 +24,16 @@ static inline uint64_t timer0_value_read(void)
__asm__ volatile ("mfdec %0" : "=r" (val));
return val;
}

static inline void csr_write_simple(unsigned long v, unsigned long a)
{
return writel(v, a);
}

static inline unsigned long csr_read_simple(unsigned long a)
{
return readl(a);
}

#endif /* __SYSTEM_H */


@ -10,89 +10,7 @@
#include "microwatt_soc.h"
#include "io.h"
#include "sdram.h"

/*
* Core UART functions to implement for a port
*/

static uint64_t potato_uart_base;

#define PROC_FREQ 100000000
#define UART_FREQ 115200

static uint8_t potato_uart_reg_read(int offset)
{
return readb(potato_uart_base + offset);
}

static void potato_uart_reg_write(int offset, uint8_t val)
{
writeb(val, potato_uart_base + offset);
}

static bool potato_uart_rx_empty(void)
{
uint8_t val = potato_uart_reg_read(POTATO_CONSOLE_STATUS);

return (val & POTATO_CONSOLE_STATUS_RX_EMPTY) != 0;
}

static int potato_uart_tx_full(void)
{
uint8_t val = potato_uart_reg_read(POTATO_CONSOLE_STATUS);

return (val & POTATO_CONSOLE_STATUS_TX_FULL) != 0;
}

static char potato_uart_read(void)
{
return potato_uart_reg_read(POTATO_CONSOLE_RX);
}

static void potato_uart_write(char c)
{
potato_uart_reg_write(POTATO_CONSOLE_TX, c);
}

static unsigned long potato_uart_divisor(unsigned long proc_freq,
unsigned long uart_freq)
{
return proc_freq / (uart_freq * 16) - 1;
}

void potato_uart_init(void)
{
potato_uart_base = UART_BASE;

potato_uart_reg_write(POTATO_CONSOLE_CLOCK_DIV,
potato_uart_divisor(PROC_FREQ, UART_FREQ));
}

int getchar(void)
{
while (potato_uart_rx_empty())
/* Do nothing */ ;

return potato_uart_read();
}

int putchar(int c)
{
while (potato_uart_tx_full())
/* Do Nothing */;

potato_uart_write(c);
return c;
}

void putstr(const char *str, unsigned long len)
{
for (unsigned long i = 0; i < len; i++) {
if (str[i] == '\n')
putchar('\r');
putchar(str[i]);
}
}
#include "console.h"

int _printf(const char *fmt, ...)
{
@ -103,26 +21,26 @@ int _printf(const char *fmt, ...)
va_start(ap, fmt);
count = vsnprintf(buffer, sizeof(buffer), fmt, ap);
va_end(ap);
putstr(buffer, count);
puts(buffer);
return count;
}

void flush_cpu_dcache(void) { }
void flush_cpu_icache(void) { }
void flush_l2_cache(void) { }
void flush_cpu_dcache(void)
{
}

void flush_cpu_icache(void)
{
__asm__ volatile ("icbi 0,0; isync" : : : "memory");
}

void main(void)
{
unsigned long long ftr, val;
int i;

/*
* Let things settle ... not sure why but the UART is
* not happy otherwise. The PLL might need to settle ?
*/
/* Init the UART */
potato_uart_init();
for (i = 0; i < 100000; i++)
potato_uart_reg_read(POTATO_CONSOLE_STATUS);

printf("\n\nWelcome to Microwatt !\n\n");

/* TODO: Add core version information somewhere in syscon, possibly

@ -25,7 +25,7 @@ entity litedram_wrapper is
-- Wishbone ports:
wb_in : in wishbone_master_out;
wb_out : out wishbone_slave_out;
wb_is_csr : in std_ulogic;
wb_is_ctrl : in std_ulogic;
wb_is_init : in std_ulogic;

-- Init core serial debug
@ -58,32 +58,39 @@ end entity litedram_wrapper;
architecture behaviour of litedram_wrapper is

component litedram_core port (
clk : in std_ulogic;
rst : in std_ulogic;
pll_locked : out std_ulogic;
ddram_a : out std_ulogic_vector(DRAM_ALINES-1 downto 0);
ddram_ba : out std_ulogic_vector(2 downto 0);
ddram_ras_n : out std_ulogic;
ddram_cas_n : out std_ulogic;
ddram_we_n : out std_ulogic;
ddram_cs_n : out std_ulogic;
ddram_dm : out std_ulogic_vector(1 downto 0);
ddram_dq : inout std_ulogic_vector(15 downto 0);
ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
ddram_dqs_n : inout std_ulogic_vector(1 downto 0);
ddram_clk_p : out std_ulogic;
ddram_clk_n : out std_ulogic;
ddram_cke : out std_ulogic;
ddram_odt : out std_ulogic;
ddram_reset_n : out std_ulogic;
init_done : out std_ulogic;
init_error : out std_ulogic;
user_clk : out std_ulogic;
user_rst : out std_ulogic;
csr_port0_adr : in std_ulogic_vector(13 downto 0);
csr_port0_we : in std_ulogic;
csr_port0_dat_w : in std_ulogic_vector(31 downto 0);
csr_port0_dat_r : out std_ulogic_vector(31 downto 0);
clk : in std_ulogic;
rst : in std_ulogic;
pll_locked : out std_ulogic;
ddram_a : out std_ulogic_vector(DRAM_ALINES-1 downto 0);
ddram_ba : out std_ulogic_vector(2 downto 0);
ddram_ras_n : out std_ulogic;
ddram_cas_n : out std_ulogic;
ddram_we_n : out std_ulogic;
ddram_cs_n : out std_ulogic;
ddram_dm : out std_ulogic_vector(1 downto 0);
ddram_dq : inout std_ulogic_vector(15 downto 0);
ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
ddram_dqs_n : inout std_ulogic_vector(1 downto 0);
ddram_clk_p : out std_ulogic;
ddram_clk_n : out std_ulogic;
ddram_cke : out std_ulogic;
ddram_odt : out std_ulogic;
ddram_reset_n : out std_ulogic;
init_done : out std_ulogic;
init_error : out std_ulogic;
user_clk : out std_ulogic;
user_rst : out std_ulogic;
wb_ctrl_adr : in std_ulogic_vector(29 downto 0);
wb_ctrl_dat_w : in std_ulogic_vector(31 downto 0);
wb_ctrl_dat_r : out std_ulogic_vector(31 downto 0);
wb_ctrl_sel : in std_ulogic_vector(3 downto 0);
wb_ctrl_cyc : in std_ulogic;
wb_ctrl_stb : in std_ulogic;
wb_ctrl_ack : out std_ulogic;
wb_ctrl_we : in std_ulogic;
wb_ctrl_cti : in std_ulogic_vector(2 downto 0);
wb_ctrl_bte : in std_ulogic_vector(1 downto 0);
wb_ctrl_err : out std_ulogic;
user_port_native_0_cmd_valid : in std_ulogic;
user_port_native_0_cmd_ready : out std_ulogic;
user_port_native_0_cmd_we : in std_ulogic;
@ -112,20 +119,19 @@ architecture behaviour of litedram_wrapper is

signal ad3 : std_ulogic;

signal dram_user_reset : std_ulogic;

signal csr_port0_adr : std_ulogic_vector(13 downto 0);
signal csr_port0_we : std_ulogic;
signal csr_port0_dat_w : std_ulogic_vector(31 downto 0);
signal csr_port0_dat_r : std_ulogic_vector(31 downto 0);
signal csr_port_read_comb : std_ulogic_vector(63 downto 0);
signal csr_valid : std_ulogic;
signal csr_write_valid : std_ulogic;
signal wb_ctrl_adr : std_ulogic_vector(29 downto 0);
signal wb_ctrl_dat_w : std_ulogic_vector(31 downto 0);
signal wb_ctrl_dat_r : std_ulogic_vector(31 downto 0);
signal wb_ctrl_sel : std_ulogic_vector(3 downto 0);
signal wb_ctrl_cyc : std_ulogic;
signal wb_ctrl_stb : std_ulogic;
signal wb_ctrl_ack : std_ulogic;
signal wb_ctrl_we : std_ulogic;

signal wb_init_in : wishbone_master_out;
signal wb_init_out : wishbone_slave_out;

type state_t is (CMD, MWRITE, MREAD, CSR);
type state_t is (CMD, MWRITE, MREAD);
signal state : state_t;

constant INIT_RAM_SIZE : integer := 16384;
@ -192,7 +198,7 @@ begin
ad3 <= wb_in.adr(3);

-- DRAM data interface signals
user_port0_cmd_valid <= (wb_in.cyc and wb_in.stb and not wb_is_csr and not wb_is_init)
user_port0_cmd_valid <= (wb_in.cyc and wb_in.stb and not wb_is_ctrl and not wb_is_init)
when state = CMD else '0';
user_port0_cmd_we <= wb_in.we when state = CMD else '0';
user_port0_wdata_valid <= '1' when state = MWRITE else '0';
@ -202,21 +208,21 @@ begin
user_port0_wdata_we <= wb_in.sel & "00000000" when ad3 = '1' else
"00000000" & wb_in.sel;

-- DRAM CSR interface signals. We only support access to the bottom byte
csr_valid <= wb_in.cyc and wb_in.stb and wb_is_csr;
csr_write_valid <= wb_in.we and wb_in.sel(0);
csr_port0_adr <= wb_in.adr(15 downto 2) when wb_is_csr = '1' else (others => '0');
csr_port0_dat_w <= wb_in.dat(31 downto 0);
csr_port0_we <= (csr_valid and csr_write_valid) when state = CMD else '0';
-- DRAM ctrl interface signals
wb_ctrl_adr <= x"0000" & wb_in.adr(15 downto 2);
wb_ctrl_dat_w <= wb_in.dat(31 downto 0);
wb_ctrl_sel <= wb_in.sel(3 downto 0);
wb_ctrl_cyc <= wb_in.cyc and wb_is_ctrl;
wb_ctrl_stb <= wb_in.stb and wb_is_ctrl;
wb_ctrl_we <= wb_in.we;

-- Wishbone out signals
wb_out.ack <= '1' when state = CSR else
wb_out.ack <= wb_ctrl_ack when wb_is_ctrl ='1' else
wb_init_out.ack when wb_is_init = '1' else
user_port0_wdata_ready when state = MWRITE else
user_port0_rdata_valid when state = MREAD else '0';

csr_port_read_comb <= x"00000000" & csr_port0_dat_r;
wb_out.dat <= csr_port_read_comb when wb_is_csr = '1' else
wb_out.dat <= (x"00000000" & wb_ctrl_dat_r) when wb_is_ctrl = '1' else
wb_init_out.dat when wb_is_init = '1' else
user_port0_rdata_data(127 downto 64) when ad3 = '1' else
user_port0_rdata_data(63 downto 0);
@ -226,7 +232,6 @@ begin
-- Reset ignored, the reset controller use the pll lock signal,
-- and alternate core reset address set when DRAM is not initialized.
--
system_reset <= '0';
core_alt_reset <= not init_done;

-- State machine
@ -234,14 +239,12 @@ begin
begin
if rising_edge(system_clk) then
if dram_user_reset = '1' then
if system_reset = '1' then
state <= CMD;
else
case state is
when CMD =>
if csr_valid = '1' then
state <= CSR;
elsif (user_port0_cmd_ready and user_port0_cmd_valid) = '1' then
if (user_port0_cmd_ready and user_port0_cmd_valid) = '1' then
state <= MWRITE when wb_in.we = '1' else MREAD;
end if;
when MWRITE =>
@ -252,8 +255,6 @@ begin
if user_port0_rdata_valid = '1' then
state <= CMD;
end if;
when CSR =>
state <= CMD;
end case;
end if;
end if;
@ -282,11 +283,18 @@ begin
init_done => init_done,
init_error => init_error,
user_clk => system_clk,
user_rst => dram_user_reset,
csr_port0_adr => csr_port0_adr,
csr_port0_we => csr_port0_we,
csr_port0_dat_w => csr_port0_dat_w,
csr_port0_dat_r => csr_port0_dat_r,
user_rst => system_reset,
wb_ctrl_adr => wb_ctrl_adr,
wb_ctrl_dat_w => wb_ctrl_dat_w,
wb_ctrl_dat_r => wb_ctrl_dat_r,
wb_ctrl_sel => wb_ctrl_sel,
wb_ctrl_cyc => wb_ctrl_cyc,
wb_ctrl_stb => wb_ctrl_stb,
wb_ctrl_ack => wb_ctrl_ack,
wb_ctrl_we => wb_ctrl_we,
wb_ctrl_cti => "000",
wb_ctrl_bte => "00",
wb_ctrl_err => open,
user_port_native_0_cmd_valid => user_port0_cmd_valid,
user_port_native_0_cmd_ready => user_port0_cmd_ready,
user_port_native_0_cmd_we => user_port0_cmd_we,

@ -25,7 +25,7 @@ entity litedram_wrapper is
-- Wishbone ports:
wb_in : in wishbone_master_out;
wb_out : out wishbone_slave_out;
wb_is_csr : in std_ulogic;
wb_is_ctrl : in std_ulogic;
wb_is_init : in std_ulogic;

-- Init core serial debug
@ -123,7 +123,7 @@ begin
ad3 <= wb_in.adr(3);

-- DRAM interface signals
user_port0_cmd_valid <= (wb_in.cyc and wb_in.stb and not wb_is_csr and not wb_is_init)
user_port0_cmd_valid <= (wb_in.cyc and wb_in.stb and not wb_is_ctrl and not wb_is_init)
when state = CMD else '0';
user_port0_cmd_we <= wb_in.we when state = CMD else '0';
user_port0_wdata_valid <= '1' when state = MWRITE else '0';
@ -134,10 +134,10 @@ begin
"00000000" & wb_in.sel;

-- Wishbone out signals. CSR and init memory do nothing, just ack
wb_out.ack <= '1' when (wb_is_csr = '1' or wb_is_init = '1') else
wb_out.ack <= '1' when (wb_is_ctrl = '1' or wb_is_init = '1') else
user_port0_wdata_ready when state = MWRITE else
user_port0_rdata_valid when state = MREAD else '0';
wb_out.dat <= (others => '0') when (wb_is_csr = '1' or wb_is_init = '1') else
wb_out.dat <= (others => '0') when (wb_is_ctrl = '1' or wb_is_init = '1') else
user_port0_rdata_data(127 downto 64) when ad3 = '1' else
user_port0_rdata_data(63 downto 0);
wb_out.stall <= '0' when wb_in.cyc = '0' else not wb_out.ack;

@ -25,7 +25,7 @@ entity litedram_wrapper is
-- Wishbone ports:
wb_in : in wishbone_master_out;
wb_out : out wishbone_slave_out;
wb_is_csr : in std_ulogic;
wb_is_ctrl : in std_ulogic;
wb_is_init : in std_ulogic;

-- Init core serial debug
@ -58,32 +58,39 @@ end entity litedram_wrapper;
architecture behaviour of litedram_wrapper is

component litedram_core port (
clk : in std_ulogic;
rst : in std_ulogic;
pll_locked : out std_ulogic;
ddram_a : out std_ulogic_vector(DRAM_ALINES-1 downto 0);
ddram_ba : out std_ulogic_vector(2 downto 0);
ddram_ras_n : out std_ulogic;
ddram_cas_n : out std_ulogic;
ddram_we_n : out std_ulogic;
ddram_cs_n : out std_ulogic;
ddram_dm : out std_ulogic_vector(1 downto 0);
ddram_dq : inout std_ulogic_vector(15 downto 0);
ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
ddram_dqs_n : inout std_ulogic_vector(1 downto 0);
ddram_clk_p : out std_ulogic;
ddram_clk_n : out std_ulogic;
ddram_cke : out std_ulogic;
ddram_odt : out std_ulogic;
ddram_reset_n : out std_ulogic;
init_done : out std_ulogic;
init_error : out std_ulogic;
user_clk : out std_ulogic;
user_rst : out std_ulogic;
csr_port0_adr : in std_ulogic_vector(13 downto 0);
csr_port0_we : in std_ulogic;
csr_port0_dat_w : in std_ulogic_vector(31 downto 0);
csr_port0_dat_r : out std_ulogic_vector(31 downto 0);
clk : in std_ulogic;
rst : in std_ulogic;
pll_locked : out std_ulogic;
ddram_a : out std_ulogic_vector(DRAM_ALINES-1 downto 0);
ddram_ba : out std_ulogic_vector(2 downto 0);
ddram_ras_n : out std_ulogic;
ddram_cas_n : out std_ulogic;
ddram_we_n : out std_ulogic;
ddram_cs_n : out std_ulogic;
ddram_dm : out std_ulogic_vector(1 downto 0);
ddram_dq : inout std_ulogic_vector(15 downto 0);
ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
ddram_dqs_n : inout std_ulogic_vector(1 downto 0);
ddram_clk_p : out std_ulogic;
ddram_clk_n : out std_ulogic;
ddram_cke : out std_ulogic;
ddram_odt : out std_ulogic;
ddram_reset_n : out std_ulogic;
init_done : out std_ulogic;
init_error : out std_ulogic;
user_clk : out std_ulogic;
user_rst : out std_ulogic;
wb_ctrl_adr : in std_ulogic_vector(29 downto 0);
wb_ctrl_dat_w : in std_ulogic_vector(31 downto 0);
wb_ctrl_dat_r : out std_ulogic_vector(31 downto 0);
wb_ctrl_sel : in std_ulogic_vector(3 downto 0);
wb_ctrl_cyc : in std_ulogic;
wb_ctrl_stb : in std_ulogic;
wb_ctrl_ack : out std_ulogic;
wb_ctrl_we : in std_ulogic;
wb_ctrl_cti : in std_ulogic_vector(2 downto 0);
wb_ctrl_bte : in std_ulogic_vector(1 downto 0);
wb_ctrl_err : out std_ulogic;
user_port_native_0_cmd_valid : in std_ulogic;
user_port_native_0_cmd_ready : out std_ulogic;
user_port_native_0_cmd_we : in std_ulogic;
@ -112,20 +119,19 @@ architecture behaviour of litedram_wrapper is

signal ad3 : std_ulogic;

signal dram_user_reset : std_ulogic;

signal csr_port0_adr : std_ulogic_vector(13 downto 0);
signal csr_port0_we : std_ulogic;
signal csr_port0_dat_w : std_ulogic_vector(31 downto 0);
signal csr_port0_dat_r : std_ulogic_vector(31 downto 0);
signal csr_port_read_comb : std_ulogic_vector(63 downto 0);
signal csr_valid : std_ulogic;
signal csr_write_valid : std_ulogic;
signal wb_ctrl_adr : std_ulogic_vector(29 downto 0);
signal wb_ctrl_dat_w : std_ulogic_vector(31 downto 0);
signal wb_ctrl_dat_r : std_ulogic_vector(31 downto 0);
signal wb_ctrl_sel : std_ulogic_vector(3 downto 0);
signal wb_ctrl_cyc : std_ulogic;
signal wb_ctrl_stb : std_ulogic;
signal wb_ctrl_ack : std_ulogic;
signal wb_ctrl_we : std_ulogic;

signal wb_init_in : wishbone_master_out;
signal wb_init_out : wishbone_slave_out;

type state_t is (CMD, MWRITE, MREAD, CSR);
type state_t is (CMD, MWRITE, MREAD);
signal state : state_t;

constant INIT_RAM_SIZE : integer := 16384;
@ -192,7 +198,7 @@ begin
ad3 <= wb_in.adr(3);

-- DRAM data interface signals
user_port0_cmd_valid <= (wb_in.cyc and wb_in.stb and not wb_is_csr and not wb_is_init)
user_port0_cmd_valid <= (wb_in.cyc and wb_in.stb and not wb_is_ctrl and not wb_is_init)
when state = CMD else '0';
user_port0_cmd_we <= wb_in.we when state = CMD else '0';
user_port0_wdata_valid <= '1' when state = MWRITE else '0';
@ -202,21 +208,21 @@ begin
user_port0_wdata_we <= wb_in.sel & "00000000" when ad3 = '1' else
"00000000" & wb_in.sel;

-- DRAM CSR interface signals. We only support access to the bottom byte
csr_valid <= wb_in.cyc and wb_in.stb and wb_is_csr;
csr_write_valid <= wb_in.we and wb_in.sel(0);
csr_port0_adr <= wb_in.adr(15 downto 2) when wb_is_csr = '1' else (others => '0');
csr_port0_dat_w <= wb_in.dat(31 downto 0);
csr_port0_we <= (csr_valid and csr_write_valid) when state = CMD else '0';
-- DRAM ctrl interface signals
wb_ctrl_adr <= x"0000" & wb_in.adr(15 downto 2);
wb_ctrl_dat_w <= wb_in.dat(31 downto 0);
wb_ctrl_sel <= wb_in.sel(3 downto 0);
wb_ctrl_cyc <= wb_in.cyc and wb_is_ctrl;
wb_ctrl_stb <= wb_in.stb and wb_is_ctrl;
wb_ctrl_we <= wb_in.we;

-- Wishbone out signals
wb_out.ack <= '1' when state = CSR else
wb_out.ack <= wb_ctrl_ack when wb_is_ctrl ='1' else
wb_init_out.ack when wb_is_init = '1' else
user_port0_wdata_ready when state = MWRITE else
user_port0_rdata_valid when state = MREAD else '0';

csr_port_read_comb <= x"00000000" & csr_port0_dat_r;
wb_out.dat <= csr_port_read_comb when wb_is_csr = '1' else
wb_out.dat <= (x"00000000" & wb_ctrl_dat_r) when wb_is_ctrl = '1' else
wb_init_out.dat when wb_is_init = '1' else
user_port0_rdata_data(127 downto 64) when ad3 = '1' else
user_port0_rdata_data(63 downto 0);
@ -226,7 +232,6 @@ begin
-- Reset ignored, the reset controller use the pll lock signal,
-- and alternate core reset address set when DRAM is not initialized.
--
system_reset <= '0';
core_alt_reset <= not init_done;

-- State machine
@ -234,14 +239,12 @@ begin
begin
if rising_edge(system_clk) then
if dram_user_reset = '1' then
if system_reset = '1' then
state <= CMD;
else
case state is
when CMD =>
if csr_valid = '1' then
state <= CSR;
elsif (user_port0_cmd_ready and user_port0_cmd_valid) = '1' then
if (user_port0_cmd_ready and user_port0_cmd_valid) = '1' then
state <= MWRITE when wb_in.we = '1' else MREAD;
end if;
when MWRITE =>
@ -252,8 +255,6 @@ begin
if user_port0_rdata_valid = '1' then
state <= CMD;
end if;
when CSR =>
state <= CMD;
end case;
end if;
end if;
@ -282,11 +283,18 @@ begin
init_done => init_done,
init_error => init_error,
user_clk => system_clk,
user_rst => dram_user_reset,
csr_port0_adr => csr_port0_adr,
csr_port0_we => csr_port0_we,
csr_port0_dat_w => csr_port0_dat_w,
csr_port0_dat_r => csr_port0_dat_r,
user_rst => system_reset,
wb_ctrl_adr => wb_ctrl_adr,
wb_ctrl_dat_w => wb_ctrl_dat_w,
wb_ctrl_dat_r => wb_ctrl_dat_r,
wb_ctrl_sel => wb_ctrl_sel,
wb_ctrl_cyc => wb_ctrl_cyc,
wb_ctrl_stb => wb_ctrl_stb,
wb_ctrl_ack => wb_ctrl_ack,
wb_ctrl_we => wb_ctrl_we,
wb_ctrl_cti => "000",
wb_ctrl_bte => "00",
wb_ctrl_err => open,
user_port_native_0_cmd_valid => user_port0_cmd_valid,
user_port_native_0_cmd_ready => user_port0_cmd_ready,
user_port_native_0_cmd_we => user_port0_cmd_we,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -25,7 +25,7 @@ entity litedram_wrapper is
-- Wishbone ports:
wb_in : in wishbone_master_out;
wb_out : out wishbone_slave_out;
wb_is_csr : in std_ulogic;
wb_is_ctrl : in std_ulogic;
wb_is_init : in std_ulogic;

-- Init core serial debug
@ -58,32 +58,39 @@ end entity litedram_wrapper;
architecture behaviour of litedram_wrapper is

component litedram_core port (
clk : in std_ulogic;
rst : in std_ulogic;
pll_locked : out std_ulogic;
ddram_a : out std_ulogic_vector(DRAM_ALINES-1 downto 0);
ddram_ba : out std_ulogic_vector(2 downto 0);
ddram_ras_n : out std_ulogic;
ddram_cas_n : out std_ulogic;
ddram_we_n : out std_ulogic;
ddram_cs_n : out std_ulogic;
ddram_dm : out std_ulogic_vector(1 downto 0);
ddram_dq : inout std_ulogic_vector(15 downto 0);
ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
ddram_dqs_n : inout std_ulogic_vector(1 downto 0);
ddram_clk_p : out std_ulogic;
ddram_clk_n : out std_ulogic;
ddram_cke : out std_ulogic;
ddram_odt : out std_ulogic;
ddram_reset_n : out std_ulogic;
init_done : out std_ulogic;
init_error : out std_ulogic;
user_clk : out std_ulogic;
user_rst : out std_ulogic;
csr_port0_adr : in std_ulogic_vector(13 downto 0);
csr_port0_we : in std_ulogic;
csr_port0_dat_w : in std_ulogic_vector(31 downto 0);
csr_port0_dat_r : out std_ulogic_vector(31 downto 0);
clk : in std_ulogic;
rst : in std_ulogic;
pll_locked : out std_ulogic;
ddram_a : out std_ulogic_vector(DRAM_ALINES-1 downto 0);
ddram_ba : out std_ulogic_vector(2 downto 0);
ddram_ras_n : out std_ulogic;
ddram_cas_n : out std_ulogic;
ddram_we_n : out std_ulogic;
ddram_cs_n : out std_ulogic;
ddram_dm : out std_ulogic_vector(1 downto 0);
ddram_dq : inout std_ulogic_vector(15 downto 0);
ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
ddram_dqs_n : inout std_ulogic_vector(1 downto 0);
ddram_clk_p : out std_ulogic;
ddram_clk_n : out std_ulogic;
ddram_cke : out std_ulogic;
ddram_odt : out std_ulogic;
ddram_reset_n : out std_ulogic;
init_done : out std_ulogic;
init_error : out std_ulogic;
user_clk : out std_ulogic;
user_rst : out std_ulogic;
wb_ctrl_adr : in std_ulogic_vector(29 downto 0);
wb_ctrl_dat_w : in std_ulogic_vector(31 downto 0);
wb_ctrl_dat_r : out std_ulogic_vector(31 downto 0);
wb_ctrl_sel : in std_ulogic_vector(3 downto 0);
wb_ctrl_cyc : in std_ulogic;
wb_ctrl_stb : in std_ulogic;
wb_ctrl_ack : out std_ulogic;
wb_ctrl_we : in std_ulogic;
wb_ctrl_cti : in std_ulogic_vector(2 downto 0);
wb_ctrl_bte : in std_ulogic_vector(1 downto 0);
wb_ctrl_err : out std_ulogic;
user_port_native_0_cmd_valid : in std_ulogic;
user_port_native_0_cmd_ready : out std_ulogic;
user_port_native_0_cmd_we : in std_ulogic;
@ -112,20 +119,19 @@ architecture behaviour of litedram_wrapper is

signal ad3 : std_ulogic;

signal dram_user_reset : std_ulogic;

signal csr_port0_adr : std_ulogic_vector(13 downto 0);
signal csr_port0_we : std_ulogic;
signal csr_port0_dat_w : std_ulogic_vector(31 downto 0);
signal csr_port0_dat_r : std_ulogic_vector(31 downto 0);
signal csr_port_read_comb : std_ulogic_vector(63 downto 0);
signal csr_valid : std_ulogic;
signal csr_write_valid : std_ulogic;
signal wb_ctrl_adr : std_ulogic_vector(29 downto 0);
signal wb_ctrl_dat_w : std_ulogic_vector(31 downto 0);
signal wb_ctrl_dat_r : std_ulogic_vector(31 downto 0);
signal wb_ctrl_sel : std_ulogic_vector(3 downto 0);
signal wb_ctrl_cyc : std_ulogic;
signal wb_ctrl_stb : std_ulogic;
signal wb_ctrl_ack : std_ulogic;
signal wb_ctrl_we : std_ulogic;

signal wb_init_in : wishbone_master_out;
signal wb_init_out : wishbone_slave_out;

type state_t is (CMD, MWRITE, MREAD, CSR);
type state_t is (CMD, MWRITE, MREAD);
signal state : state_t;

constant INIT_RAM_SIZE : integer := 16384;
@ -192,7 +198,7 @@ begin
ad3 <= wb_in.adr(3);

-- DRAM data interface signals
user_port0_cmd_valid <= (wb_in.cyc and wb_in.stb and not wb_is_csr and not wb_is_init)
user_port0_cmd_valid <= (wb_in.cyc and wb_in.stb and not wb_is_ctrl and not wb_is_init)
when state = CMD else '0';
user_port0_cmd_we <= wb_in.we when state = CMD else '0';
user_port0_wdata_valid <= '1' when state = MWRITE else '0';
@ -202,21 +208,21 @@ begin
user_port0_wdata_we <= wb_in.sel & "00000000" when ad3 = '1' else
"00000000" & wb_in.sel;

-- DRAM CSR interface signals. We only support access to the bottom byte
csr_valid <= wb_in.cyc and wb_in.stb and wb_is_csr;
csr_write_valid <= wb_in.we and wb_in.sel(0);
csr_port0_adr <= wb_in.adr(15 downto 2) when wb_is_csr = '1' else (others => '0');
csr_port0_dat_w <= wb_in.dat(31 downto 0);
csr_port0_we <= (csr_valid and csr_write_valid) when state = CMD else '0';
-- DRAM ctrl interface signals
wb_ctrl_adr <= x"0000" & wb_in.adr(15 downto 2);
wb_ctrl_dat_w <= wb_in.dat(31 downto 0);
wb_ctrl_sel <= wb_in.sel(3 downto 0);
wb_ctrl_cyc <= wb_in.cyc and wb_is_ctrl;
wb_ctrl_stb <= wb_in.stb and wb_is_ctrl;
wb_ctrl_we <= wb_in.we;

-- Wishbone out signals
wb_out.ack <= '1' when state = CSR else
wb_out.ack <= wb_ctrl_ack when wb_is_ctrl ='1' else
wb_init_out.ack when wb_is_init = '1' else
user_port0_wdata_ready when state = MWRITE else
user_port0_rdata_valid when state = MREAD else '0';

csr_port_read_comb <= x"00000000" & csr_port0_dat_r;
wb_out.dat <= csr_port_read_comb when wb_is_csr = '1' else
wb_out.dat <= (x"00000000" & wb_ctrl_dat_r) when wb_is_ctrl = '1' else
wb_init_out.dat when wb_is_init = '1' else
user_port0_rdata_data(127 downto 64) when ad3 = '1' else
user_port0_rdata_data(63 downto 0);
@ -226,7 +232,6 @@ begin
-- Reset ignored, the reset controller use the pll lock signal,
-- and alternate core reset address set when DRAM is not initialized.
--
system_reset <= '0';
core_alt_reset <= not init_done;

-- State machine
@ -234,14 +239,12 @@ begin
begin
if rising_edge(system_clk) then
if dram_user_reset = '1' then
if system_reset = '1' then
state <= CMD;
else
case state is
when CMD =>
if csr_valid = '1' then
state <= CSR;
elsif (user_port0_cmd_ready and user_port0_cmd_valid) = '1' then
if (user_port0_cmd_ready and user_port0_cmd_valid) = '1' then
state <= MWRITE when wb_in.we = '1' else MREAD;
end if;
when MWRITE =>
@ -252,8 +255,6 @@ begin
if user_port0_rdata_valid = '1' then
state <= CMD;
end if;
when CSR =>
state <= CMD;
end case;
end if;
end if;
@ -282,11 +283,18 @@ begin
init_done => init_done,
init_error => init_error,
user_clk => system_clk,
user_rst => dram_user_reset,
csr_port0_adr => csr_port0_adr,
csr_port0_we => csr_port0_we,
csr_port0_dat_w => csr_port0_dat_w,
csr_port0_dat_r => csr_port0_dat_r,
user_rst => system_reset,
wb_ctrl_adr => wb_ctrl_adr,
wb_ctrl_dat_w => wb_ctrl_dat_w,
wb_ctrl_dat_r => wb_ctrl_dat_r,
wb_ctrl_sel => wb_ctrl_sel,
wb_ctrl_cyc => wb_ctrl_cyc,
wb_ctrl_stb => wb_ctrl_stb,
wb_ctrl_ack => wb_ctrl_ack,
wb_ctrl_we => wb_ctrl_we,
wb_ctrl_cti => "000",
wb_ctrl_bte => "00",
wb_ctrl_err => open,
user_port_native_0_cmd_valid => user_port0_cmd_valid,
user_port_native_0_cmd_ready => user_port0_cmd_ready,
user_port_native_0_cmd_we => user_port0_cmd_we,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -17,7 +17,7 @@ use work.wishbone_types.all;
-- 0xc0000000: SYSCON
-- 0xc0002000: UART0
-- 0xc0004000: XICS ICP
-- 0xc0100000: DRAM CSRs
-- 0xc0100000: LiteDRAM control (CSRs)
-- 0xf0000000: Block RAM (aliased & repeated)
-- 0xffff0000: DRAM init code (if any)

@ -39,7 +39,7 @@ entity soc is
-- DRAM controller signals
wb_dram_in : out wishbone_master_out;
wb_dram_out : in wishbone_slave_out;
wb_dram_csr : out std_ulogic;
wb_dram_ctrl : out std_ulogic;
wb_dram_init : out std_ulogic;

-- UART0 signals:
@ -73,7 +73,6 @@ architecture behaviour of soc is

-- Syscon signals
signal dram_at_0 : std_ulogic;
signal core_reset : std_ulogic;
signal do_core_reset : std_ulogic;
signal wb_syscon_in : wishbone_master_out;
signal wb_syscon_out : wishbone_slave_out;
@ -110,10 +109,34 @@ architecture behaviour of soc is
signal dmi_core_dout : std_ulogic_vector(63 downto 0);
signal dmi_core_req : std_ulogic;
signal dmi_core_ack : std_ulogic;

-- Delayed/latched resets and alt_reset
signal rst_core : std_ulogic := '1';
signal rst_uart : std_ulogic := '1';
signal rst_xics : std_ulogic := '1';
signal rst_bram : std_ulogic := '1';
signal rst_dtm : std_ulogic := '1';
signal rst_wbar : std_ulogic := '1';
signal rst_wbdb : std_ulogic := '1';
signal alt_reset_d : std_ulogic;

begin

resets: process(system_clk)
begin
if rising_edge(system_clk) then
rst_core <= rst or do_core_reset;
rst_uart <= rst;
rst_xics <= rst;
rst_bram <= rst;
rst_dtm <= rst;
rst_wbar <= rst;
rst_wbdb <= rst;
alt_reset_d <= alt_reset;
end if;
end process;

-- Processor core
core_reset <= rst or do_core_reset;
processor: entity work.core
generic map(
SIM => SIM,
@ -122,8 +145,8 @@ begin
)
port map(
clk => system_clk,
rst => core_reset,
alt_reset => alt_reset,
rst => rst_core,
alt_reset => alt_reset_d,
wishbone_insn_in => wishbone_icore_in,
wishbone_insn_out => wishbone_icore_out,
wishbone_data_in => wishbone_dcore_in,
@ -149,7 +172,8 @@ begin
NUM_MASTERS => NUM_WB_MASTERS
)
port map(
clk => system_clk, rst => rst,
clk => system_clk,
rst => rst_wbar,
wb_masters_in => wb_masters_out,
wb_masters_out => wb_masters_in,
wb_slave_out => wb_master_out,
@ -164,7 +188,7 @@ begin
SLAVE_BRAM,
SLAVE_DRAM,
SLAVE_DRAM_INIT,
SLAVE_DRAM_CSR,
SLAVE_DRAM_CTRL,
SLAVE_ICP_0,
SLAVE_NONE);
variable slave : slave_type;
@ -187,7 +211,7 @@ begin
elsif std_match(wb_master_out.adr, x"C0002---") then
slave := SLAVE_UART;
elsif std_match(wb_master_out.adr, x"C01-----") then
slave := SLAVE_DRAM_CSR;
slave := SLAVE_DRAM_CTRL;
elsif std_match(wb_master_out.adr, x"C0004---") then
slave := SLAVE_ICP_0;
end if;
@ -206,7 +230,7 @@ begin

wb_dram_in <= wb_master_out;
wb_dram_in.cyc <= '0';
wb_dram_csr <= '0';
wb_dram_ctrl <= '0';
wb_dram_init <= '0';
wb_syscon_in <= wb_master_out;
wb_syscon_in.cyc <= '0';
@ -221,10 +245,10 @@ begin
wb_dram_in.cyc <= wb_master_out.cyc;
wb_master_in <= wb_dram_out;
wb_dram_init <= '1';
when SLAVE_DRAM_CSR =>
when SLAVE_DRAM_CTRL =>
wb_dram_in.cyc <= wb_master_out.cyc;
wb_master_in <= wb_dram_out;
wb_dram_csr <= '1';
wb_dram_ctrl <= '1';
when SLAVE_SYSCON =>
wb_syscon_in.cyc <= wb_master_out.cyc;
wb_master_in <= wb_syscon_out;
@ -273,7 +297,7 @@ begin
)
port map(
clk => system_clk,
reset => rst,
reset => rst_uart,
txd => uart0_txd,
rxd => uart0_rxd,
irq => int_level_in(0),
@ -294,7 +318,7 @@ begin
)
port map(
clk => system_clk,
rst => rst,
rst => rst_xics,
wb_in => wb_xics0_in,
wb_out => wb_xics0_out,
int_level_in => int_level_in,
@ -309,7 +333,7 @@ begin
)
port map(
clk => system_clk,
rst => rst,
rst => rst_bram,
wishbone_in => wb_bram_in,
wishbone_out => wb_bram_out
);
@ -322,7 +346,7 @@ begin
)
port map(
sys_clk => system_clk,
sys_reset => rst,
sys_reset => rst_dtm,
dmi_addr => dmi_addr,
dmi_din => dmi_din,
dmi_dout => dmi_dout,
@ -380,7 +404,8 @@ begin

-- Wishbone debug master (TODO: Add a DMI address decoder)
wishbone_debug: entity work.wishbone_debug_master
port map(clk => system_clk, rst => rst,
port map(clk => system_clk,
rst => rst_wbdb,
dmi_addr => dmi_addr(1 downto 0),
dmi_dout => dmi_wb_dout,
dmi_din => dmi_dout,

Loading…
Cancel
Save