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
parent
31b55b2a75
commit
982cf166dd
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 @@
|
||||
vexriscv
|
@ -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 @@
|
||||
vexriscv
|
@ -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)
|
Loading…
Reference in New Issue