mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-03-09 20:18:27 +00:00
Merge pull request #177 from antonblanchard/litedram
LiteDRAM fixes from Ben
This commit is contained in:
4
Makefile
4
Makefile
@@ -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
|
||||
|
||||
52
core.vhdl
52
core.vhdl
@@ -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);
|
||||
|
||||
--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);
|
||||
pll_locked_in <= tv.pll_locked_in;
|
||||
ext_rst_in <= tv.ext_rst_in;
|
||||
|
||||
assert pll_rst_out_expected = pll_rst_out report "pll_rst_out bad";
|
||||
assert rst_out_expected = rst_out report "rst_out bad";
|
||||
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 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) { }
|
||||
#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"
|
||||
|
||||
extern void flush_cpu_dcache(void);
|
||||
extern void flush_cpu_icache(void);
|
||||
static inline void flush_l2_cache(void) { }
|
||||
|
||||
#define CONFIG_CPU_NOP "nop"
|
||||
#define CONFIG_CLOCK_FREQUENCY 100000000
|
||||
|
||||
/* 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
59
soc.vhdl
59
soc.vhdl
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user