litedram: Add basic support for LiteX LiteDRAM

This comes in two parts:

 - A generator script which uses LiteX to generate litedram cores
along with their init files for various boards (currently Arty and
Nexys-video). This comes with configs for arty and nexys_video.

 - A fusesoc "generator" which uses pre-generated litedram cores

The generation process is manual on purpose. This include pre-generated
cores for the two above boards.

This is done so that one doesn't have to install LiteX to build
microwatt. In addition, the generator script or wrapper vhdl tend to
break when LiteX changes significantly which happens.

This is still rather standalone and hasn't been plumbed into the SoC
or the FPGA toplevel files yet.

At this point LiteDRAM self-initializes using a built-in VexRiscv
"Minimum" core obtained from LiteX and included in this commit. There
is some plumbing to generate and cores that are initialized by Microwatt
directly but this isn't working yet and so isn't enabled yet.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
pull/170/head
Benjamin Herrenschmidt 5 years ago
parent 31b55b2a75
commit 982cf166dd

@ -152,11 +152,21 @@ TAGS:

.PHONY: TAGS

clean:
_clean:
rm -f *.o work-*cf unisim-*cf $(all)
rm -f fpga/*.o fpga/work-*cf
rm -f sim-unisim/*.o sim-unisim/unisim-*cf
rm -f TAGS
rm -f scripts/mw_debug/*.o
rm -f scripts/mw_debug/mw_debug

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

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

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,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": "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
}

@ -0,0 +1,150 @@
#!/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(build_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", gen_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):

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])

# 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)

# 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 cpu is None:
print("Microwatt based inits not supported yet !")
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']
for t in targets:
generate_one(t)

# 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
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 ($(VERBOSE),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,3 @@
static inline void flush_cpu_dcache(void) { }
static inline void flush_l2_cache(void) { }

@ -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,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,162 @@
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
#include <stdio.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
#define UART_BASE 0xc0002000
#define SYSCON_BASE 0xc0000000

#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

static inline uint8_t readb(unsigned long addr)
{
__asm__ volatile("sync" : : : "memory");
return *((volatile uint8_t *)addr);
}

static inline uint64_t readq(unsigned long addr)
{
__asm__ volatile("sync" : : : "memory");
return *((volatile uint64_t *)addr);
}

static inline void writeb(uint8_t val, unsigned long addr)
{
__asm__ volatile("sync" : : : "memory");
*((volatile uint8_t *)addr) = val;
}

static inline void writeq(uint64_t val, unsigned long addr)
{
__asm__ volatile("sync" : : : "memory");
*((volatile uint64_t *)addr) = val;
}

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)
{
int i;

// Let things settle ... not sure why but UART not happy otherwise
potato_uart_init();
for (i = 0; i < 10000; i++)
potato_uart_reg_read(POTATO_CONSOLE_STATUS);
printf("Welcome to Microwatt !\n");
printf(" SIG: %016llx\n", (unsigned long long)readq(SYSCON_BASE + 0x00));
printf(" INFO: %016llx\n", (unsigned long long)readq(SYSCON_BASE + 0x08));
printf(" BRAMINFO: %016llx\n", (unsigned long long)readq(SYSCON_BASE + 0x10));
printf(" DRAMINFO: %016llx\n", (unsigned long long)readq(SYSCON_BASE + 0x18));
printf(" CTRL: %016llx\n", (unsigned long long)readq(SYSCON_BASE + 0x20));
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 : out std_ulogic_vector(1 downto 0);
ddram_dqs_n : out 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 : out std_ulogic_vector(1 downto 0);
ddram_dqs_n : out 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(7 downto 0);
csr_port0_dat_r : out std_ulogic_vector(7 downto 0);
user_port0_cmd_valid : in std_ulogic;
user_port0_cmd_ready : out std_ulogic;
user_port0_cmd_we : in std_ulogic;
user_port0_cmd_addr : in std_ulogic_vector(DRAM_ABITS-1 downto 0);
user_port0_wdata_valid : in std_ulogic;
user_port0_wdata_ready : out std_ulogic;
user_port0_wdata_we : in std_ulogic_vector(15 downto 0);
user_port0_wdata_data : in std_ulogic_vector(127 downto 0);
user_port0_rdata_valid : out std_ulogic;
user_port0_rdata_ready : in std_ulogic;
user_port0_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(7 downto 0);
signal csr_port0_dat_r : std_ulogic_vector(7 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 := "sdram_init.hex";

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 3) & '0' when wb_is_csr = '1' else (others => '0');
csr_port0_dat_w <= wb_in.dat(7 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"00000000000000" & 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_port0_cmd_valid => user_port0_cmd_valid,
user_port0_cmd_ready => user_port0_cmd_ready,
user_port0_cmd_we => user_port0_cmd_we,
user_port0_cmd_addr => user_port0_cmd_addr,
user_port0_wdata_valid => user_port0_wdata_valid,
user_port0_wdata_ready => user_port0_wdata_ready,
user_port0_wdata_we => user_port0_wdata_we,
user_port0_wdata_data => user_port0_wdata_data,
user_port0_rdata_valid => user_port0_rdata_valid,
user_port0_rdata_ready => user_port0_rdata_ready,
user_port0_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,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;

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -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;

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)

@ -87,6 +87,9 @@ filesets:
- fpga/cmod_a7-35.xdc : {file_type : xdc}
- fpga/clk_gen_mcmm.vhd : {file_type : vhdlSource-2008}

litedram:
depend : [":microwatt:litedram"]

targets:
nexys_a7:
default_tool: vivado
@ -194,3 +197,9 @@ parameters:
description : Prevent Vivado from flattening the main core components
paramtype : generic
default : false

use_litedram:
datatype : bool
description : Use liteDRAM
paramtype : generic
default : false

@ -5,3 +5,8 @@ all: mw_debug
mw_debug: mw_debug.c
$(CC) -o $@ $^ -lurjtag

clean:
rm -f mw_debug
distclean:
rm -f *~


Loading…
Cancel
Save