mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-05-04 15:26:12 +00:00
This comes in two parts: - A generator script which uses LiteX to generate litedram cores along with their init files for various boards (currently Arty and Nexys-video). This comes with configs for arty and nexys_video. - A fusesoc "generator" which uses pre-generated litedram cores The generation process is manual on purpose. This include pre-generated cores for the two above boards. This is done so that one doesn't have to install LiteX to build microwatt. In addition, the generator script or wrapper vhdl tend to break when LiteX changes significantly which happens. This is still rather standalone and hasn't been plumbed into the SoC or the FPGA toplevel files yet. At this point LiteDRAM self-initializes using a built-in VexRiscv "Minimum" core obtained from LiteX and included in this commit. There is some plumbing to generate and cores that are initialized by Microwatt directly but this isn't working yet and so isn't enabled yet. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
215 lines
7.4 KiB
VHDL
215 lines
7.4 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
use std.textio.all;
|
|
|
|
library work;
|
|
use work.wishbone_types.all;
|
|
use work.sim_console.all;
|
|
|
|
entity litedram_wrapper is
|
|
generic (
|
|
DRAM_ABITS : positive;
|
|
DRAM_ALINES : positive
|
|
);
|
|
port(
|
|
-- LiteDRAM generates the system clock and reset
|
|
-- from the input clkin
|
|
clk_in : in std_ulogic;
|
|
rst : in std_ulogic;
|
|
system_clk : out std_ulogic;
|
|
system_reset : out std_ulogic;
|
|
core_alt_reset : out std_ulogic;
|
|
pll_locked : out std_ulogic;
|
|
|
|
-- Wishbone ports:
|
|
wb_in : in wishbone_master_out;
|
|
wb_out : out wishbone_slave_out;
|
|
wb_is_csr : in std_ulogic;
|
|
wb_is_init : in std_ulogic;
|
|
|
|
-- Init core serial debug
|
|
serial_tx : out std_ulogic;
|
|
serial_rx : in std_ulogic;
|
|
|
|
-- Misc
|
|
init_done : out std_ulogic;
|
|
init_error : out std_ulogic;
|
|
|
|
-- DRAM wires
|
|
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
|
|
);
|
|
end entity litedram_wrapper;
|
|
|
|
architecture behaviour of litedram_wrapper is
|
|
|
|
component litedram_core port (
|
|
clk : in std_ulogic;
|
|
rst : in std_ulogic;
|
|
serial_tx : out std_ulogic;
|
|
serial_rx : 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;
|
|
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;
|
|
user_port_native_0_cmd_addr : in std_ulogic_vector(DRAM_ABITS-1 downto 0);
|
|
user_port_native_0_wdata_valid : in std_ulogic;
|
|
user_port_native_0_wdata_ready : out std_ulogic;
|
|
user_port_native_0_wdata_we : in std_ulogic_vector(15 downto 0);
|
|
user_port_native_0_wdata_data : in std_ulogic_vector(127 downto 0);
|
|
user_port_native_0_rdata_valid : out std_ulogic;
|
|
user_port_native_0_rdata_ready : in std_ulogic;
|
|
user_port_native_0_rdata_data : out std_ulogic_vector(127 downto 0)
|
|
);
|
|
end component;
|
|
|
|
signal user_port0_cmd_valid : std_ulogic;
|
|
signal user_port0_cmd_ready : std_ulogic;
|
|
signal user_port0_cmd_we : std_ulogic;
|
|
signal user_port0_cmd_addr : std_ulogic_vector(DRAM_ABITS-1 downto 0);
|
|
signal user_port0_wdata_valid : std_ulogic;
|
|
signal user_port0_wdata_ready : std_ulogic;
|
|
signal user_port0_wdata_we : std_ulogic_vector(15 downto 0);
|
|
signal user_port0_wdata_data : std_ulogic_vector(127 downto 0);
|
|
signal user_port0_rdata_valid : std_ulogic;
|
|
signal user_port0_rdata_ready : std_ulogic;
|
|
signal user_port0_rdata_data : std_ulogic_vector(127 downto 0);
|
|
|
|
signal ad3 : std_ulogic;
|
|
|
|
signal dram_user_reset : std_ulogic;
|
|
|
|
type state_t is (CMD, MWRITE, MREAD);
|
|
signal state : state_t;
|
|
|
|
begin
|
|
|
|
-- Address bit 3 selects the top or bottom half of the data
|
|
-- bus (64-bit wishbone vs. 128-bit DRAM interface)
|
|
--
|
|
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)
|
|
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';
|
|
user_port0_rdata_ready <= '1' when state = MREAD else '0';
|
|
user_port0_cmd_addr <= wb_in.adr(DRAM_ABITS+3 downto 4);
|
|
user_port0_wdata_data <= wb_in.dat & wb_in.dat;
|
|
user_port0_wdata_we <= wb_in.sel & "00000000" when ad3 = '1' else
|
|
"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
|
|
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
|
|
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;
|
|
|
|
-- Reset, lift it when init done, no alt core reset
|
|
system_reset <= dram_user_reset or not init_done;
|
|
core_alt_reset <= '0';
|
|
|
|
-- State machine
|
|
sm: process(system_clk)
|
|
begin
|
|
|
|
if rising_edge(system_clk) then
|
|
if dram_user_reset = '1' then
|
|
state <= CMD;
|
|
else
|
|
case state is
|
|
when CMD =>
|
|
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 =>
|
|
if user_port0_wdata_ready = '1' then
|
|
state <= CMD;
|
|
end if;
|
|
when MREAD =>
|
|
if user_port0_rdata_valid = '1' then
|
|
state <= CMD;
|
|
end if;
|
|
end case;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
litedram: litedram_core
|
|
port map(
|
|
clk => clk_in,
|
|
rst => rst,
|
|
serial_tx => serial_tx,
|
|
serial_rx => serial_rx,
|
|
pll_locked => pll_locked,
|
|
ddram_a => ddram_a,
|
|
ddram_ba => ddram_ba,
|
|
ddram_ras_n => ddram_ras_n,
|
|
ddram_cas_n => ddram_cas_n,
|
|
ddram_we_n => ddram_we_n,
|
|
ddram_cs_n => ddram_cs_n,
|
|
ddram_dm => ddram_dm,
|
|
ddram_dq => ddram_dq,
|
|
ddram_dqs_p => ddram_dqs_p,
|
|
ddram_dqs_n => ddram_dqs_n,
|
|
ddram_clk_p => ddram_clk_p,
|
|
ddram_clk_n => ddram_clk_n,
|
|
ddram_cke => ddram_cke,
|
|
ddram_odt => ddram_odt,
|
|
ddram_reset_n => ddram_reset_n,
|
|
init_done => init_done,
|
|
init_error => init_error,
|
|
user_clk => system_clk,
|
|
user_rst => dram_user_reset,
|
|
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,
|
|
user_port_native_0_cmd_addr => user_port0_cmd_addr,
|
|
user_port_native_0_wdata_valid => user_port0_wdata_valid,
|
|
user_port_native_0_wdata_ready => user_port0_wdata_ready,
|
|
user_port_native_0_wdata_we => user_port0_wdata_we,
|
|
user_port_native_0_wdata_data => user_port0_wdata_data,
|
|
user_port_native_0_rdata_valid => user_port0_rdata_valid,
|
|
user_port_native_0_rdata_ready => user_port0_rdata_ready,
|
|
user_port_native_0_rdata_data => user_port0_rdata_data
|
|
);
|
|
|
|
end architecture behaviour;
|