commit
fcec66acf4
@ -0,0 +1,246 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
library unisim;
|
||||||
|
use unisim.vcomponents.all;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.wishbone_types.all;
|
||||||
|
|
||||||
|
entity toplevel is
|
||||||
|
generic (
|
||||||
|
MEMORY_SIZE : positive := 16384;
|
||||||
|
RAM_INIT_FILE : string := "firmware.hex";
|
||||||
|
RESET_LOW : boolean := true;
|
||||||
|
CLK_FREQUENCY : positive := 100000000;
|
||||||
|
USE_LITEDRAM : boolean := false;
|
||||||
|
DISABLE_FLATTEN_CORE : boolean := false
|
||||||
|
);
|
||||||
|
port(
|
||||||
|
ext_clk : in std_ulogic;
|
||||||
|
ext_rst : in std_ulogic;
|
||||||
|
|
||||||
|
-- UART0 signals:
|
||||||
|
uart_main_tx : out std_ulogic;
|
||||||
|
uart_main_rx : in std_ulogic;
|
||||||
|
|
||||||
|
-- DRAM UART signals (PMOD)
|
||||||
|
uart_pmod_tx : out std_ulogic;
|
||||||
|
uart_pmod_rx : in std_ulogic;
|
||||||
|
uart_pmod_cts_n : in std_ulogic;
|
||||||
|
uart_pmod_rts_n : out std_ulogic;
|
||||||
|
|
||||||
|
-- LEDs
|
||||||
|
led0_b : out std_ulogic;
|
||||||
|
led0_g : out std_ulogic;
|
||||||
|
led0_r : out std_ulogic;
|
||||||
|
|
||||||
|
-- DRAM wires
|
||||||
|
ddram_a : out std_ulogic_vector(13 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 toplevel;
|
||||||
|
|
||||||
|
architecture behaviour of toplevel is
|
||||||
|
|
||||||
|
-- Reset signals:
|
||||||
|
signal soc_rst : std_ulogic;
|
||||||
|
signal pll_rst : std_ulogic;
|
||||||
|
|
||||||
|
-- Internal clock signals:
|
||||||
|
signal system_clk : std_ulogic;
|
||||||
|
signal system_clk_locked : std_ulogic;
|
||||||
|
|
||||||
|
-- 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_init : std_ulogic;
|
||||||
|
|
||||||
|
-- Control/status
|
||||||
|
signal core_alt_reset : std_ulogic;
|
||||||
|
|
||||||
|
-- Status LED
|
||||||
|
signal led0_b_pwm : std_ulogic;
|
||||||
|
signal led0_r_pwm : std_ulogic;
|
||||||
|
signal led0_g_pwm : std_ulogic;
|
||||||
|
|
||||||
|
-- Dumb PWM for the LEDs, those RGB LEDs are too bright otherwise
|
||||||
|
signal pwm_counter : std_ulogic_vector(8 downto 0);
|
||||||
|
begin
|
||||||
|
|
||||||
|
uart_pmod_rts_n <= '0';
|
||||||
|
|
||||||
|
-- Main SoC
|
||||||
|
soc0: entity work.soc
|
||||||
|
generic map(
|
||||||
|
MEMORY_SIZE => MEMORY_SIZE,
|
||||||
|
RAM_INIT_FILE => RAM_INIT_FILE,
|
||||||
|
RESET_LOW => RESET_LOW,
|
||||||
|
SIM => false,
|
||||||
|
CLK_FREQ => CLK_FREQUENCY,
|
||||||
|
HAS_DRAM => USE_LITEDRAM,
|
||||||
|
DRAM_SIZE => 256 * 1024 * 1024,
|
||||||
|
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE
|
||||||
|
)
|
||||||
|
port map (
|
||||||
|
system_clk => system_clk,
|
||||||
|
rst => soc_rst,
|
||||||
|
uart0_txd => uart_main_tx,
|
||||||
|
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_init => wb_dram_init,
|
||||||
|
alt_reset => core_alt_reset
|
||||||
|
);
|
||||||
|
|
||||||
|
nodram: if not USE_LITEDRAM generate
|
||||||
|
signal ddram_clk_dummy : std_ulogic;
|
||||||
|
begin
|
||||||
|
reset_controller: entity work.soc_reset
|
||||||
|
generic map(
|
||||||
|
RESET_LOW => RESET_LOW
|
||||||
|
)
|
||||||
|
port map(
|
||||||
|
ext_clk => ext_clk,
|
||||||
|
pll_clk => system_clk,
|
||||||
|
pll_locked_in => system_clk_locked,
|
||||||
|
ext_rst_in => ext_rst,
|
||||||
|
pll_rst_out => pll_rst,
|
||||||
|
rst_out => soc_rst
|
||||||
|
);
|
||||||
|
|
||||||
|
clkgen: entity work.clock_generator
|
||||||
|
generic map(
|
||||||
|
CLK_INPUT_HZ => 100000000,
|
||||||
|
CLK_OUTPUT_HZ => CLK_FREQUENCY
|
||||||
|
)
|
||||||
|
port map(
|
||||||
|
ext_clk => ext_clk,
|
||||||
|
pll_rst_in => pll_rst,
|
||||||
|
pll_clk_out => system_clk,
|
||||||
|
pll_locked_out => system_clk_locked
|
||||||
|
);
|
||||||
|
|
||||||
|
led0_b_pwm <= '1';
|
||||||
|
led0_r_pwm <= '1';
|
||||||
|
led0_g_pwm <= '0';
|
||||||
|
core_alt_reset <= '0';
|
||||||
|
|
||||||
|
-- Vivado barfs on those differential signals if left
|
||||||
|
-- unconnected. So instanciate a diff. buffer and feed
|
||||||
|
-- it a constant '0'.
|
||||||
|
dummy_dram_clk: OBUFDS
|
||||||
|
port map (
|
||||||
|
O => ddram_clk_p,
|
||||||
|
OB => ddram_clk_n,
|
||||||
|
I => ddram_clk_dummy
|
||||||
|
);
|
||||||
|
ddram_clk_dummy <= '0';
|
||||||
|
|
||||||
|
end generate;
|
||||||
|
|
||||||
|
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;
|
||||||
|
begin
|
||||||
|
|
||||||
|
-- Eventually dig out the frequency from the generator
|
||||||
|
-- but for now, assert it's 100Mhz
|
||||||
|
assert CLK_FREQUENCY = 100000000;
|
||||||
|
|
||||||
|
reset_controller: entity work.soc_reset
|
||||||
|
generic map(
|
||||||
|
RESET_LOW => RESET_LOW
|
||||||
|
)
|
||||||
|
port map(
|
||||||
|
ext_clk => ext_clk,
|
||||||
|
pll_clk => system_clk,
|
||||||
|
pll_locked_in => system_clk_locked,
|
||||||
|
ext_rst_in => ext_rst,
|
||||||
|
pll_rst_out => pll_rst,
|
||||||
|
rst_out => soc_rst_0
|
||||||
|
);
|
||||||
|
|
||||||
|
dram: entity work.litedram_wrapper
|
||||||
|
generic map(
|
||||||
|
DRAM_ABITS => 24,
|
||||||
|
DRAM_ALINES => 14
|
||||||
|
)
|
||||||
|
port map(
|
||||||
|
clk_in => ext_clk,
|
||||||
|
rst => pll_rst,
|
||||||
|
system_clk => system_clk,
|
||||||
|
system_reset => soc_rst_1,
|
||||||
|
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_init => wb_dram_init,
|
||||||
|
|
||||||
|
serial_tx => uart_pmod_tx,
|
||||||
|
serial_rx => uart_pmod_rx,
|
||||||
|
|
||||||
|
init_done => dram_init_done,
|
||||||
|
init_error => dram_init_error,
|
||||||
|
|
||||||
|
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
|
||||||
|
);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
leds_pwm : process(system_clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(system_clk) then
|
||||||
|
pwm_counter <= std_ulogic_vector(signed(pwm_counter) + 1);
|
||||||
|
if pwm_counter(8 downto 4) = "00000" then
|
||||||
|
led0_b <= led0_b_pwm;
|
||||||
|
led0_r <= led0_r_pwm;
|
||||||
|
led0_g <= led0_g_pwm;
|
||||||
|
else
|
||||||
|
led0_b <= '0';
|
||||||
|
led0_r <= '0';
|
||||||
|
led0_g <= '0';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end architecture behaviour;
|
@ -0,0 +1,209 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
library unisim;
|
||||||
|
use unisim.vcomponents.all;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.wishbone_types.all;
|
||||||
|
|
||||||
|
entity toplevel is
|
||||||
|
generic (
|
||||||
|
MEMORY_SIZE : positive := 16384;
|
||||||
|
RAM_INIT_FILE : string := "firmware.hex";
|
||||||
|
RESET_LOW : boolean := true;
|
||||||
|
CLK_FREQUENCY : positive := 100000000;
|
||||||
|
USE_LITEDRAM : boolean := false;
|
||||||
|
DISABLE_FLATTEN_CORE : boolean := false
|
||||||
|
);
|
||||||
|
port(
|
||||||
|
ext_clk : in std_ulogic;
|
||||||
|
ext_rst : in std_ulogic;
|
||||||
|
|
||||||
|
-- UART0 signals:
|
||||||
|
uart_main_tx : out std_ulogic;
|
||||||
|
uart_main_rx : in std_ulogic;
|
||||||
|
|
||||||
|
-- LEDs
|
||||||
|
led0 : out std_logic;
|
||||||
|
led1 : out std_logic;
|
||||||
|
|
||||||
|
-- DRAM wires
|
||||||
|
ddram_a : out std_logic_vector(14 downto 0);
|
||||||
|
ddram_ba : out std_logic_vector(2 downto 0);
|
||||||
|
ddram_ras_n : out std_logic;
|
||||||
|
ddram_cas_n : out std_logic;
|
||||||
|
ddram_we_n : out std_logic;
|
||||||
|
ddram_dm : out std_logic_vector(1 downto 0);
|
||||||
|
ddram_dq : inout std_logic_vector(15 downto 0);
|
||||||
|
ddram_dqs_p : inout std_logic_vector(1 downto 0);
|
||||||
|
ddram_dqs_n : inout std_logic_vector(1 downto 0);
|
||||||
|
ddram_clk_p : out std_logic;
|
||||||
|
ddram_clk_n : out std_logic;
|
||||||
|
ddram_cke : out std_logic;
|
||||||
|
ddram_odt : out std_logic;
|
||||||
|
ddram_reset_n : out std_logic
|
||||||
|
);
|
||||||
|
end entity toplevel;
|
||||||
|
|
||||||
|
architecture behaviour of toplevel is
|
||||||
|
|
||||||
|
-- Reset signals:
|
||||||
|
signal soc_rst : std_ulogic;
|
||||||
|
signal pll_rst : std_ulogic;
|
||||||
|
|
||||||
|
-- Internal clock signals:
|
||||||
|
signal system_clk : std_ulogic;
|
||||||
|
signal system_clk_locked : std_ulogic;
|
||||||
|
|
||||||
|
-- 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_init : std_ulogic;
|
||||||
|
|
||||||
|
-- Control/status
|
||||||
|
signal core_alt_reset : std_ulogic;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
-- Main SoC
|
||||||
|
soc0: entity work.soc
|
||||||
|
generic map(
|
||||||
|
MEMORY_SIZE => MEMORY_SIZE,
|
||||||
|
RAM_INIT_FILE => RAM_INIT_FILE,
|
||||||
|
RESET_LOW => RESET_LOW,
|
||||||
|
SIM => false,
|
||||||
|
CLK_FREQ => CLK_FREQUENCY,
|
||||||
|
HAS_DRAM => USE_LITEDRAM,
|
||||||
|
DRAM_SIZE => 512 * 1024 * 1024,
|
||||||
|
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE
|
||||||
|
)
|
||||||
|
port map (
|
||||||
|
system_clk => system_clk,
|
||||||
|
rst => soc_rst,
|
||||||
|
uart0_txd => uart_main_tx,
|
||||||
|
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_init => wb_dram_init,
|
||||||
|
alt_reset => core_alt_reset
|
||||||
|
);
|
||||||
|
|
||||||
|
nodram: if not USE_LITEDRAM generate
|
||||||
|
signal ddram_clk_dummy : std_ulogic;
|
||||||
|
begin
|
||||||
|
reset_controller: entity work.soc_reset
|
||||||
|
generic map(
|
||||||
|
RESET_LOW => RESET_LOW
|
||||||
|
)
|
||||||
|
port map(
|
||||||
|
ext_clk => ext_clk,
|
||||||
|
pll_clk => system_clk,
|
||||||
|
pll_locked_in => system_clk_locked,
|
||||||
|
ext_rst_in => ext_rst,
|
||||||
|
pll_rst_out => pll_rst,
|
||||||
|
rst_out => soc_rst
|
||||||
|
);
|
||||||
|
|
||||||
|
clkgen: entity work.clock_generator
|
||||||
|
generic map(
|
||||||
|
CLK_INPUT_HZ => 100000000,
|
||||||
|
CLK_OUTPUT_HZ => CLK_FREQUENCY
|
||||||
|
)
|
||||||
|
port map(
|
||||||
|
ext_clk => ext_clk,
|
||||||
|
pll_rst_in => pll_rst,
|
||||||
|
pll_clk_out => system_clk,
|
||||||
|
pll_locked_out => system_clk_locked
|
||||||
|
);
|
||||||
|
|
||||||
|
led0 <= '1';
|
||||||
|
led1 <= not soc_rst;
|
||||||
|
core_alt_reset <= '0';
|
||||||
|
|
||||||
|
-- Vivado barfs on those differential signals if left
|
||||||
|
-- unconnected. So instanciate a diff. buffer and feed
|
||||||
|
-- it a constant '0'.
|
||||||
|
dummy_dram_clk: OBUFDS
|
||||||
|
port map (
|
||||||
|
O => ddram_clk_p,
|
||||||
|
OB => ddram_clk_n,
|
||||||
|
I => ddram_clk_dummy
|
||||||
|
);
|
||||||
|
ddram_clk_dummy <= '0';
|
||||||
|
|
||||||
|
end generate;
|
||||||
|
|
||||||
|
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;
|
||||||
|
begin
|
||||||
|
|
||||||
|
-- Eventually dig out the frequency from the generator
|
||||||
|
-- but for now, assert it's 100Mhz
|
||||||
|
assert CLK_FREQUENCY = 100000000;
|
||||||
|
|
||||||
|
reset_controller: entity work.soc_reset
|
||||||
|
generic map(
|
||||||
|
RESET_LOW => RESET_LOW
|
||||||
|
)
|
||||||
|
port map(
|
||||||
|
ext_clk => ext_clk,
|
||||||
|
pll_clk => system_clk,
|
||||||
|
pll_locked_in => system_clk_locked,
|
||||||
|
ext_rst_in => ext_rst,
|
||||||
|
pll_rst_out => pll_rst,
|
||||||
|
rst_out => soc_rst_0
|
||||||
|
);
|
||||||
|
|
||||||
|
dram: entity work.litedram_wrapper
|
||||||
|
generic map(
|
||||||
|
DRAM_ABITS => 25,
|
||||||
|
DRAM_ALINES => 15
|
||||||
|
)
|
||||||
|
port map(
|
||||||
|
clk_in => ext_clk,
|
||||||
|
rst => pll_rst,
|
||||||
|
system_clk => system_clk,
|
||||||
|
system_reset => soc_rst_1,
|
||||||
|
pll_locked => system_clk_locked,
|
||||||
|
|
||||||
|
wb_in => wb_dram_in,
|
||||||
|
wb_out => wb_dram_out,
|
||||||
|
wb_is_csr => wb_dram_csr,
|
||||||
|
wb_is_init => wb_dram_init,
|
||||||
|
|
||||||
|
serial_tx => open,
|
||||||
|
serial_rx => '0',
|
||||||
|
|
||||||
|
init_done => dram_init_done,
|
||||||
|
init_error => dram_init_error,
|
||||||
|
|
||||||
|
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 => open,
|
||||||
|
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
|
||||||
|
);
|
||||||
|
|
||||||
|
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;
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,53 @@
|
|||||||
|
#ifndef __IO_H
|
||||||
|
#define __IO_H
|
||||||
|
|
||||||
|
static inline uint8_t readb(unsigned long addr)
|
||||||
|
{
|
||||||
|
uint8_t val;
|
||||||
|
__asm__ volatile("sync; lbzcix %0,0,%1" : "=r" (val) : "r" (addr) : "memory");
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t readw(unsigned long addr)
|
||||||
|
{
|
||||||
|
uint16_t val;
|
||||||
|
__asm__ volatile("sync; lhzcix %0,0,%1" : "=r" (val) : "r" (addr) : "memory");
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t readl(unsigned long addr)
|
||||||
|
{
|
||||||
|
uint32_t val;
|
||||||
|
__asm__ volatile("sync; lwzcix %0,0,%1" : "=r" (val) : "r" (addr) : "memory");
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t readq(unsigned long addr)
|
||||||
|
{
|
||||||
|
uint64_t val;
|
||||||
|
__asm__ volatile("sync; ldcix %0,0,%1" : "=r" (val) : "r" (addr) : "memory");
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void writeb(uint8_t val, unsigned long addr)
|
||||||
|
{
|
||||||
|
__asm__ volatile("sync; stbcix %0,0,%1" : : "r" (val), "r" (addr) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void writew(uint16_t val, unsigned long addr)
|
||||||
|
{
|
||||||
|
__asm__ volatile("sync; sthcix %0,0,%1" : : "r" (val), "r" (addr) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void writel(uint32_t val, unsigned long addr)
|
||||||
|
{
|
||||||
|
__asm__ volatile("sync; stwcix %0,0,%1" : : "r" (val), "r" (addr) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void writeq(uint64_t val, unsigned long addr)
|
||||||
|
{
|
||||||
|
__asm__ volatile("sync; stdcix %0,0,%1" : : "r" (val), "r" (addr) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __IO_H */
|
||||||
|
|
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef __MICROWATT_SOC_H
|
||||||
|
#define __MICROWATT_SOC_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Definitions for the syscon registers
|
||||||
|
*/
|
||||||
|
#define SYSCON_BASE 0xc0000000
|
||||||
|
|
||||||
|
#define SYS_REG_SIGNATURE 0x00
|
||||||
|
#define SYS_REG_INFO 0x08
|
||||||
|
#define SYS_REG_INFO_HAS_UART (1ull << 0)
|
||||||
|
#define SYS_REG_INFO_HAS_DRAM (1ull << 1)
|
||||||
|
#define SYS_REG_BRAMINFO 0x10
|
||||||
|
#define SYS_REG_DRAMINFO 0x18
|
||||||
|
#define SYS_REG_CLKINFO 0x20
|
||||||
|
#define SYS_REG_CTRL 0x28
|
||||||
|
#define SYS_REG_CTRL_DRAM_AT_0 (1ull << 0)
|
||||||
|
#define SYS_REG_CTRL_CORE_RESET (1ull << 1)
|
||||||
|
#define SYS_REG_CTRL_SOC_RESET (1ull << 2)
|
||||||
|
|
||||||
|
/* Definition for the "Potato" UART */
|
||||||
|
#define UART_BASE 0xc0002000
|
||||||
|
|
||||||
|
#define POTATO_CONSOLE_TX 0x00
|
||||||
|
#define POTATO_CONSOLE_RX 0x08
|
||||||
|
#define POTATO_CONSOLE_STATUS 0x10
|
||||||
|
#define POTATO_CONSOLE_STATUS_RX_EMPTY 0x01
|
||||||
|
#define POTATO_CONSOLE_STATUS_TX_EMPTY 0x02
|
||||||
|
#define POTATO_CONSOLE_STATUS_RX_FULL 0x04
|
||||||
|
#define POTATO_CONSOLE_STATUS_TX_FULL 0x08
|
||||||
|
#define POTATO_CONSOLE_CLOCK_DIV 0x18
|
||||||
|
#define POTATO_CONSOLE_IRQ_EN 0x20
|
||||||
|
|
||||||
|
#endif /* __MICROWATT_SOC_H */
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
from fusesoc.capi2.generator import Generator
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
class LiteDRAMGenerator(Generator):
|
||||||
|
def run(self):
|
||||||
|
board = self.config.get('board')
|
||||||
|
|
||||||
|
# Collect a bunch of directory path
|
||||||
|
script_dir = os.path.dirname(sys.argv[0])
|
||||||
|
base_dir = os.path.join(script_dir, os.pardir)
|
||||||
|
gen_dir = os.path.join(base_dir, "generated", board)
|
||||||
|
extras_dir = os.path.join(base_dir, "extras")
|
||||||
|
|
||||||
|
print("Adding LiteDRAM for board... ", board)
|
||||||
|
|
||||||
|
# Grab init-cpu.txt if it exists
|
||||||
|
cpu_file = os.path.join(gen_dir, "init-cpu.txt")
|
||||||
|
if os.path.exists(cpu_file):
|
||||||
|
cpu = pathlib.Path(cpu_file).read_text()
|
||||||
|
else:
|
||||||
|
cpu = None
|
||||||
|
|
||||||
|
# Add files to fusesoc
|
||||||
|
files = []
|
||||||
|
f = os.path.join(gen_dir, "litedram_core.v")
|
||||||
|
files.append({f : {'file_type' : 'verilogSource'}})
|
||||||
|
f = os.path.join(gen_dir, "litedram-wrapper.vhdl")
|
||||||
|
files.append({f : {'file_type' : 'vhdlSource-2008'}})
|
||||||
|
f = os.path.join(gen_dir, "litedram_core.init")
|
||||||
|
files.append({f : {'file_type' : 'user'}})
|
||||||
|
|
||||||
|
# Look for init CPU types and add corresponding files
|
||||||
|
if cpu == "vexriscv":
|
||||||
|
f = os.path.join(base_dir, "extras", "VexRiscv.v")
|
||||||
|
files.append({f : {'file_type' : 'verilogSource'}})
|
||||||
|
|
||||||
|
self.add_files(files)
|
||||||
|
|
||||||
|
g = LiteDRAMGenerator()
|
||||||
|
g.run()
|
||||||
|
g.write()
|
||||||
|
|
@ -0,0 +1,43 @@
|
|||||||
|
# This file is Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
|
# License: BSD
|
||||||
|
|
||||||
|
{
|
||||||
|
# General ------------------------------------------------------------------
|
||||||
|
"cpu": "vexriscv", # Type of CPU used for init/calib (vexriscv, lm32)
|
||||||
|
"cpu_variant":"minimal",
|
||||||
|
"speedgrade": -1, # FPGA speedgrade
|
||||||
|
"memtype": "DDR3", # DRAM type
|
||||||
|
|
||||||
|
# PHY ----------------------------------------------------------------------
|
||||||
|
"cmd_delay": 0, # Command additional delay (in taps)
|
||||||
|
"cmd_latency": 0, # Command additional latency
|
||||||
|
"sdram_module": "MT41K128M16", # SDRAM modules of the board or SO-DIMM
|
||||||
|
"sdram_module_nb": 2, # Number of byte groups
|
||||||
|
"sdram_rank_nb": 1, # Number of ranks
|
||||||
|
"sdram_phy": "A7DDRPHY", # Type of FPGA PHY
|
||||||
|
|
||||||
|
# Electrical ---------------------------------------------------------------
|
||||||
|
"rtt_nom": "60ohm", # Nominal termination
|
||||||
|
"rtt_wr": "60ohm", # Write termination
|
||||||
|
"ron": "34ohm", # Output driver impedance
|
||||||
|
|
||||||
|
# Frequency ----------------------------------------------------------------
|
||||||
|
"input_clk_freq": 100e6, # Input clock frequency
|
||||||
|
"sys_clk_freq": 100e6, # System clock frequency (DDR_clk = 4 x sys_clk)
|
||||||
|
"iodelay_clk_freq": 200e6, # IODELAYs reference clock frequency
|
||||||
|
|
||||||
|
# Core ---------------------------------------------------------------------
|
||||||
|
"cmd_buffer_depth": 16, # Depth of the command buffer
|
||||||
|
|
||||||
|
# User Ports ---------------------------------------------------------------
|
||||||
|
"user_ports": {
|
||||||
|
"native_0": {
|
||||||
|
"type": "native",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
# CSR Port -----------------------------------------------------------------
|
||||||
|
"csr_expose": "False", # expose access to CSR (I/O) ports
|
||||||
|
"csr_align" : 32, # CSR alignment
|
||||||
|
"csr_base" : 0xc0100000 # For cpu=None only
|
||||||
|
}
|
@ -0,0 +1,157 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
from fusesoc.capi2.generator import Generator
|
||||||
|
from litex.build.tools import write_to_file
|
||||||
|
from litex.build.tools import replace_in_file
|
||||||
|
from litex.build.generic_platform import *
|
||||||
|
from litex.build.xilinx import XilinxPlatform
|
||||||
|
from litex.build.lattice import LatticePlatform
|
||||||
|
from litex.soc.integration.builder import *
|
||||||
|
from litedram.gen import *
|
||||||
|
import subprocess
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import yaml
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
def make_new_dir(base, added):
|
||||||
|
r = os.path.join(base, added)
|
||||||
|
if os.path.exists(r):
|
||||||
|
shutil.rmtree(r)
|
||||||
|
os.mkdir(r)
|
||||||
|
return r
|
||||||
|
|
||||||
|
gen_src_dir = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
base_dir = os.path.join(gen_src_dir, os.pardir)
|
||||||
|
build_top_dir = make_new_dir(base_dir, "build")
|
||||||
|
gen_src_dir = os.path.join(base_dir, "gen-src")
|
||||||
|
gen_dir = make_new_dir(base_dir, "generated")
|
||||||
|
|
||||||
|
# Build the init code for microwatt-initialized DRAM
|
||||||
|
#
|
||||||
|
# XXX Not working yet
|
||||||
|
#
|
||||||
|
def build_init_code(build_dir):
|
||||||
|
|
||||||
|
# More path fudging
|
||||||
|
sw_dir = os.path.join(build_dir, "software");
|
||||||
|
sw_inc_dir = os.path.join(sw_dir, "include")
|
||||||
|
gen_inc_dir = os.path.join(sw_inc_dir, "generated")
|
||||||
|
src_dir = os.path.join(gen_src_dir, "sdram_init")
|
||||||
|
lxbios_src_dir = os.path.join(soc_directory, "software", "bios")
|
||||||
|
lxbios_inc_dir = os.path.join(soc_directory, "software", "include")
|
||||||
|
print(" sw dir:", sw_dir)
|
||||||
|
print("gen_inc_dir:", gen_inc_dir)
|
||||||
|
print(" src dir:", src_dir)
|
||||||
|
print(" lx src dir:", lxbios_src_dir)
|
||||||
|
print(" lx inc dir:", lxbios_inc_dir)
|
||||||
|
|
||||||
|
# Generate mem.h
|
||||||
|
mem_h = "#define MAIN_RAM_BASE 0x40000000"
|
||||||
|
write_to_file(os.path.join(gen_inc_dir, "mem.h"), mem_h)
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
env_vars = []
|
||||||
|
def _makefile_escape(s): # From LiteX
|
||||||
|
return s.replace("\\", "\\\\")
|
||||||
|
def add_var(k, v):
|
||||||
|
env_vars.append("{}={}\n".format(k, _makefile_escape(v)))
|
||||||
|
|
||||||
|
add_var("BUILD_DIR", sw_dir)
|
||||||
|
add_var("SRC_DIR", src_dir)
|
||||||
|
add_var("GENINC_DIR", sw_inc_dir)
|
||||||
|
add_var("LXSRC_DIR", lxbios_src_dir)
|
||||||
|
add_var("LXINC_DIR", lxbios_inc_dir)
|
||||||
|
write_to_file(os.path.join(gen_inc_dir, "variables.mak"), "".join(env_vars))
|
||||||
|
|
||||||
|
# Build init code
|
||||||
|
print(" Generating init software...")
|
||||||
|
makefile = os.path.join(src_dir, "Makefile")
|
||||||
|
r = subprocess.check_call(["make", "-C", build_dir, "-I", gen_inc_dir, "-f", makefile])
|
||||||
|
print("Make result:", r)
|
||||||
|
|
||||||
|
return os.path.join(sw_dir, "obj", "sdram_init.hex")
|
||||||
|
|
||||||
|
def generate_one(t, mw_init):
|
||||||
|
|
||||||
|
print("Generating target:", t)
|
||||||
|
|
||||||
|
# Muck with directory path
|
||||||
|
build_dir = make_new_dir(build_top_dir, t)
|
||||||
|
t_dir = make_new_dir(gen_dir, t)
|
||||||
|
|
||||||
|
# Grab config file
|
||||||
|
cfile = os.path.join(gen_src_dir, t + ".yml")
|
||||||
|
core_config = yaml.load(open(cfile).read(), Loader=yaml.Loader)
|
||||||
|
|
||||||
|
### TODO: Make most stuff below a function in litedram gen.py and
|
||||||
|
### call it rather than duplicate it
|
||||||
|
###
|
||||||
|
|
||||||
|
# Convert YAML elements to Python/LiteX
|
||||||
|
for k, v in core_config.items():
|
||||||
|
replaces = {"False": False, "True": True, "None": None}
|
||||||
|
for r in replaces.keys():
|
||||||
|
if v == r:
|
||||||
|
core_config[k] = replaces[r]
|
||||||
|
if "clk_freq" in k:
|
||||||
|
core_config[k] = float(core_config[k])
|
||||||
|
if k == "sdram_module":
|
||||||
|
core_config[k] = getattr(litedram_modules, core_config[k])
|
||||||
|
if k == "sdram_phy":
|
||||||
|
core_config[k] = getattr(litedram_phys, core_config[k])
|
||||||
|
|
||||||
|
# Override values for mw_init
|
||||||
|
if mw_init:
|
||||||
|
core_config["cpu"] = None
|
||||||
|
core_config["csr_expose"] = True
|
||||||
|
core_config["csr_align"] = 64
|
||||||
|
|
||||||
|
# Generate core
|
||||||
|
if core_config["sdram_phy"] in [litedram_phys.ECP5DDRPHY]:
|
||||||
|
platform = LatticePlatform("LFE5UM5G-45F-8BG381C", io=[], toolchain="trellis")
|
||||||
|
elif core_config["sdram_phy"] in [litedram_phys.A7DDRPHY, litedram_phys.K7DDRPHY, litedram_phys.V7DDRPHY]:
|
||||||
|
platform = XilinxPlatform("", io=[], toolchain="vivado")
|
||||||
|
else:
|
||||||
|
raise ValueError("Unsupported SDRAM PHY: {}".format(core_config["sdram_phy"]))
|
||||||
|
|
||||||
|
soc = LiteDRAMCore(platform, core_config, integrated_rom_size=0x6000, csr_data_width=32)
|
||||||
|
|
||||||
|
# Build into build_dir
|
||||||
|
builder = Builder(soc, output_dir=build_dir, compile_gateware=False)
|
||||||
|
vns = builder.build(build_name="litedram_core", regular_comb=False)
|
||||||
|
|
||||||
|
# Grab generated gatewar dir
|
||||||
|
gw_dir = os.path.join(build_dir, "gateware")
|
||||||
|
|
||||||
|
# Generate init-cpu.txt if any and generate init code if none
|
||||||
|
cpu = core_config["cpu"]
|
||||||
|
if mw_init:
|
||||||
|
src_wrap_file = os.path.join(gen_src_dir, "wrapper-mw-init.vhdl")
|
||||||
|
src_init_file = build_init_code(build_dir)
|
||||||
|
else:
|
||||||
|
write_to_file(os.path.join(t_dir, "init-cpu.txt"), cpu)
|
||||||
|
src_wrap_file = os.path.join(gen_src_dir, "wrapper-self-init.vhdl")
|
||||||
|
src_init_file = os.path.join(gw_dir, "mem.init")
|
||||||
|
|
||||||
|
# Copy generated files to target dir, amend them if necessary
|
||||||
|
core_file = os.path.join(gw_dir, "litedram_core.v")
|
||||||
|
dst_init_file = os.path.join(t_dir, "litedram_core.init")
|
||||||
|
dst_wrap_file = os.path.join(t_dir, "litedram-wrapper.vhdl")
|
||||||
|
replace_in_file(core_file, "mem.init", "litedram_core.init")
|
||||||
|
shutil.copy(core_file, t_dir)
|
||||||
|
shutil.copyfile(src_init_file, dst_init_file)
|
||||||
|
shutil.copyfile(src_wrap_file, dst_wrap_file)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
|
||||||
|
targets = ['arty','nexys-video']
|
||||||
|
|
||||||
|
# XXX Set mw_init to False to use a local VexRiscV for memory inits
|
||||||
|
for t in targets:
|
||||||
|
generate_one(t, mw_init = True)
|
||||||
|
|
||||||
|
# XXX TODO: Remove build dir unless told not to via cmdline option
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@ -0,0 +1,42 @@
|
|||||||
|
# This file is Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
|
# License: BSD
|
||||||
|
|
||||||
|
{
|
||||||
|
# General ------------------------------------------------------------------
|
||||||
|
"cpu": "vexriscv", # Type of CPU used for init/calib (vexriscv, lm32)
|
||||||
|
"cpu_variant":"minimal",
|
||||||
|
"speedgrade": -1, # FPGA speedgrade
|
||||||
|
"memtype": "DDR3", # DRAM type
|
||||||
|
|
||||||
|
# PHY ----------------------------------------------------------------------
|
||||||
|
"cmd_delay": 0, # Command additional delay (in taps)
|
||||||
|
"cmd_latency": 0, # Command additional latency
|
||||||
|
"sdram_module": "MT41K256M16", # SDRAM modules of the board or SO-DIMM
|
||||||
|
"sdram_module_nb": 2, # Number of byte groups
|
||||||
|
"sdram_rank_nb": 1, # Number of ranks
|
||||||
|
"sdram_phy": "A7DDRPHY", # Type of FPGA PHY
|
||||||
|
|
||||||
|
# Electrical ---------------------------------------------------------------
|
||||||
|
"rtt_nom": "60ohm", # Nominal termination
|
||||||
|
"rtt_wr": "60ohm", # Write termination
|
||||||
|
"ron": "34ohm", # Output driver impedance
|
||||||
|
|
||||||
|
# Frequency ----------------------------------------------------------------
|
||||||
|
"input_clk_freq": 100e6, # Input clock frequency
|
||||||
|
"sys_clk_freq": 100e6, # System clock frequency (DDR_clk = 4 x sys_clk)
|
||||||
|
"iodelay_clk_freq": 200e6, # IODELAYs reference clock frequency
|
||||||
|
|
||||||
|
# Core ---------------------------------------------------------------------
|
||||||
|
"cmd_buffer_depth": 16, # Depth of the command buffer
|
||||||
|
|
||||||
|
# User Ports ---------------------------------------------------------------
|
||||||
|
"user_ports": {
|
||||||
|
"native_0": {
|
||||||
|
"type": "native",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
# CSR Port -----------------------------------------------------------------
|
||||||
|
"csr_expose": "False", # expose access to CSR (I/O) ports
|
||||||
|
"csr_align" : 32, # 64-bit alignment
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
#### Directories
|
||||||
|
|
||||||
|
include variables.mak
|
||||||
|
OBJ = $(BUILD_DIR)/obj
|
||||||
|
|
||||||
|
PROGRAM = sdram_init
|
||||||
|
OBJECTS = $(OBJ)/head.o $(OBJ)/main.o $(OBJ)/sdram.o
|
||||||
|
|
||||||
|
#### Compiler
|
||||||
|
|
||||||
|
ARCH = $(shell uname -m)
|
||||||
|
ifneq ("$(ARCH)", "ppc64")
|
||||||
|
ifneq ("$(ARCH)", "ppc64le")
|
||||||
|
CROSS_COMPILE = powerpc64le-linux-gnu-
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
CC = $(CROSS_COMPILE)gcc
|
||||||
|
LD = $(CROSS_COMPILE)ld
|
||||||
|
OBJCOPY = $(CROSS_COMPILE)objcopy
|
||||||
|
|
||||||
|
#### Flags
|
||||||
|
|
||||||
|
CPPFLAGS = -nostdinc
|
||||||
|
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
|
||||||
|
ASFLAGS = $(CPPFLAGS) $(CFLAGS)
|
||||||
|
LDFLAGS = -static -nostdlib -Ttext-segment=0xffff0000 -T $(SRC_DIR)/$(PROGRAM).lds --gc-sections
|
||||||
|
|
||||||
|
#### Pretty print
|
||||||
|
|
||||||
|
ifeq ($(V),1)
|
||||||
|
define Q
|
||||||
|
$(2)
|
||||||
|
endef
|
||||||
|
else
|
||||||
|
define Q
|
||||||
|
@echo " [$1] $(3)"
|
||||||
|
@$(2)
|
||||||
|
endef
|
||||||
|
endif
|
||||||
|
|
||||||
|
#### Rules. This is a bit crappy, I'm sure we can do better with the
|
||||||
|
#### handling of the various path, but this will have to do
|
||||||
|
#### until I can be bothered getting my head around the finer
|
||||||
|
#### points of Makefiles
|
||||||
|
|
||||||
|
all: objdir $(OBJ)/$(PROGRAM).hex
|
||||||
|
|
||||||
|
$(OBJ)/sdram.o: $(LXSRC_DIR)/sdram.c
|
||||||
|
$(call Q,CC, $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@, $@)
|
||||||
|
$(OBJ)/%.o : $(SRC_DIR)/%.S
|
||||||
|
$(call Q,AS, $(CC) $(ASFLAGS) -c $< -o $@, $@)
|
||||||
|
$(OBJ)/%.o : $(SRC_DIR)/%.c
|
||||||
|
$(call Q,CC, $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@, $@)
|
||||||
|
$(OBJ)/%.o : $(SRC_DIR)/libc/src/%.c
|
||||||
|
$(call Q,CC, $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@, $@)
|
||||||
|
|
||||||
|
LIBC_SRC := $(wildcard $(SRC_DIR)/libc/src/*.c)
|
||||||
|
LIBC_OBJ := $(patsubst $(SRC_DIR)/libc/src/%.c, $(OBJ)/%.o,$(LIBC_SRC))
|
||||||
|
$(OBJ)/libc.o: $(LIBC_OBJ)
|
||||||
|
$(call Q,LD, $(LD) -r -o $@ $^, $@)
|
||||||
|
|
||||||
|
$(OBJ)/$(PROGRAM).elf: $(OBJECTS) $(OBJ)/libc.o
|
||||||
|
$(call Q,LD, $(LD) $(LDFLAGS) -o $@ $^, $@)
|
||||||
|
|
||||||
|
$(OBJ)/$(PROGRAM).bin: $(OBJ)/$(PROGRAM).elf
|
||||||
|
$(call Q,OC, $(OBJCOPY) -O binary -S $^ $@, $@)
|
||||||
|
|
||||||
|
$(OBJ)/$(PROGRAM).hex: $(OBJ)/$(PROGRAM).bin
|
||||||
|
$(call Q,HX, $(SRC_DIR)/bin2hex.py $^ > $@, $@)
|
||||||
|
|
||||||
|
objdir:
|
||||||
|
@mkdir -p $(OBJ)
|
@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import struct
|
||||||
|
|
||||||
|
with open(sys.argv[1], "rb") as f:
|
||||||
|
while True:
|
||||||
|
word = f.read(8)
|
||||||
|
if len(word) == 8:
|
||||||
|
print("%016x" % struct.unpack('Q', word));
|
||||||
|
elif len(word) == 4:
|
||||||
|
print("00000000%08x" % struct.unpack('I', word));
|
||||||
|
elif len(word) == 0:
|
||||||
|
exit(0);
|
||||||
|
else:
|
||||||
|
raise Exception("Bad length")
|
@ -0,0 +1,102 @@
|
|||||||
|
/* Copyright 2013-2014 IBM Corp.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
* implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define STACK_TOP 0xffff4000
|
||||||
|
|
||||||
|
#define FIXUP_ENDIAN \
|
||||||
|
tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \
|
||||||
|
b 191f; /* Skip trampoline if endian is good */ \
|
||||||
|
.long 0xa600607d; /* mfmsr r11 */ \
|
||||||
|
.long 0x01006b69; /* xori r11,r11,1 */ \
|
||||||
|
.long 0x05009f42; /* bcl 20,31,$+4 */ \
|
||||||
|
.long 0xa602487d; /* mflr r10 */ \
|
||||||
|
.long 0x14004a39; /* addi r10,r10,20 */ \
|
||||||
|
.long 0xa64b5a7d; /* mthsrr0 r10 */ \
|
||||||
|
.long 0xa64b7b7d; /* mthsrr1 r11 */ \
|
||||||
|
.long 0x2402004c; /* hrfid */ \
|
||||||
|
191:
|
||||||
|
|
||||||
|
|
||||||
|
/* Load an immediate 64-bit value into a register */
|
||||||
|
#define LOAD_IMM64(r, e) \
|
||||||
|
lis r,(e)@highest; \
|
||||||
|
ori r,r,(e)@higher; \
|
||||||
|
rldicr r,r, 32, 31; \
|
||||||
|
oris r,r, (e)@h; \
|
||||||
|
ori r,r, (e)@l;
|
||||||
|
|
||||||
|
.section ".head","ax"
|
||||||
|
|
||||||
|
. = 0
|
||||||
|
.global start
|
||||||
|
start:
|
||||||
|
FIXUP_ENDIAN
|
||||||
|
|
||||||
|
/* setup stack */
|
||||||
|
LOAD_IMM64(%r1, STACK_TOP - 0x100)
|
||||||
|
LOAD_IMM64(%r12, main)
|
||||||
|
mtctr %r12,
|
||||||
|
bctrl
|
||||||
|
ba 0
|
||||||
|
|
||||||
|
/* XXX: litedram init should not take exceptions, maybe we could get
|
||||||
|
* rid of these to save space, along with a core tweak to suppress
|
||||||
|
* exceptions in case they happen (just terminate ?)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define EXCEPTION(nr) \
|
||||||
|
.= nr; \
|
||||||
|
b .
|
||||||
|
|
||||||
|
/* More exception stubs */
|
||||||
|
EXCEPTION(0x100)
|
||||||
|
EXCEPTION(0x200)
|
||||||
|
EXCEPTION(0x300)
|
||||||
|
EXCEPTION(0x380)
|
||||||
|
EXCEPTION(0x400)
|
||||||
|
EXCEPTION(0x480)
|
||||||
|
EXCEPTION(0x500)
|
||||||
|
EXCEPTION(0x600)
|
||||||
|
EXCEPTION(0x700)
|
||||||
|
EXCEPTION(0x800)
|
||||||
|
EXCEPTION(0x900)
|
||||||
|
EXCEPTION(0x980)
|
||||||
|
EXCEPTION(0xa00)
|
||||||
|
EXCEPTION(0xb00)
|
||||||
|
EXCEPTION(0xc00)
|
||||||
|
EXCEPTION(0xd00)
|
||||||
|
EXCEPTION(0xe00)
|
||||||
|
EXCEPTION(0xe20)
|
||||||
|
EXCEPTION(0xe40)
|
||||||
|
EXCEPTION(0xe60)
|
||||||
|
EXCEPTION(0xe80)
|
||||||
|
EXCEPTION(0xf00)
|
||||||
|
EXCEPTION(0xf20)
|
||||||
|
EXCEPTION(0xf40)
|
||||||
|
EXCEPTION(0xf60)
|
||||||
|
EXCEPTION(0xf80)
|
||||||
|
#if 0
|
||||||
|
EXCEPTION(0x1000)
|
||||||
|
EXCEPTION(0x1100)
|
||||||
|
EXCEPTION(0x1200)
|
||||||
|
EXCEPTION(0x1300)
|
||||||
|
EXCEPTION(0x1400)
|
||||||
|
EXCEPTION(0x1500)
|
||||||
|
EXCEPTION(0x1600)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
@ -0,0 +1,17 @@
|
|||||||
|
static inline void flush_cpu_dcache(void) { }
|
||||||
|
static inline void flush_l2_cache(void) { }
|
||||||
|
|
||||||
|
#define CONFIG_CPU_NOP "nop"
|
||||||
|
#define CONFIG_CLOCK_FREQUENCY 100000000
|
||||||
|
|
||||||
|
static inline void timer0_en_write(int e) { }
|
||||||
|
static inline void timer0_reload_write(int r) { }
|
||||||
|
static inline void timer0_load_write(int l) { }
|
||||||
|
static inline void timer0_update_value_write(int v) { }
|
||||||
|
static inline uint64_t timer0_value_read(void)
|
||||||
|
{
|
||||||
|
uint64_t val;
|
||||||
|
|
||||||
|
__asm__ volatile ("mfdec %0" : "=r" (val));
|
||||||
|
return val;
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008, 2012 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _ASSERT_H
|
||||||
|
#define _ASSERT_H
|
||||||
|
|
||||||
|
#define assert(cond) \
|
||||||
|
do { if (!(cond)) { \
|
||||||
|
assert_fail(__FILE__ \
|
||||||
|
":" stringify(__LINE__) \
|
||||||
|
":" stringify(cond)); } \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
void __attribute__((noreturn)) assert_fail(const char *msg);
|
||||||
|
|
||||||
|
#define stringify(expr) stringify_1(expr)
|
||||||
|
/* Double-indirection required to stringify expansions */
|
||||||
|
#define stringify_1(expr) #expr
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,54 @@
|
|||||||
|
/* Copyright 2013-2014 IBM Corp.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
* implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __COMPILER_H
|
||||||
|
#define __COMPILER_H
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* Macros for various compiler bits and pieces */
|
||||||
|
#define __packed __attribute__((packed))
|
||||||
|
#define __align(x) __attribute__((__aligned__(x)))
|
||||||
|
#define __unused __attribute__((unused))
|
||||||
|
#define __used __attribute__((used))
|
||||||
|
#define __section(x) __attribute__((__section__(x)))
|
||||||
|
#define __noreturn __attribute__((noreturn))
|
||||||
|
/* not __const as this has a different meaning (const) */
|
||||||
|
#define __attrconst __attribute__((const))
|
||||||
|
#define __warn_unused_result __attribute__((warn_unused_result))
|
||||||
|
#define __noinline __attribute__((noinline))
|
||||||
|
|
||||||
|
#if 0 /* Provided by gcc stddef.h */
|
||||||
|
#define offsetof(type,m) __builtin_offsetof(type,m)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __nomcount __attribute__((no_instrument_function))
|
||||||
|
|
||||||
|
/* Compiler barrier */
|
||||||
|
static inline void barrier(void)
|
||||||
|
{
|
||||||
|
// asm volatile("" : : : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
|
/* Stringification macro */
|
||||||
|
#define __tostr(x) #x
|
||||||
|
#define tostr(x) __tostr(x)
|
||||||
|
|
||||||
|
#endif /* __COMPILER_H */
|
@ -0,0 +1,26 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _CTYPE_H
|
||||||
|
#define _CTYPE_H
|
||||||
|
|
||||||
|
#include <compiler.h>
|
||||||
|
|
||||||
|
int __attrconst isdigit(int c);
|
||||||
|
int __attrconst isxdigit(int c);
|
||||||
|
int __attrconst isprint(int c);
|
||||||
|
int __attrconst isspace(int c);
|
||||||
|
|
||||||
|
int __attrconst tolower(int c);
|
||||||
|
int __attrconst toupper(int c);
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,36 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _ERRNO_H
|
||||||
|
#define _ERRNO_H
|
||||||
|
|
||||||
|
extern int errno;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Error number definitions
|
||||||
|
*/
|
||||||
|
#define EPERM 1 /* not permitted */
|
||||||
|
#define ENOENT 2 /* file or directory not found */
|
||||||
|
#define EIO 5 /* input/output error */
|
||||||
|
#define EBADF 9 /* Bad file number */
|
||||||
|
#define ENOMEM 12 /* not enough space */
|
||||||
|
#define EACCES 13 /* permission denied */
|
||||||
|
#define EFAULT 14 /* bad address */
|
||||||
|
#define EBUSY 16 /* resource busy */
|
||||||
|
#define EEXIST 17 /* file already exists */
|
||||||
|
#define ENODEV 19 /* device not found */
|
||||||
|
#define EINVAL 22 /* invalid argument */
|
||||||
|
#define EDOM 33 /* math argument out of domain of func */
|
||||||
|
#define ERANGE 34 /* math result not representable */
|
||||||
|
#define ENOSYS 38 /* Function not implemented */
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,32 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _LIMITS_H
|
||||||
|
#define _LIMITS_H
|
||||||
|
|
||||||
|
#define UCHAR_MAX 255
|
||||||
|
#define SCHAR_MAX 127
|
||||||
|
#define SCHAR_MIN (-128)
|
||||||
|
|
||||||
|
#define USHRT_MAX 65535
|
||||||
|
#define SHRT_MAX 32767
|
||||||
|
#define SHRT_MIN (-32768)
|
||||||
|
|
||||||
|
#define UINT_MAX (4294967295U)
|
||||||
|
#define INT_MAX 2147483647
|
||||||
|
#define INT_MIN (-2147483648)
|
||||||
|
|
||||||
|
#define ULONG_MAX ((unsigned long)-1L)
|
||||||
|
#define LONG_MAX (ULONG_MAX/2)
|
||||||
|
#define LONG_MIN ((-LONG_MAX)-1)
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,30 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _STDINT_H
|
||||||
|
#define _STDINT_H
|
||||||
|
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef signed char int8_t;
|
||||||
|
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef signed short int16_t;
|
||||||
|
|
||||||
|
typedef unsigned int uint32_t;
|
||||||
|
typedef signed int int32_t;
|
||||||
|
|
||||||
|
typedef unsigned long long uint64_t;
|
||||||
|
typedef signed long long int64_t;
|
||||||
|
|
||||||
|
typedef unsigned long int uintptr_t;
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,35 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _STDIO_H
|
||||||
|
#define _STDIO_H
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include "stddef.h"
|
||||||
|
|
||||||
|
#define EOF (-1)
|
||||||
|
|
||||||
|
int _printf(const char *format, ...) __attribute__((format (printf, 1, 2)));
|
||||||
|
|
||||||
|
#ifndef pr_fmt
|
||||||
|
#define pr_fmt(fmt) fmt
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define printf(f, ...) do { _printf(pr_fmt(f), ##__VA_ARGS__); } while(0)
|
||||||
|
|
||||||
|
int snprintf(char *str, size_t size, const char *format, ...) __attribute__((format (printf, 3, 4)));
|
||||||
|
int vsnprintf(char *str, size_t size, const char *format, va_list);
|
||||||
|
|
||||||
|
int putchar(int ch);
|
||||||
|
int puts(const char *str);
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,25 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _STDLIB_H
|
||||||
|
#define _STDLIB_H
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
|
||||||
|
#define RAND_MAX 32767
|
||||||
|
|
||||||
|
int atoi(const char *str);
|
||||||
|
long atol(const char *str);
|
||||||
|
unsigned long int strtoul(const char *nptr, char **endptr, int base);
|
||||||
|
long int strtol(const char *nptr, char **endptr, int base);
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,45 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2016 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _STRING_H
|
||||||
|
#define _STRING_H
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
|
||||||
|
char *strcpy(char *dest, const char *src);
|
||||||
|
char *strncpy(char *dest, const char *src, size_t n);
|
||||||
|
char *strcat(char *dest, const char *src);
|
||||||
|
int strcmp(const char *s1, const char *s2);
|
||||||
|
int strncmp(const char *s1, const char *s2, size_t n);
|
||||||
|
int strcasecmp(const char *s1, const char *s2);
|
||||||
|
int strncasecmp(const char *s1, const char *s2, size_t n);
|
||||||
|
char *strchr(const char *s, int c);
|
||||||
|
char *strrchr(const char *s, int c);
|
||||||
|
size_t strlen(const char *s);
|
||||||
|
size_t strnlen(const char *s, size_t n);
|
||||||
|
char *strstr(const char *hay, const char *needle);
|
||||||
|
char *strtok(char *src, const char *pattern);
|
||||||
|
char *strdup(const char *src);
|
||||||
|
|
||||||
|
void *memset(void *s, int c, size_t n);
|
||||||
|
void *memchr(const void *s, int c, size_t n);
|
||||||
|
void *memcpy(void *dest, const void *src, size_t n);
|
||||||
|
void *memcpy_from_ci(void *destpp, const void *srcpp, size_t len);
|
||||||
|
void *memmove(void *dest, const void *src, size_t n);
|
||||||
|
int memcmp(const void *s1, const void *s2, size_t n);
|
||||||
|
|
||||||
|
static inline int ffs(unsigned long val)
|
||||||
|
{
|
||||||
|
return __builtin_ffs(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,26 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _UNISTD_H
|
||||||
|
#define _UNISTD_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
typedef long ssize_t;
|
||||||
|
|
||||||
|
extern int open(const char *name, int flags);
|
||||||
|
extern int close(int fd);
|
||||||
|
extern ssize_t read(int fd, void *buf, size_t count);
|
||||||
|
extern ssize_t write(int fd, const void *buf, size_t count);
|
||||||
|
extern ssize_t lseek(int fd, long offset, int whence);
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,26 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <compiler.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
int __attrconst isdigit(int ch)
|
||||||
|
{
|
||||||
|
switch (ch) {
|
||||||
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <compiler.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
int __attrconst isprint(int ch)
|
||||||
|
{
|
||||||
|
return (ch >= 32 && ch < 127);
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <compiler.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
int __attrconst isspace(int ch)
|
||||||
|
{
|
||||||
|
switch (ch) {
|
||||||
|
case ' ':
|
||||||
|
case '\f':
|
||||||
|
case '\n':
|
||||||
|
case '\r':
|
||||||
|
case '\t':
|
||||||
|
case '\v':
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <compiler.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
int __attrconst isxdigit(int ch)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
(ch >= '0' && ch <= '9') |
|
||||||
|
(ch >= 'A' && ch <= 'F') |
|
||||||
|
(ch >= 'a' && ch <= 'f') );
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
void *memchr(const void *ptr, int c, size_t n);
|
||||||
|
void *memchr(const void *ptr, int c, size_t n)
|
||||||
|
{
|
||||||
|
unsigned char ch = (unsigned char)c;
|
||||||
|
const unsigned char *p = ptr;
|
||||||
|
|
||||||
|
while (n-- > 0) {
|
||||||
|
if (*p == ch)
|
||||||
|
return (void *)p;
|
||||||
|
p += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
int memcmp(const void *ptr1, const void *ptr2, size_t n);
|
||||||
|
int memcmp(const void *ptr1, const void *ptr2, size_t n)
|
||||||
|
{
|
||||||
|
const unsigned char *p1 = ptr1;
|
||||||
|
const unsigned char *p2 = ptr2;
|
||||||
|
|
||||||
|
while (n-- > 0) {
|
||||||
|
if (*p1 != *p2)
|
||||||
|
return (*p1 - *p2);
|
||||||
|
p1 += 1;
|
||||||
|
p2 += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void *memcpy(void *dest, const void *src, size_t n);
|
||||||
|
void *memcpy(void *dest, const void *src, size_t n)
|
||||||
|
{
|
||||||
|
void *ret = dest;
|
||||||
|
|
||||||
|
while (n >= 8) {
|
||||||
|
*(uint64_t *)dest = *(uint64_t *)src;
|
||||||
|
dest += 8;
|
||||||
|
src += 8;
|
||||||
|
n -= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (n > 0) {
|
||||||
|
*(uint8_t *)dest = *(uint8_t *)src;
|
||||||
|
dest += 1;
|
||||||
|
src += 1;
|
||||||
|
n -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
void *memcpy(void *dest, const void *src, size_t n);
|
||||||
|
void *memmove(void *dest, const void *src, size_t n);
|
||||||
|
void *memmove(void *dest, const void *src, size_t n)
|
||||||
|
{
|
||||||
|
/* Do the buffers overlap in a bad way? */
|
||||||
|
if (src < dest && src + n >= dest) {
|
||||||
|
char *cdest;
|
||||||
|
const char *csrc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Copy from end to start */
|
||||||
|
cdest = dest + n - 1;
|
||||||
|
csrc = src + n - 1;
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
*cdest-- = *csrc--;
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
} else {
|
||||||
|
/* Normal copy is possible */
|
||||||
|
return memcpy(dest, src, n);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#define CACHE_LINE_SIZE 128
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
void *memset(void *dest, int c, size_t size);
|
||||||
|
void *memset(void *dest, int c, size_t size)
|
||||||
|
{
|
||||||
|
unsigned char *d = (unsigned char *)dest;
|
||||||
|
unsigned long big_c = 0;
|
||||||
|
|
||||||
|
if (c) {
|
||||||
|
big_c = c;
|
||||||
|
big_c |= (big_c << 8) | big_c;
|
||||||
|
big_c |= (big_c << 16) | big_c;
|
||||||
|
big_c |= (big_c << 32) | big_c;
|
||||||
|
}
|
||||||
|
while (size >= 8 && c == 0) {
|
||||||
|
*((unsigned long *)d) = big_c;
|
||||||
|
d+=8;
|
||||||
|
size-=8;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (size-- > 0) {
|
||||||
|
*d++ = (unsigned char)c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
int strcasecmp(const char *s1, const char *s2);
|
||||||
|
int strcasecmp(const char *s1, const char *s2)
|
||||||
|
{
|
||||||
|
while (*s1 != 0 && *s2 != 0) {
|
||||||
|
if (toupper(*s1) != toupper(*s2))
|
||||||
|
break;
|
||||||
|
++s1;
|
||||||
|
++s2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *s1 - *s2;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
size_t strlen(const char *s);
|
||||||
|
char *strcpy(char *dst, const char *src);
|
||||||
|
char *strcat(char *dst, const char *src);
|
||||||
|
char *strcat(char *dst, const char *src)
|
||||||
|
{
|
||||||
|
size_t p;
|
||||||
|
|
||||||
|
p = strlen(dst);
|
||||||
|
strcpy(&dst[p], src);
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
char *strchr(const char *s, int c);
|
||||||
|
char *strchr(const char *s, int c)
|
||||||
|
{
|
||||||
|
char cb = c;
|
||||||
|
|
||||||
|
while (*s != 0) {
|
||||||
|
if (*s == cb) {
|
||||||
|
return (char *)s;
|
||||||
|
}
|
||||||
|
s += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
int strcmp(const char *s1, const char *s2);
|
||||||
|
int strcmp(const char *s1, const char *s2)
|
||||||
|
{
|
||||||
|
while (*s1 != 0 && *s2 != 0) {
|
||||||
|
if (*s1 != *s2)
|
||||||
|
break;
|
||||||
|
s1 += 1;
|
||||||
|
s2 += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *s1 - *s2;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
char *strcpy(char *dst, const char *src);
|
||||||
|
char *strcpy(char *dst, const char *src)
|
||||||
|
{
|
||||||
|
char *ptr = dst;
|
||||||
|
|
||||||
|
do {
|
||||||
|
*ptr++ = *src;
|
||||||
|
} while (*src++ != 0);
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
size_t strlen(const char *s);
|
||||||
|
size_t strlen(const char *s)
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
while (*s != 0) {
|
||||||
|
len += 1;
|
||||||
|
s += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t strnlen(const char *s, size_t n);
|
||||||
|
size_t strnlen(const char *s, size_t n)
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
while (*s != 0 && n) {
|
||||||
|
len += 1;
|
||||||
|
s += 1;
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
int strncasecmp(const char *s1, const char *s2, size_t n);
|
||||||
|
int strncasecmp(const char *s1, const char *s2, size_t n)
|
||||||
|
{
|
||||||
|
if (n < 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (*s1 != 0 && *s2 != 0 && --n > 0) {
|
||||||
|
if (toupper(*s1) != toupper(*s2))
|
||||||
|
break;
|
||||||
|
++s1;
|
||||||
|
++s2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return toupper(*s1) - toupper(*s2);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
int strncmp(const char *s1, const char *s2, size_t n);
|
||||||
|
int strncmp(const char *s1, const char *s2, size_t n)
|
||||||
|
{
|
||||||
|
if (n < 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (*s1 != 0 && *s2 != 0 && --n > 0) {
|
||||||
|
if (*s1 != *s2)
|
||||||
|
break;
|
||||||
|
s1 += 1;
|
||||||
|
s2 += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *s1 - *s2;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
char *strncpy(char *dst, const char *src, size_t n);
|
||||||
|
char *strncpy(char *dst, const char *src, size_t n)
|
||||||
|
{
|
||||||
|
char *ret = dst;
|
||||||
|
|
||||||
|
/* Copy string */
|
||||||
|
while (*src != 0 && n > 0) {
|
||||||
|
*dst++ = *src++;
|
||||||
|
n -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* strncpy always clears the rest of destination string... */
|
||||||
|
while (n > 0) {
|
||||||
|
*dst++ = 0;
|
||||||
|
n -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008, 2019 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
char *strrchr(const char *s, int c);
|
||||||
|
char *strrchr(const char *s, int c)
|
||||||
|
{
|
||||||
|
char *last = NULL;
|
||||||
|
char cb = c;
|
||||||
|
|
||||||
|
while (*s != 0) {
|
||||||
|
if (*s == cb)
|
||||||
|
last = (char *)s;
|
||||||
|
s += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return last;
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
size_t strlen(const char *s);
|
||||||
|
int strncmp(const char *s1, const char *s2, size_t n);
|
||||||
|
char *strstr(const char *hay, const char *needle);
|
||||||
|
char *strstr(const char *hay, const char *needle)
|
||||||
|
{
|
||||||
|
char *pos;
|
||||||
|
size_t hlen, nlen;
|
||||||
|
|
||||||
|
if (hay == NULL || needle == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
hlen = strlen(hay);
|
||||||
|
nlen = strlen(needle);
|
||||||
|
if (nlen < 1)
|
||||||
|
return (char *)hay;
|
||||||
|
|
||||||
|
for (pos = (char *)hay; pos < hay + hlen; pos++) {
|
||||||
|
if (strncmp(pos, needle, nlen) == 0) {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
char *strtok(char *src, const char *pattern);
|
||||||
|
char *strtok(char *src, const char *pattern)
|
||||||
|
{
|
||||||
|
static char *nxtTok;
|
||||||
|
char *retVal = NULL;
|
||||||
|
|
||||||
|
if (!src) {
|
||||||
|
src = nxtTok;
|
||||||
|
if (!src)
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*src) {
|
||||||
|
const char *pp = pattern;
|
||||||
|
while (*pp) {
|
||||||
|
if (*pp == *src) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pp++;
|
||||||
|
}
|
||||||
|
if (!*pp) {
|
||||||
|
if (!retVal)
|
||||||
|
retVal = src;
|
||||||
|
else if (!src[-1])
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
*src = '\0';
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
|
||||||
|
nxtTok = src;
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
@ -0,0 +1,113 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
long int strtol(const char *S, char **PTR,int BASE)
|
||||||
|
{
|
||||||
|
long rval = 0;
|
||||||
|
short int negative = 0;
|
||||||
|
short int digit;
|
||||||
|
// *PTR is S, unless PTR is NULL, in which case i override it with my own ptr
|
||||||
|
char* ptr;
|
||||||
|
if (PTR == NULL)
|
||||||
|
{
|
||||||
|
//override
|
||||||
|
PTR = &ptr;
|
||||||
|
}
|
||||||
|
// i use PTR to advance through the string
|
||||||
|
*PTR = (char *) S;
|
||||||
|
//check if BASE is ok
|
||||||
|
if ((BASE < 0) || BASE > 36)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// ignore white space at beginning of S
|
||||||
|
while ((**PTR == ' ')
|
||||||
|
|| (**PTR == '\t')
|
||||||
|
|| (**PTR == '\n')
|
||||||
|
|| (**PTR == '\r')
|
||||||
|
)
|
||||||
|
{
|
||||||
|
(*PTR)++;
|
||||||
|
}
|
||||||
|
// check if S starts with "-" in which case the return value is negative
|
||||||
|
if (**PTR == '-')
|
||||||
|
{
|
||||||
|
negative = 1;
|
||||||
|
(*PTR)++;
|
||||||
|
}
|
||||||
|
// if BASE is 0... determine the base from the first chars...
|
||||||
|
if (BASE == 0)
|
||||||
|
{
|
||||||
|
// if S starts with "0x", BASE = 16, else 10
|
||||||
|
if ((**PTR == '0') && (*((*PTR)+1) == 'x'))
|
||||||
|
{
|
||||||
|
BASE = 16;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BASE = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (BASE == 16)
|
||||||
|
{
|
||||||
|
// S may start with "0x"
|
||||||
|
if ((**PTR == '0') && (*((*PTR)+1) == 'x'))
|
||||||
|
{
|
||||||
|
(*PTR)++;
|
||||||
|
(*PTR)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//until end of string
|
||||||
|
while (**PTR)
|
||||||
|
{
|
||||||
|
if (((**PTR) >= '0') && ((**PTR) <= '9'))
|
||||||
|
{
|
||||||
|
//digit (0..9)
|
||||||
|
digit = **PTR - '0';
|
||||||
|
}
|
||||||
|
else if (((**PTR) >= 'a') && ((**PTR) <='z'))
|
||||||
|
{
|
||||||
|
//alphanumeric digit lowercase(a (10) .. z (35) )
|
||||||
|
digit = (**PTR - 'a') + 10;
|
||||||
|
}
|
||||||
|
else if (((**PTR) >= 'A') && ((**PTR) <='Z'))
|
||||||
|
{
|
||||||
|
//alphanumeric digit uppercase(a (10) .. z (35) )
|
||||||
|
digit = (**PTR - 'A') + 10;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//end of parseable number reached...
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (digit < BASE)
|
||||||
|
{
|
||||||
|
rval = (rval * BASE) + digit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//digit found, but its too big for current base
|
||||||
|
//end of parseable number reached...
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//next...
|
||||||
|
(*PTR)++;
|
||||||
|
}
|
||||||
|
if (negative)
|
||||||
|
{
|
||||||
|
return rval * -1;
|
||||||
|
}
|
||||||
|
//else
|
||||||
|
return rval;
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
unsigned long int strtoul(const char *S, char **PTR,int BASE)
|
||||||
|
{
|
||||||
|
unsigned long rval = 0;
|
||||||
|
short int digit;
|
||||||
|
// *PTR is S, unless PTR is NULL, in which case i override it with my own ptr
|
||||||
|
char* ptr;
|
||||||
|
if (PTR == NULL)
|
||||||
|
{
|
||||||
|
//override
|
||||||
|
PTR = &ptr;
|
||||||
|
}
|
||||||
|
// i use PTR to advance through the string
|
||||||
|
*PTR = (char *) S;
|
||||||
|
//check if BASE is ok
|
||||||
|
if ((BASE < 0) || BASE > 36)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// ignore white space at beginning of S
|
||||||
|
while ((**PTR == ' ')
|
||||||
|
|| (**PTR == '\t')
|
||||||
|
|| (**PTR == '\n')
|
||||||
|
|| (**PTR == '\r')
|
||||||
|
)
|
||||||
|
{
|
||||||
|
(*PTR)++;
|
||||||
|
}
|
||||||
|
// if BASE is 0... determine the base from the first chars...
|
||||||
|
if (BASE == 0)
|
||||||
|
{
|
||||||
|
// if S starts with "0x", BASE = 16, else 10
|
||||||
|
if ((**PTR == '0') && (*((*PTR)+1) == 'x'))
|
||||||
|
{
|
||||||
|
BASE = 16;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BASE = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (BASE == 16)
|
||||||
|
{
|
||||||
|
// S may start with "0x"
|
||||||
|
if ((**PTR == '0') && (*((*PTR)+1) == 'x'))
|
||||||
|
{
|
||||||
|
(*PTR)++;
|
||||||
|
(*PTR)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//until end of string
|
||||||
|
while (**PTR)
|
||||||
|
{
|
||||||
|
if (((**PTR) >= '0') && ((**PTR) <='9'))
|
||||||
|
{
|
||||||
|
//digit (0..9)
|
||||||
|
digit = **PTR - '0';
|
||||||
|
}
|
||||||
|
else if (((**PTR) >= 'a') && ((**PTR) <='z'))
|
||||||
|
{
|
||||||
|
//alphanumeric digit lowercase(a (10) .. z (35) )
|
||||||
|
digit = (**PTR - 'a') + 10;
|
||||||
|
}
|
||||||
|
else if (((**PTR) >= 'A') && ((**PTR) <='Z'))
|
||||||
|
{
|
||||||
|
//alphanumeric digit uppercase(a (10) .. z (35) )
|
||||||
|
digit = (**PTR - 'A') + 10;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//end of parseable number reached...
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (digit < BASE)
|
||||||
|
{
|
||||||
|
rval = (rval * BASE) + digit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//digit found, but its too big for current base
|
||||||
|
//end of parseable number reached...
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//next...
|
||||||
|
(*PTR)++;
|
||||||
|
}
|
||||||
|
//done
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <compiler.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
int __attrconst tolower(int c)
|
||||||
|
{
|
||||||
|
return (((c >= 'A') && (c <= 'Z')) ? (c - 'A' + 'a' ) : c);
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <compiler.h>
|
||||||
|
#include "ctype.h"
|
||||||
|
|
||||||
|
int __attrconst toupper (int cha)
|
||||||
|
{
|
||||||
|
if((cha >= 'a') && (cha <= 'z'))
|
||||||
|
return(cha - 'a' + 'A');
|
||||||
|
return(cha);
|
||||||
|
}
|
@ -0,0 +1,304 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2008 IBM Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the BSD License
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial implementation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <compiler.h>
|
||||||
|
#include "stdio.h"
|
||||||
|
#include "stdlib.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "ctype.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
static const unsigned long long convert[] = {
|
||||||
|
0x0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF,
|
||||||
|
0xFFFFFFFFFFULL, 0xFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
print_str_fill(char **buffer, size_t bufsize, char *sizec,
|
||||||
|
const char *str, char c)
|
||||||
|
{
|
||||||
|
size_t i, sizei, len;
|
||||||
|
char *bstart = *buffer;
|
||||||
|
|
||||||
|
sizei = strtoul(sizec, NULL, 10);
|
||||||
|
len = strlen(str);
|
||||||
|
if (sizei > len) {
|
||||||
|
for (i = 0;
|
||||||
|
(i < (sizei - len)) && ((*buffer - bstart) < bufsize);
|
||||||
|
i++) {
|
||||||
|
**buffer = c;
|
||||||
|
*buffer += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
print_str(char **buffer, size_t bufsize, const char *str)
|
||||||
|
{
|
||||||
|
char *bstart = *buffer;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; (i < strlen(str)) && ((*buffer - bstart) < bufsize); i++) {
|
||||||
|
**buffer = str[i];
|
||||||
|
*buffer += 1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int __attrconst
|
||||||
|
print_intlen(unsigned long value, unsigned short int base)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (value > 0) {
|
||||||
|
if (base == 16)
|
||||||
|
value >>= 4;
|
||||||
|
else
|
||||||
|
value /= base;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i == 0)
|
||||||
|
i = 1;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
print_itoa(char **buffer, size_t bufsize, unsigned long value,
|
||||||
|
unsigned short base, bool upper)
|
||||||
|
{
|
||||||
|
const char zeichen[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
|
||||||
|
char c;
|
||||||
|
int i, len;
|
||||||
|
|
||||||
|
if(base <= 2 || base > 16)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
len = i = print_intlen(value, base);
|
||||||
|
|
||||||
|
/* Don't print to buffer if bufsize is not enough. */
|
||||||
|
if (len > bufsize)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
c = zeichen[value % base];
|
||||||
|
if (upper)
|
||||||
|
c = toupper(c);
|
||||||
|
|
||||||
|
(*buffer)[--i] = c;
|
||||||
|
value /= base;
|
||||||
|
} while(value);
|
||||||
|
|
||||||
|
*buffer += len;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
print_fill(char **buffer, size_t bufsize, char *sizec, unsigned long size,
|
||||||
|
unsigned short int base, char c, int optlen)
|
||||||
|
{
|
||||||
|
int i, sizei, len;
|
||||||
|
char *bstart = *buffer;
|
||||||
|
|
||||||
|
sizei = strtoul(sizec, NULL, 10);
|
||||||
|
len = print_intlen(size, base) + optlen;
|
||||||
|
if (sizei > len) {
|
||||||
|
for (i = 0;
|
||||||
|
(i < (sizei - len)) && ((*buffer - bstart) < bufsize);
|
||||||
|
i++) {
|
||||||
|
**buffer = c;
|
||||||
|
*buffer += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
print_format(char **buffer, size_t bufsize, const char *format, void *var)
|
||||||
|
{
|
||||||
|
char *start;
|
||||||
|
unsigned int i = 0, length_mod = sizeof(int);
|
||||||
|
unsigned long value = 0;
|
||||||
|
unsigned long signBit;
|
||||||
|
char *form, sizec[32];
|
||||||
|
char sign = ' ';
|
||||||
|
bool upper = false;
|
||||||
|
|
||||||
|
form = (char *) format;
|
||||||
|
start = *buffer;
|
||||||
|
|
||||||
|
form++;
|
||||||
|
if(*form == '0' || *form == '.') {
|
||||||
|
sign = '0';
|
||||||
|
form++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((*form != '\0') && ((*buffer - start) < bufsize)) {
|
||||||
|
switch(*form) {
|
||||||
|
case 'u':
|
||||||
|
case 'd':
|
||||||
|
case 'i':
|
||||||
|
sizec[i] = '\0';
|
||||||
|
value = (unsigned long) var;
|
||||||
|
signBit = 0x1ULL << (length_mod * 8 - 1);
|
||||||
|
if ((*form != 'u') && (signBit & value)) {
|
||||||
|
**buffer = '-';
|
||||||
|
*buffer += 1;
|
||||||
|
value = (-(unsigned long)value) & convert[length_mod];
|
||||||
|
}
|
||||||
|
print_fill(buffer, bufsize - (*buffer - start),
|
||||||
|
sizec, value, 10, sign, 0);
|
||||||
|
print_itoa(buffer, bufsize - (*buffer - start),
|
||||||
|
value, 10, upper);
|
||||||
|
break;
|
||||||
|
case 'X':
|
||||||
|
upper = true;
|
||||||
|
/* fallthrough */
|
||||||
|
case 'x':
|
||||||
|
sizec[i] = '\0';
|
||||||
|
value = (unsigned long) var & convert[length_mod];
|
||||||
|
print_fill(buffer, bufsize - (*buffer - start),
|
||||||
|
sizec, value, 16, sign, 0);
|
||||||
|
print_itoa(buffer, bufsize - (*buffer - start),
|
||||||
|
value, 16, upper);
|
||||||
|
break;
|
||||||
|
case 'O':
|
||||||
|
case 'o':
|
||||||
|
sizec[i] = '\0';
|
||||||
|
value = (long int) var & convert[length_mod];
|
||||||
|
print_fill(buffer, bufsize - (*buffer - start),
|
||||||
|
sizec, value, 8, sign, 0);
|
||||||
|
print_itoa(buffer, bufsize - (*buffer - start),
|
||||||
|
value, 8, upper);
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
sizec[i] = '\0';
|
||||||
|
print_fill(buffer, bufsize - (*buffer - start),
|
||||||
|
sizec, (unsigned long) var, 16, ' ', 2);
|
||||||
|
print_str(buffer, bufsize - (*buffer - start),
|
||||||
|
"0x");
|
||||||
|
print_itoa(buffer, bufsize - (*buffer - start),
|
||||||
|
(unsigned long) var, 16, upper);
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
sizec[i] = '\0';
|
||||||
|
print_fill(buffer, bufsize - (*buffer - start),
|
||||||
|
sizec, 1, 10, ' ', 0);
|
||||||
|
**buffer = (unsigned long) var;
|
||||||
|
*buffer += 1;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
sizec[i] = '\0';
|
||||||
|
print_str_fill(buffer,
|
||||||
|
bufsize - (*buffer - start), sizec,
|
||||||
|
(char *) var, ' ');
|
||||||
|
|
||||||
|
print_str(buffer, bufsize - (*buffer - start),
|
||||||
|
(char *) var);
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
form++;
|
||||||
|
if(*form == 'l') {
|
||||||
|
length_mod = sizeof(long long int);
|
||||||
|
} else {
|
||||||
|
form--;
|
||||||
|
length_mod = sizeof(long int);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
form++;
|
||||||
|
if(*form == 'h') {
|
||||||
|
length_mod = sizeof(signed char);
|
||||||
|
} else {
|
||||||
|
form--;
|
||||||
|
length_mod = sizeof(short int);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'z':
|
||||||
|
length_mod = sizeof(size_t);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if(*form >= '0' && *form <= '9')
|
||||||
|
sizec[i++] = *form;
|
||||||
|
}
|
||||||
|
form++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (long int) (*buffer - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The vsnprintf function prints a formatted strings into a buffer.
|
||||||
|
* BUG: buffer size checking does not fully work yet
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
vsnprintf(char *buffer, size_t bufsize, const char *format, va_list arg)
|
||||||
|
{
|
||||||
|
char *ptr, *bstart;
|
||||||
|
|
||||||
|
bstart = buffer;
|
||||||
|
ptr = (char *) format;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return from here if size passed is zero, otherwise we would
|
||||||
|
* overrun buffer while setting NULL character at the end.
|
||||||
|
*/
|
||||||
|
if (!buffer || !bufsize)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Leave one space for NULL character */
|
||||||
|
bufsize--;
|
||||||
|
|
||||||
|
while(*ptr != '\0' && (buffer - bstart) < bufsize)
|
||||||
|
{
|
||||||
|
if(*ptr == '%') {
|
||||||
|
char formstr[20];
|
||||||
|
int i=0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
formstr[i] = *ptr;
|
||||||
|
ptr++;
|
||||||
|
i++;
|
||||||
|
} while(!(*ptr == 'd' || *ptr == 'i' || *ptr == 'u' || *ptr == 'x' || *ptr == 'X'
|
||||||
|
|| *ptr == 'p' || *ptr == 'c' || *ptr == 's' || *ptr == '%'
|
||||||
|
|| *ptr == 'O' || *ptr == 'o' ));
|
||||||
|
formstr[i++] = *ptr;
|
||||||
|
formstr[i] = '\0';
|
||||||
|
if(*ptr == '%') {
|
||||||
|
*buffer++ = '%';
|
||||||
|
} else {
|
||||||
|
print_format(&buffer,
|
||||||
|
bufsize - (buffer - bstart),
|
||||||
|
formstr, va_arg(arg, void *));
|
||||||
|
}
|
||||||
|
ptr++;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
*buffer = *ptr;
|
||||||
|
|
||||||
|
buffer++;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*buffer = '\0';
|
||||||
|
|
||||||
|
return (buffer - bstart);
|
||||||
|
}
|
@ -0,0 +1,156 @@
|
|||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <generated/git.h>
|
||||||
|
|
||||||
|
#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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int _printf(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
char buffer[320];
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
count = vsnprintf(buffer, sizeof(buffer), fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
putstr(buffer, count);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush_cpu_dcache(void) { }
|
||||||
|
void flush_cpu_icache(void) { }
|
||||||
|
void flush_l2_cache(void) { }
|
||||||
|
|
||||||
|
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 ?
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
* extracted from git
|
||||||
|
*/
|
||||||
|
printf(" Soc signature: %016llx\n",
|
||||||
|
(unsigned long long)readq(SYSCON_BASE + SYS_REG_SIGNATURE));
|
||||||
|
printf(" Soc features: ");
|
||||||
|
ftr = readq(SYSCON_BASE + SYS_REG_INFO);
|
||||||
|
if (ftr & SYS_REG_INFO_HAS_UART)
|
||||||
|
printf("UART ");
|
||||||
|
if (ftr & SYS_REG_INFO_HAS_DRAM)
|
||||||
|
printf("DRAM ");
|
||||||
|
printf("\n");
|
||||||
|
val = readq(SYSCON_BASE + SYS_REG_BRAMINFO);
|
||||||
|
printf(" BRAM: %lld KB\n", val / 1024);
|
||||||
|
if (ftr & SYS_REG_INFO_HAS_DRAM) {
|
||||||
|
val = readq(SYSCON_BASE + SYS_REG_DRAMINFO);
|
||||||
|
printf(" DRAM: %lld MB\n", val / (1024 * 1024));
|
||||||
|
}
|
||||||
|
val = readq(SYSCON_BASE + SYS_REG_CLKINFO);
|
||||||
|
printf(" CLK: %lld MHz\n", val / 1000000);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
if (ftr & SYS_REG_INFO_HAS_DRAM) {
|
||||||
|
printf("LiteDRAM built from Migen %s and LiteX %s\n",
|
||||||
|
MIGEN_GIT_SHA1, LITEX_GIT_SHA1);
|
||||||
|
sdrinit();
|
||||||
|
}
|
||||||
|
printf("Booting from BRAM...\n");
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0xffff0000;
|
||||||
|
start = .;
|
||||||
|
.head : {
|
||||||
|
KEEP(*(.head))
|
||||||
|
}
|
||||||
|
. = 0xffff1000;
|
||||||
|
.text : { *(.text*) *(.sfpr) *(.rodata*) }
|
||||||
|
.data : { *(.data*) }
|
||||||
|
.bss : { *(.bss*) }
|
||||||
|
}
|
@ -0,0 +1,303 @@
|
|||||||
|
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;
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
|
||||||
|
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_init_in : wishbone_master_out;
|
||||||
|
signal wb_init_out : wishbone_slave_out;
|
||||||
|
|
||||||
|
type state_t is (CMD, MWRITE, MREAD, CSR);
|
||||||
|
signal state : state_t;
|
||||||
|
|
||||||
|
constant INIT_RAM_SIZE : integer := 16384;
|
||||||
|
constant INIT_RAM_ABITS :integer := 14;
|
||||||
|
constant INIT_RAM_FILE : string := "litedram_core.init";
|
||||||
|
|
||||||
|
type ram_t is array(0 to (INIT_RAM_SIZE / 8) - 1) of std_logic_vector(63 downto 0);
|
||||||
|
|
||||||
|
impure function init_load_ram(name : string) return ram_t is
|
||||||
|
file ram_file : text open read_mode is name;
|
||||||
|
variable temp_word : std_logic_vector(63 downto 0);
|
||||||
|
variable temp_ram : ram_t := (others => (others => '0'));
|
||||||
|
variable ram_line : line;
|
||||||
|
begin
|
||||||
|
for i in 0 to (INIT_RAM_SIZE/8)-1 loop
|
||||||
|
exit when endfile(ram_file);
|
||||||
|
readline(ram_file, ram_line);
|
||||||
|
hread(ram_line, temp_word);
|
||||||
|
temp_ram(i) := temp_word;
|
||||||
|
end loop;
|
||||||
|
return temp_ram;
|
||||||
|
end function;
|
||||||
|
|
||||||
|
signal init_ram : ram_t := init_load_ram(INIT_RAM_FILE);
|
||||||
|
|
||||||
|
attribute ram_style : string;
|
||||||
|
attribute ram_style of init_ram: signal is "block";
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
-- BRAM Memory slave
|
||||||
|
init_ram_0: process(system_clk)
|
||||||
|
variable adr : integer;
|
||||||
|
begin
|
||||||
|
if rising_edge(system_clk) then
|
||||||
|
wb_init_out.ack <= '0';
|
||||||
|
if (wb_init_in.cyc and wb_init_in.stb) = '1' then
|
||||||
|
adr := to_integer((unsigned(wb_init_in.adr(INIT_RAM_ABITS-1 downto 3))));
|
||||||
|
if wb_init_in.we = '0' then
|
||||||
|
wb_init_out.dat <= init_ram(adr);
|
||||||
|
else
|
||||||
|
for i in 0 to 7 loop
|
||||||
|
if wb_init_in.sel(i) = '1' then
|
||||||
|
init_ram(adr)(((i + 1) * 8) - 1 downto i * 8) <=
|
||||||
|
wb_init_in.dat(((i + 1) * 8) - 1 downto i * 8);
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
end if;
|
||||||
|
wb_init_out.ack <= not wb_init_out.ack;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
wb_init_in.adr <= wb_in.adr;
|
||||||
|
wb_init_in.dat <= wb_in.dat;
|
||||||
|
wb_init_in.sel <= wb_in.sel;
|
||||||
|
wb_init_in.we <= wb_in.we;
|
||||||
|
wb_init_in.stb <= wb_in.stb;
|
||||||
|
wb_init_in.cyc <= wb_in.cyc and wb_is_init;
|
||||||
|
|
||||||
|
-- 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 data 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;
|
||||||
|
|
||||||
|
-- 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';
|
||||||
|
|
||||||
|
-- Wishbone out signals
|
||||||
|
wb_out.ack <= '1' when state = CSR 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_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);
|
||||||
|
-- We don't do pipelining yet.
|
||||||
|
wb_out.stall <= '0' when wb_in.cyc = '0' else not wb_out.ack;
|
||||||
|
|
||||||
|
-- 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
|
||||||
|
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 csr_valid = '1' then
|
||||||
|
state <= CSR;
|
||||||
|
elsif (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;
|
||||||
|
when CSR =>
|
||||||
|
state <= CMD;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
litedram: litedram_core
|
||||||
|
port map(
|
||||||
|
clk => clk_in,
|
||||||
|
rst => rst,
|
||||||
|
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,
|
||||||
|
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_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;
|
@ -0,0 +1,214 @@
|
|||||||
|
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;
|
@ -0,0 +1,303 @@
|
|||||||
|
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;
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
|
||||||
|
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_init_in : wishbone_master_out;
|
||||||
|
signal wb_init_out : wishbone_slave_out;
|
||||||
|
|
||||||
|
type state_t is (CMD, MWRITE, MREAD, CSR);
|
||||||
|
signal state : state_t;
|
||||||
|
|
||||||
|
constant INIT_RAM_SIZE : integer := 16384;
|
||||||
|
constant INIT_RAM_ABITS :integer := 14;
|
||||||
|
constant INIT_RAM_FILE : string := "litedram_core.init";
|
||||||
|
|
||||||
|
type ram_t is array(0 to (INIT_RAM_SIZE / 8) - 1) of std_logic_vector(63 downto 0);
|
||||||
|
|
||||||
|
impure function init_load_ram(name : string) return ram_t is
|
||||||
|
file ram_file : text open read_mode is name;
|
||||||
|
variable temp_word : std_logic_vector(63 downto 0);
|
||||||
|
variable temp_ram : ram_t := (others => (others => '0'));
|
||||||
|
variable ram_line : line;
|
||||||
|
begin
|
||||||
|
for i in 0 to (INIT_RAM_SIZE/8)-1 loop
|
||||||
|
exit when endfile(ram_file);
|
||||||
|
readline(ram_file, ram_line);
|
||||||
|
hread(ram_line, temp_word);
|
||||||
|
temp_ram(i) := temp_word;
|
||||||
|
end loop;
|
||||||
|
return temp_ram;
|
||||||
|
end function;
|
||||||
|
|
||||||
|
signal init_ram : ram_t := init_load_ram(INIT_RAM_FILE);
|
||||||
|
|
||||||
|
attribute ram_style : string;
|
||||||
|
attribute ram_style of init_ram: signal is "block";
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
-- BRAM Memory slave
|
||||||
|
init_ram_0: process(system_clk)
|
||||||
|
variable adr : integer;
|
||||||
|
begin
|
||||||
|
if rising_edge(system_clk) then
|
||||||
|
wb_init_out.ack <= '0';
|
||||||
|
if (wb_init_in.cyc and wb_init_in.stb) = '1' then
|
||||||
|
adr := to_integer((unsigned(wb_init_in.adr(INIT_RAM_ABITS-1 downto 3))));
|
||||||
|
if wb_init_in.we = '0' then
|
||||||
|
wb_init_out.dat <= init_ram(adr);
|
||||||
|
else
|
||||||
|
for i in 0 to 7 loop
|
||||||
|
if wb_init_in.sel(i) = '1' then
|
||||||
|
init_ram(adr)(((i + 1) * 8) - 1 downto i * 8) <=
|
||||||
|
wb_init_in.dat(((i + 1) * 8) - 1 downto i * 8);
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
end if;
|
||||||
|
wb_init_out.ack <= not wb_init_out.ack;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
wb_init_in.adr <= wb_in.adr;
|
||||||
|
wb_init_in.dat <= wb_in.dat;
|
||||||
|
wb_init_in.sel <= wb_in.sel;
|
||||||
|
wb_init_in.we <= wb_in.we;
|
||||||
|
wb_init_in.stb <= wb_in.stb;
|
||||||
|
wb_init_in.cyc <= wb_in.cyc and wb_is_init;
|
||||||
|
|
||||||
|
-- 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 data 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;
|
||||||
|
|
||||||
|
-- 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';
|
||||||
|
|
||||||
|
-- Wishbone out signals
|
||||||
|
wb_out.ack <= '1' when state = CSR 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_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);
|
||||||
|
-- We don't do pipelining yet.
|
||||||
|
wb_out.stall <= '0' when wb_in.cyc = '0' else not wb_out.ack;
|
||||||
|
|
||||||
|
-- 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
|
||||||
|
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 csr_valid = '1' then
|
||||||
|
state <= CSR;
|
||||||
|
elsif (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;
|
||||||
|
when CSR =>
|
||||||
|
state <= CMD;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
litedram: litedram_core
|
||||||
|
port map(
|
||||||
|
clk => clk_in,
|
||||||
|
rst => rst,
|
||||||
|
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,
|
||||||
|
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_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;
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -0,0 +1,303 @@
|
|||||||
|
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;
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
|
||||||
|
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_init_in : wishbone_master_out;
|
||||||
|
signal wb_init_out : wishbone_slave_out;
|
||||||
|
|
||||||
|
type state_t is (CMD, MWRITE, MREAD, CSR);
|
||||||
|
signal state : state_t;
|
||||||
|
|
||||||
|
constant INIT_RAM_SIZE : integer := 16384;
|
||||||
|
constant INIT_RAM_ABITS :integer := 14;
|
||||||
|
constant INIT_RAM_FILE : string := "litedram_core.init";
|
||||||
|
|
||||||
|
type ram_t is array(0 to (INIT_RAM_SIZE / 8) - 1) of std_logic_vector(63 downto 0);
|
||||||
|
|
||||||
|
impure function init_load_ram(name : string) return ram_t is
|
||||||
|
file ram_file : text open read_mode is name;
|
||||||
|
variable temp_word : std_logic_vector(63 downto 0);
|
||||||
|
variable temp_ram : ram_t := (others => (others => '0'));
|
||||||
|
variable ram_line : line;
|
||||||
|
begin
|
||||||
|
for i in 0 to (INIT_RAM_SIZE/8)-1 loop
|
||||||
|
exit when endfile(ram_file);
|
||||||
|
readline(ram_file, ram_line);
|
||||||
|
hread(ram_line, temp_word);
|
||||||
|
temp_ram(i) := temp_word;
|
||||||
|
end loop;
|
||||||
|
return temp_ram;
|
||||||
|
end function;
|
||||||
|
|
||||||
|
signal init_ram : ram_t := init_load_ram(INIT_RAM_FILE);
|
||||||
|
|
||||||
|
attribute ram_style : string;
|
||||||
|
attribute ram_style of init_ram: signal is "block";
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
-- BRAM Memory slave
|
||||||
|
init_ram_0: process(system_clk)
|
||||||
|
variable adr : integer;
|
||||||
|
begin
|
||||||
|
if rising_edge(system_clk) then
|
||||||
|
wb_init_out.ack <= '0';
|
||||||
|
if (wb_init_in.cyc and wb_init_in.stb) = '1' then
|
||||||
|
adr := to_integer((unsigned(wb_init_in.adr(INIT_RAM_ABITS-1 downto 3))));
|
||||||
|
if wb_init_in.we = '0' then
|
||||||
|
wb_init_out.dat <= init_ram(adr);
|
||||||
|
else
|
||||||
|
for i in 0 to 7 loop
|
||||||
|
if wb_init_in.sel(i) = '1' then
|
||||||
|
init_ram(adr)(((i + 1) * 8) - 1 downto i * 8) <=
|
||||||
|
wb_init_in.dat(((i + 1) * 8) - 1 downto i * 8);
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
end if;
|
||||||
|
wb_init_out.ack <= not wb_init_out.ack;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
wb_init_in.adr <= wb_in.adr;
|
||||||
|
wb_init_in.dat <= wb_in.dat;
|
||||||
|
wb_init_in.sel <= wb_in.sel;
|
||||||
|
wb_init_in.we <= wb_in.we;
|
||||||
|
wb_init_in.stb <= wb_in.stb;
|
||||||
|
wb_init_in.cyc <= wb_in.cyc and wb_is_init;
|
||||||
|
|
||||||
|
-- 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 data 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;
|
||||||
|
|
||||||
|
-- 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';
|
||||||
|
|
||||||
|
-- Wishbone out signals
|
||||||
|
wb_out.ack <= '1' when state = CSR 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_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);
|
||||||
|
-- We don't do pipelining yet.
|
||||||
|
wb_out.stall <= '0' when wb_in.cyc = '0' else not wb_out.ack;
|
||||||
|
|
||||||
|
-- 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
|
||||||
|
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 csr_valid = '1' then
|
||||||
|
state <= CSR;
|
||||||
|
elsif (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;
|
||||||
|
when CSR =>
|
||||||
|
state <= CMD;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
litedram: litedram_core
|
||||||
|
port map(
|
||||||
|
clk => clk_in,
|
||||||
|
rst => rst,
|
||||||
|
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,
|
||||||
|
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_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;
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -0,0 +1,15 @@
|
|||||||
|
CAPI=2:
|
||||||
|
|
||||||
|
name : :microwatt:litedram:0
|
||||||
|
|
||||||
|
generators:
|
||||||
|
litedram_gen:
|
||||||
|
interpreter: python3
|
||||||
|
command: extras/fusesoc-add-files.py
|
||||||
|
description: Generate a litedram memory controller
|
||||||
|
usage: |
|
||||||
|
litedram_gen adds the pre-generated LiteX LiteDRAM memory controller
|
||||||
|
based on the board type.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
board: The board type (arty, nexys_video)
|
@ -0,0 +1,136 @@
|
|||||||
|
-- syscon module, a bunch of misc global system control MMIO registers
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.wishbone_types.all;
|
||||||
|
|
||||||
|
entity syscon is
|
||||||
|
generic (
|
||||||
|
SIG_VALUE : std_ulogic_vector(63 downto 0) := x"f00daa5500010001";
|
||||||
|
CLK_FREQ : integer;
|
||||||
|
HAS_UART : boolean;
|
||||||
|
HAS_DRAM : boolean;
|
||||||
|
BRAM_SIZE : integer;
|
||||||
|
DRAM_SIZE : integer
|
||||||
|
);
|
||||||
|
port (
|
||||||
|
clk : in std_ulogic;
|
||||||
|
rst : in std_ulogic;
|
||||||
|
|
||||||
|
-- Wishbone ports:
|
||||||
|
wishbone_in : in wishbone_master_out;
|
||||||
|
wishbone_out : out wishbone_slave_out;
|
||||||
|
|
||||||
|
-- System control ports
|
||||||
|
dram_at_0 : out std_ulogic;
|
||||||
|
core_reset : out std_ulogic;
|
||||||
|
soc_reset : out std_ulogic
|
||||||
|
);
|
||||||
|
end entity syscon;
|
||||||
|
|
||||||
|
|
||||||
|
architecture behaviour of syscon is
|
||||||
|
-- Register address bits
|
||||||
|
constant SYS_REG_BITS : positive := 3;
|
||||||
|
|
||||||
|
-- Register addresses (matches wishbone addr downto 3, ie, 8 bytes per reg)
|
||||||
|
constant SYS_REG_SIG : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000";
|
||||||
|
constant SYS_REG_INFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "001";
|
||||||
|
constant SYS_REG_BRAMINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "010";
|
||||||
|
constant SYS_REG_DRAMINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "011";
|
||||||
|
constant SYS_REG_CLKINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "100";
|
||||||
|
constant SYS_REG_CTRL : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "101";
|
||||||
|
|
||||||
|
-- INFO register bits
|
||||||
|
constant SYS_REG_INFO_HAS_UART : integer := 0;
|
||||||
|
constant SYS_REG_INFO_HAS_DRAM : integer := 1;
|
||||||
|
|
||||||
|
-- BRAMINFO contains the BRAM size in the bottom 52 bits
|
||||||
|
-- DRAMINFO contains the DRAM size if any in the bottom 52 bits
|
||||||
|
-- (both have reserved top bits for future use)
|
||||||
|
-- CLKINFO contains the CLK frequency is HZ in the bottom 40 bits
|
||||||
|
|
||||||
|
-- CTRL register bits
|
||||||
|
constant SYS_REG_CTRL_BITS : positive := 3;
|
||||||
|
constant SYS_REG_CTRL_DRAM_AT_0 : integer := 0;
|
||||||
|
constant SYS_REG_CTRL_CORE_RESET : integer := 1;
|
||||||
|
constant SYS_REG_CTRL_SOC_RESET : integer := 2;
|
||||||
|
|
||||||
|
-- Ctrl register
|
||||||
|
signal reg_ctrl : std_ulogic_vector(SYS_REG_CTRL_BITS-1 downto 0);
|
||||||
|
signal reg_ctrl_out : std_ulogic_vector(63 downto 0);
|
||||||
|
|
||||||
|
-- Others
|
||||||
|
signal reg_info : std_ulogic_vector(63 downto 0);
|
||||||
|
signal reg_braminfo : std_ulogic_vector(63 downto 0);
|
||||||
|
signal reg_draminfo : std_ulogic_vector(63 downto 0);
|
||||||
|
signal reg_clkinfo : std_ulogic_vector(63 downto 0);
|
||||||
|
signal info_has_dram : std_ulogic;
|
||||||
|
signal info_has_uart : std_ulogic;
|
||||||
|
signal info_clk : std_ulogic_vector(39 downto 0);
|
||||||
|
begin
|
||||||
|
|
||||||
|
-- Generated output signals
|
||||||
|
dram_at_0 <= reg_ctrl(SYS_REG_CTRL_DRAM_AT_0);
|
||||||
|
soc_reset <= reg_ctrl(SYS_REG_CTRL_SOC_RESET);
|
||||||
|
core_reset <= reg_ctrl(SYS_REG_CTRL_CORE_RESET);
|
||||||
|
|
||||||
|
-- All register accesses are single cycle
|
||||||
|
wishbone_out.ack <= wishbone_in.cyc and wishbone_in.stb;
|
||||||
|
wishbone_out.stall <= '0';
|
||||||
|
|
||||||
|
-- Info register is hard wired
|
||||||
|
info_has_uart <= '1' when HAS_UART else '0';
|
||||||
|
info_has_dram <= '1' when HAS_DRAM else '0';
|
||||||
|
info_clk <= std_ulogic_vector(to_unsigned(CLK_FREQ, 40));
|
||||||
|
reg_info <= (0 => info_has_uart,
|
||||||
|
1 => info_has_dram,
|
||||||
|
others => '0');
|
||||||
|
reg_braminfo <= x"000" & std_ulogic_vector(to_unsigned(BRAM_SIZE, 52));
|
||||||
|
reg_draminfo <= x"000" & std_ulogic_vector(to_unsigned(DRAM_SIZE, 52)) when HAS_DRAM
|
||||||
|
else (others => '0');
|
||||||
|
reg_clkinfo <= (39 downto 0 => info_clk,
|
||||||
|
others => '0');
|
||||||
|
|
||||||
|
-- Control register read composition
|
||||||
|
reg_ctrl_out <= (63 downto SYS_REG_CTRL_BITS => '0',
|
||||||
|
SYS_REG_CTRL_BITS-1 downto 0 => reg_ctrl);
|
||||||
|
|
||||||
|
-- Register read mux
|
||||||
|
with wishbone_in.adr(SYS_REG_BITS+2 downto 3) select wishbone_out.dat <=
|
||||||
|
SIG_VALUE when SYS_REG_SIG,
|
||||||
|
reg_info when SYS_REG_INFO,
|
||||||
|
reg_braminfo when SYS_REG_BRAMINFO,
|
||||||
|
reg_draminfo when SYS_REG_DRAMINFO,
|
||||||
|
reg_clkinfo when SYS_REG_CLKINFO,
|
||||||
|
reg_ctrl_out when SYS_REG_CTRL,
|
||||||
|
(others => '0') when others;
|
||||||
|
|
||||||
|
-- Register writes
|
||||||
|
regs_write: process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if (rst) then
|
||||||
|
reg_ctrl <= (others => '0');
|
||||||
|
else
|
||||||
|
if wishbone_in.cyc and wishbone_in.stb and wishbone_in.we then
|
||||||
|
if wishbone_in.adr(SYS_REG_BITS+2 downto 3) = SYS_REG_CTRL then
|
||||||
|
reg_ctrl(SYS_REG_CTRL_BITS-1 downto 0) <=
|
||||||
|
wishbone_in.dat(SYS_REG_CTRL_BITS-1 downto 0);
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
-- Reset auto-clear
|
||||||
|
if reg_ctrl(SYS_REG_CTRL_SOC_RESET) = '1' then
|
||||||
|
reg_ctrl(SYS_REG_CTRL_SOC_RESET) <= '0';
|
||||||
|
end if;
|
||||||
|
if reg_ctrl(SYS_REG_CTRL_CORE_RESET) = '1' then
|
||||||
|
reg_ctrl(SYS_REG_CTRL_CORE_RESET) <= '0';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end architecture behaviour;
|
Loading…
Reference in New Issue