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