Start work on iCE40 chipdb
Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
parent
1338f0f9eb
commit
1899833b4d
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
/build/
|
||||
/objs/
|
||||
/nextpnr-dummy
|
||||
/nextpnr-ice40
|
||||
|
21
Makefile
21
Makefile
@ -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
4
ice40/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/chipdb-1k.cc
|
||||
/chipdb-384.cc
|
||||
/chipdb-5k.cc
|
||||
/chipdb-8k.cc
|
34
ice40/chip.cc
Normal file
34
ice40/chip.cc
Normal 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
224
ice40/chip.h
Normal 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
114
ice40/chipdb.py
Normal 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
30
ice40/main.cc
Normal 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
17
ice40/makefile.inc
Normal 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))
|
Loading…
Reference in New Issue
Block a user