Start work on iCE40 chipdb

Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
Clifford Wolf 2018-05-26 14:27:21 +02:00
parent 1338f0f9eb
commit 1899833b4d
8 changed files with 438 additions and 9 deletions

3
.gitignore vendored
View File

@ -1,2 +1,3 @@
/build/
/objs/
/nextpnr-dummy
/nextpnr-ice40

View File

@ -2,6 +2,11 @@ archs = dummy
common_objs = design.o
dummy_objs = chip.o main.o
all::
clean::
include ice40/makefile.inc
CXX = clang
CXXFLAGS = -ggdb -MD -std=c++11 -O2 -Icommon
LDFLAGS = -ggdb
@ -10,21 +15,21 @@ LDLIBS = -lstdc++
define binaries
all:: nextpnr-$(1)
nextpnr-$(1): $$(addprefix build/$(1)-common-,$$(common_objs)) $$(addprefix build/$(1)-arch-,$$($(1)_objs))
nextpnr-$(1): $$(addprefix objs/$(1)-common-,$$(common_objs)) $$(addprefix objs/$(1)-arch-,$$($(1)_objs))
$$(CXX) -o $$@ $$(LDFLAGS) -I$(1) $$^ $$(LDLIBS)
build/$(1)-common-%.o: common/%.cc
@mkdir -p build
objs/$(1)-common-%.o: common/%.cc
@mkdir -p objs
$$(CXX) -c -o $$@ -D$$(shell echo arch_$(1) | tr a-z A-Z) $$(CXXFLAGS) -I$(1) $$<
build/$(1)-arch-%.o: $(1)/%.cc
@mkdir -p build
objs/$(1)-arch-%.o: $(1)/%.cc
@mkdir -p objs
$$(CXX) -c -o $$@ -D$$(shell echo arch_$(1) | tr a-z A-Z) $$(CXXFLAGS) -I$(1) $$<
endef
$(foreach arch,$(archs),$(eval $(call binaries,$(arch))))
clean:
rm -rf $(addprefix nextpnr-,$(archs)) build
clean::
rm -rf $(addprefix nextpnr-,$(archs)) objs
-include build/*.d
-include objs/*.d

4
ice40/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/chipdb-1k.cc
/chipdb-384.cc
/chipdb-5k.cc
/chipdb-8k.cc

34
ice40/chip.cc Normal file
View File

@ -0,0 +1,34 @@
/*
* nextpnr -- Next Generation Place and Route
*
* Copyright (C) 2018 Clifford Wolf <clifford@clifford.at>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include "chip.h"
Chip::Chip(ChipArgs)
{
}
BelRange Chip::getBels() const
{
return BelRange();
}
IdString Chip::getBelName(BelId bel) const
{
return "*unknown*";
}

224
ice40/chip.h Normal file
View File

@ -0,0 +1,224 @@
/*
* nextpnr -- Next Generation Place and Route
*
* Copyright (C) 2018 Clifford Wolf <clifford@clifford.at>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include "design.h"
#ifndef CHIP_H
#define CHIP_H
struct BelId
{
int32_t index = -1;
bool nil() const {
return index < 0;
}
};
struct WireId
{
int32_t index = -1;
bool nil() const {
return index < 0;
}
};
namespace std
{
template<> struct hash<BelId>
{
std::size_t operator()(const BelId &bel) const noexcept
{
return bel.index;
}
};
template<> struct hash<WireId>
{
std::size_t operator()(const WireId &wire) const noexcept
{
return wire.index;
}
};
}
struct BelIterator
{
BelId *ptr = nullptr;
void operator++() { ptr++; }
bool operator!=(const BelIterator &other) const { return ptr != other.ptr; }
BelId operator*() const { return *ptr; }
};
struct BelRange
{
BelIterator b, e;
BelIterator begin() const { return b; }
BelIterator end() const { return e; }
};
struct WireIterator
{
WireId *ptr = nullptr;
void operator++() { ptr++; }
bool operator!=(const WireIterator &other) const { return ptr != other.ptr; }
WireId operator*() const { return *ptr; }
};
struct WireRange
{
WireIterator b, e;
WireIterator begin() const { return b; }
WireIterator end() const { return e; }
};
struct WireDelay
{
WireId wire;
float delay;
};
struct WireDelayIterator
{
WireDelay *ptr = nullptr;
void operator++() { ptr++; }
bool operator!=(const WireDelayIterator &other) const { return ptr != other.ptr; }
WireDelay operator*() const { return *ptr; }
};
struct WireDelayRange
{
WireDelayIterator b, e;
WireDelayIterator begin() const { return b; }
WireDelayIterator end() const { return e; }
};
struct BelPin
{
BelId bel;
IdString pin;
};
struct BelPinIterator
{
BelPin *ptr = nullptr;
void operator++() { ptr++; }
bool operator!=(const BelPinIterator &other) const { return ptr != other.ptr; }
BelPin operator*() const { return *ptr; }
};
struct BelPinRange
{
BelPinIterator b, e;
BelPinIterator begin() const { return b; }
BelPinIterator end() const { return e; }
};
struct GuiLine
{
float x1, y1, x2, y2;
};
struct ChipArgs
{
enum {
NONE,
LP384,
LP1K,
LP8K,
HX1K,
HX8K,
UP5K
} type = NONE;
};
struct BelInfo
{
const char *name;
};
struct WireDelayPOD
{
int32_t wire_index;
float delay;
};
struct BelPortPOD
{
int32_t bel_index;
int port_index;
};
struct WireInfo
{
const char *name;
int num_uphill, num_downhill, num_bidir;
WireDelayPOD *wires_uphill, *wires_downhill, *wires_bidir;
int num_bels_downhill;
BelPortPOD bel_uphill;
BelPortPOD *bels_downhill;
};
struct Chip
{
int num_bels, num_wires;
BelInfo *bel_data;
WireInfo *wire_data;
// ...
Chip(ChipArgs args);
void setBelActive(BelId bel, bool active);
bool getBelActive(BelId bel);
BelId getBelByName(IdString name) const;
WireId getWireByName(IdString name) const;
IdString getBelName(BelId bel) const;
IdString getWireName(WireId wire) const;
BelRange getBels() const;
BelRange getBelsByType(IdString type) const;
IdString getBelType(BelId bel) const;
void getBelPosition(BelId bel, float &x, float &y) const;
void getWirePosition(WireId wire, float &x, float &y) const;
vector<GuiLine> getBelGuiLines(BelId bel) const;
vector<GuiLine> getWireGuiLines(WireId wire) const;
WireRange getWires() const;
WireDelayRange getWiresUphill(WireId wire) const;
WireDelayRange getWiresDownhill(WireId wire) const;
WireDelayRange getWiresBidir(WireId wire) const;
WireDelayRange getWireAliases(WireId wire) const;
// the following will only operate on / return "active" BELs
// multiple active uphill BELs for a wire will cause a runtime error
WireId getWireBelPin(BelId bel, IdString pin) const;
BelPin getBelPinUphill(WireId wire) const;
BelPinRange getBelPinsDownhill(WireId wire) const;
};
#endif

114
ice40/chipdb.py Normal file
View File

@ -0,0 +1,114 @@
#!/usr/bin/env python3
import sys
dev_name = None
dev_width = None
dev_height = None
num_wires = None
wire_uphill = dict()
wire_downhill = dict()
wire_bidir = dict()
with open(sys.argv[1], "r") as f:
mode = None
for line in f:
line = line.split()
if len(line) == 0 or line[0] == "#":
continue
if line[0] == ".device":
dev_name = line[1]
dev_width = int(line[2])
dev_height = int(line[3])
num_wires = int(line[4])
continue
if line[0] == ".net":
mode = ("net", int(line[1]))
continue
if line[0] == ".buffer":
mode = ("buffer", int(line[3]))
continue
if line[0] == ".routing":
mode = ("routing", int(line[3]))
continue
if (line[0][0] == ".") or (mode is None):
mode = None
continue
if mode[0] == "net":
continue
if mode[0] == "buffer":
wire_a = int(line[1])
wire_b = mode[1]
if wire_a not in wire_downhill:
wire_downhill[wire_a] = set()
if wire_b not in wire_uphill:
wire_uphill[wire_b] = set()
wire_downhill[wire_a].add(wire_b)
wire_uphill[wire_b].add(wire_a)
continue
if mode[0] == "routing":
wire_a = int(line[1])
wire_b = mode[1]
if wire_a not in wire_bidir:
wire_bidir[wire_a] = set()
if wire_b not in wire_bidir:
wire_bidir[wire_b] = set()
wire_bidir[wire_a].add(wire_b)
wire_bidir[wire_b].add(wire_b)
continue
print('#include "chip.h"')
wireinfo = list()
for wire in range(num_wires):
num_uphill = 0
num_downhill = 0
num_bidir = 0
has_bel_uphill = False
num_bels_downhill = 0
if wire in wire_uphill:
num_uphill = len(wire_uphill[wire])
print("static WireDelayPOD wire%d_uphill[] = {" % wire)
print(",\n".join([" {%d, 1.0}" % other_wire for other_wire in wire_uphill[wire]]))
print("};")
if wire in wire_downhill:
num_downhill = len(wire_downhill[wire])
print("static WireDelayPOD wire%d_downhill[] = {" % wire)
print(",\n".join([" {%d, 1.0}" % other_wire for other_wire in wire_downhill[wire]]))
print("};")
if wire in wire_bidir:
num_bidir = len(wire_bidir[wire])
print("static WireDelayPOD wire%d_bidir[] = {" % wire)
print(",\n".join([" {%d, 1.0}" % other_wire for other_wire in wire_bidir[wire]]))
print("};")
info = " {"
info += "\"wire%d\", " % wire
info += "%d, %d, %d, " % (num_uphill, num_downhill, num_bidir)
info += ("wire%d_uphill, " % wire) if num_uphill > 0 else "nullptr, "
info += ("wire%d_downhill, " % wire) if num_downhill > 0 else "nullptr, "
info += ("wire%d_bidir, " % wire) if num_bidir > 0 else "nullptr, "
info += "}"
wireinfo.append(info)
print("extern WireInfo wire_data_%s[%d];" % (dev_name, num_wires))
print("WireInfo wire_data_%s[%d] = {" % (dev_name, num_wires))
print(",\n".join(wireinfo))
print("};")

30
ice40/main.cc Normal file
View File

@ -0,0 +1,30 @@
/*
* nextpnr -- Next Generation Place and Route
*
* Copyright (C) 2018 Clifford Wolf <clifford@clifford.at>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include "design.h"
int main()
{
Design design(ChipArgs{});
for (auto bel : design.chip.getBels())
printf("%s\n", design.chip.getBelName(bel).c_str());
return 0;
}

17
ice40/makefile.inc Normal file
View File

@ -0,0 +1,17 @@
archs += ice40
ice40_objs = chip.o main.o
define ice40_chipdb
ice40_objs += chipdb-$(1).o
ice40/chipdb-$(1).cc: ice40/chipdb.py /usr/local/share/icebox/chipdb-$(1).txt
python3 ice40/chipdb.py /usr/local/share/icebox/chipdb-$(1).txt > ice40/chipdb-$(1).cc.new
mv ice40/chipdb-$(1).cc.new ice40/chipdb-$(1).cc
clean::
rm -f ice40/chipdb-$(1).cc
endef
$(eval $(call ice40_chipdb,384))
$(eval $(call ice40_chipdb,1k))
$(eval $(call ice40_chipdb,5k))
$(eval $(call ice40_chipdb,8k))