Merge branch 'master' into gqtech
This commit is contained in:
commit
5e463b8543
@ -21,6 +21,7 @@
|
|||||||
#define DESIGN_H
|
#define DESIGN_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
@ -36,11 +36,6 @@
|
|||||||
void arch_wrap_python();
|
void arch_wrap_python();
|
||||||
|
|
||||||
BOOST_PYTHON_MODULE (MODULE_NAME) {
|
BOOST_PYTHON_MODULE (MODULE_NAME) {
|
||||||
// From Chip.h
|
|
||||||
WRAP_RANGE(Bel);
|
|
||||||
WRAP_RANGE(WireDelay);
|
|
||||||
WRAP_RANGE(BelPin);
|
|
||||||
|
|
||||||
arch_wrap_python();
|
arch_wrap_python();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,13 +22,3 @@
|
|||||||
Chip::Chip(ChipArgs)
|
Chip::Chip(ChipArgs)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
BelRange Chip::getBels() const
|
|
||||||
{
|
|
||||||
return BelRange();
|
|
||||||
}
|
|
||||||
|
|
||||||
IdString Chip::getBelName(BelId bel) const
|
|
||||||
{
|
|
||||||
return "*unknown*";
|
|
||||||
}
|
|
||||||
|
178
dummy/chip.h
178
dummy/chip.h
@ -39,104 +39,9 @@ static inline IdString portPinToId(PortPin type) { return type; }
|
|||||||
static inline BelType belTypeFromId(IdString id) { return id; }
|
static inline BelType belTypeFromId(IdString id) { return id; }
|
||||||
static inline PortPin portPinFromId(IdString id) { return id; }
|
static inline PortPin portPinFromId(IdString id) { return id; }
|
||||||
|
|
||||||
struct BelId
|
typedef IdString BelId;
|
||||||
{
|
typedef IdString WireId;
|
||||||
uint8_t tile_x = 0, tile_y = 0;
|
typedef IdString PipId;
|
||||||
uint16_t index = 0;
|
|
||||||
|
|
||||||
bool nil() const {
|
|
||||||
return !tile_x && !tile_y && !index;
|
|
||||||
}
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct WireId
|
|
||||||
{
|
|
||||||
uint8_t tile_x = 0, tile_y = 0;
|
|
||||||
uint16_t index = 0;
|
|
||||||
|
|
||||||
bool nil() const {
|
|
||||||
return !tile_x && !tile_y && !index;
|
|
||||||
}
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
template<> struct hash<BelId>
|
|
||||||
{
|
|
||||||
std::size_t operator()(const BelId &bel) const noexcept
|
|
||||||
{
|
|
||||||
std::size_t result = std::hash<int>{}(bel.index);
|
|
||||||
result ^= std::hash<int>{}(bel.tile_x) + 0x9e3779b9 + (result << 6) + (result >> 2);
|
|
||||||
result ^= std::hash<int>{}(bel.tile_y) + 0x9e3779b9 + (result << 6) + (result >> 2);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct hash<WireId>
|
|
||||||
{
|
|
||||||
std::size_t operator()(const WireId &wire) const noexcept
|
|
||||||
{
|
|
||||||
std::size_t result = std::hash<int>{}(wire.index);
|
|
||||||
result ^= std::hash<int>{}(wire.tile_x) + 0x9e3779b9 + (result << 6) + (result >> 2);
|
|
||||||
result ^= std::hash<int>{}(wire.tile_y) + 0x9e3779b9 + (result << 6) + (result >> 2);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
DelayInfo 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
|
struct BelPin
|
||||||
{
|
{
|
||||||
@ -144,61 +49,54 @@ struct BelPin
|
|||||||
PortPin pin;
|
PortPin 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 ChipArgs
|
struct ChipArgs
|
||||||
{
|
{
|
||||||
// ...
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Chip
|
struct Chip
|
||||||
{
|
{
|
||||||
// ...
|
|
||||||
|
|
||||||
Chip(ChipArgs args);
|
Chip(ChipArgs args);
|
||||||
|
|
||||||
void setBelActive(BelId bel, bool active);
|
|
||||||
bool getBelActive(BelId bel);
|
|
||||||
|
|
||||||
BelId getBelByName(IdString name) const;
|
BelId getBelByName(IdString name) const;
|
||||||
WireId getWireByName(IdString name) const;
|
|
||||||
IdString getBelName(BelId bel) const;
|
IdString getBelName(BelId bel) const;
|
||||||
IdString getWireName(WireId wire) const;
|
void bindBel(BelId bel, IdString cell);
|
||||||
|
void unbindBel(BelId bel);
|
||||||
BelRange getBels() const;
|
bool checkBelAvail(BelId bel) const;
|
||||||
BelRange getBelsByType(BelType type) const;
|
const vector<BelId> &getBels() const;
|
||||||
|
const vector<BelId> &getBelsByType(BelType type) const;
|
||||||
BelType getBelType(BelId bel) const;
|
BelType 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, PortPin pin) const;
|
WireId getWireBelPin(BelId bel, PortPin pin) const;
|
||||||
BelPin getBelPinUphill(WireId wire) const;
|
BelPin getBelPinUphill(WireId wire) const;
|
||||||
BelPinRange getBelPinsDownhill(WireId wire) const;
|
const vector<BelPin> &getBelPinsDownhill(WireId wire) const;
|
||||||
|
|
||||||
|
WireId getWireByName(IdString name) const;
|
||||||
|
IdString getWireName(WireId wire) const;
|
||||||
|
void bindWire(WireId bel, IdString net);
|
||||||
|
void unbindWire(WireId bel);
|
||||||
|
bool checkWireAvail(WireId bel) const;
|
||||||
|
const vector<WireId> &getWires() const;
|
||||||
|
|
||||||
|
PipId getPipByName(IdString name) const;
|
||||||
|
IdString getPipName(PipId pip) const;
|
||||||
|
void bindPip(PipId bel, IdString net);
|
||||||
|
void unbindPip(PipId bel);
|
||||||
|
bool checkPipAvail(PipId bel) const;
|
||||||
|
const vector<PipId> &getPips() const;
|
||||||
|
WireId getPipSrcWire(PipId pip) const;
|
||||||
|
WireId getPipDstWire(PipId pip) const;
|
||||||
|
DelayInfo getPipDelay(PipId pip) const;
|
||||||
|
const vector<PipId> &getPipsDownhill(WireId wire) const;
|
||||||
|
const vector<PipId> &getPipsUphill(WireId wire) const;
|
||||||
|
const vector<PipId> &getWireAliases(WireId wire) const;
|
||||||
|
|
||||||
|
void getBelPosition(BelId bel, float &x, float &y) const;
|
||||||
|
void getWirePosition(WireId wire, float &x, float &y) const;
|
||||||
|
void getPipPosition(PipId pip, float &x, float &y) const;
|
||||||
|
vector<GraphicElement> getBelGraphics(BelId bel) const;
|
||||||
|
vector<GraphicElement> getWireGraphics(WireId wire) const;
|
||||||
|
vector<GraphicElement> getPipGraphics(PipId pip) const;
|
||||||
|
vector<GraphicElement> getFrameGraphics() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -25,9 +25,6 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
Design design(ChipArgs{});
|
Design design(ChipArgs{});
|
||||||
|
|
||||||
for (auto bel : design.chip.getBels())
|
|
||||||
printf("%s\n", design.chip.getBelName(bel).c_str());
|
|
||||||
|
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
MainWindow w;
|
MainWindow w;
|
||||||
w.show();
|
w.show();
|
||||||
|
@ -24,5 +24,4 @@
|
|||||||
|
|
||||||
void arch_wrap_python() {
|
void arch_wrap_python() {
|
||||||
class_<ChipArgs>("ChipArgs");
|
class_<ChipArgs>("ChipArgs");
|
||||||
WRAP_RANGE(Wire);
|
|
||||||
}
|
}
|
||||||
|
196
ice40/chip.cc
196
ice40/chip.cc
@ -278,10 +278,16 @@ PortPin PortPinFromId(IdString id)
|
|||||||
Chip::Chip(ChipArgs args)
|
Chip::Chip(ChipArgs args)
|
||||||
{
|
{
|
||||||
if (args.type == ChipArgs::LP384) {
|
if (args.type == ChipArgs::LP384) {
|
||||||
num_bels = 0;
|
chip_info = chip_info_384;
|
||||||
bel_data = nullptr;
|
return;
|
||||||
num_wires = num_wires_384;
|
} else if (args.type == ChipArgs::LP1K || args.type == ChipArgs::HX1K) {
|
||||||
wire_data = wire_data_384;
|
chip_info = chip_info_1k;
|
||||||
|
return;
|
||||||
|
} else if (args.type == ChipArgs::UP5K) {
|
||||||
|
chip_info = chip_info_5k;
|
||||||
|
return;
|
||||||
|
} else if (args.type == ChipArgs::LP8K || args.type == ChipArgs::HX8K) {
|
||||||
|
chip_info = chip_info_8k;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Unsupported chip type\n");
|
fprintf(stderr, "Unsupported chip type\n");
|
||||||
@ -291,13 +297,15 @@ Chip::Chip(ChipArgs args)
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
BelId Chip::getBelByName(IdString name) const
|
BelId Chip::getBelByName(IdString name) const
|
||||||
{
|
{
|
||||||
BelId ret;
|
BelId ret;
|
||||||
|
|
||||||
if (bel_by_name.empty()) {
|
if (bel_by_name.empty()) {
|
||||||
for (int i = 0; i < num_bels; i++)
|
for (int i = 0; i < chip_info.num_bels; i++)
|
||||||
bel_by_name[bel_data[i].name] = i;
|
bel_by_name[chip_info.bel_data[i].name] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it = bel_by_name.find(name);
|
auto it = bel_by_name.find(name);
|
||||||
@ -307,24 +315,168 @@ BelId Chip::getBelByName(IdString name) const
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
WireId Chip::getWireByName(IdString name) const
|
|
||||||
{
|
|
||||||
WireId ret;
|
|
||||||
|
|
||||||
if (wire_by_name.empty()) {
|
|
||||||
for (int i = 0; i < num_wires; i++)
|
|
||||||
wire_by_name[wire_data[i].name] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto it = wire_by_name.find(name);
|
|
||||||
if (it != wire_by_name.end())
|
|
||||||
ret.index = it->second;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
WireId Chip::getWireBelPin(BelId bel, PortPin pin) const
|
WireId Chip::getWireBelPin(BelId bel, PortPin pin) const
|
||||||
{
|
{
|
||||||
// FIXME
|
// FIXME
|
||||||
return WireId();
|
return WireId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
WireId Chip::getWireByName(IdString name) const
|
||||||
|
{
|
||||||
|
WireId ret;
|
||||||
|
|
||||||
|
if (wire_by_name.empty()) {
|
||||||
|
for (int i = 0; i < chip_info.num_wires; i++)
|
||||||
|
wire_by_name[chip_info.wire_data[i].name] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = wire_by_name.find(name);
|
||||||
|
if (it != wire_by_name.end())
|
||||||
|
ret.index = it->second;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
PipId Chip::getPipByName(IdString name) const
|
||||||
|
{
|
||||||
|
PipId ret;
|
||||||
|
|
||||||
|
if (pip_by_name.empty()) {
|
||||||
|
for (int i = 0; i < chip_info.num_pips; i++) {
|
||||||
|
PipId pip;
|
||||||
|
pip.index = i;
|
||||||
|
pip_by_name[getPipName(pip)] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = pip_by_name.find(name);
|
||||||
|
if (it != pip_by_name.end())
|
||||||
|
ret.index = it->second;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void Chip::getBelPosition(BelId bel, float &x, float &y) const
|
||||||
|
{
|
||||||
|
assert(!bel.nil());
|
||||||
|
x = chip_info.bel_data[bel.index].x;
|
||||||
|
y = chip_info.bel_data[bel.index].y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Chip::getWirePosition(WireId wire, float &x, float &y) const
|
||||||
|
{
|
||||||
|
assert(!wire.nil());
|
||||||
|
x = chip_info.wire_data[wire.index].x;
|
||||||
|
y = chip_info.wire_data[wire.index].y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Chip::getPipPosition(PipId pip, float &x, float &y) const
|
||||||
|
{
|
||||||
|
assert(!pip.nil());
|
||||||
|
x = chip_info.pip_data[pip.index].x;
|
||||||
|
y = chip_info.pip_data[pip.index].y;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<GraphicElement> Chip::getBelGraphics(BelId bel) const
|
||||||
|
{
|
||||||
|
vector<GraphicElement> ret;
|
||||||
|
|
||||||
|
auto bel_type = getBelType(bel);
|
||||||
|
|
||||||
|
if (bel_type == TYPE_ICESTORM_LC) {
|
||||||
|
GraphicElement el;
|
||||||
|
el.type = GraphicElement::G_BOX;
|
||||||
|
el.x1 = chip_info.bel_data[bel.index].x + 0.1;
|
||||||
|
el.x2 = chip_info.bel_data[bel.index].x + 0.9;
|
||||||
|
el.y1 = chip_info.bel_data[bel.index].y + 0.10 + (chip_info.bel_data[bel.index].z) * (0.8/8);
|
||||||
|
el.y2 = chip_info.bel_data[bel.index].y + 0.18 + (chip_info.bel_data[bel.index].z) * (0.8/8);
|
||||||
|
el.z = 0;
|
||||||
|
ret.push_back(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bel_type == TYPE_SB_IO) {
|
||||||
|
if (chip_info.bel_data[bel.index].x == 0 || chip_info.bel_data[bel.index].x == chip_info.width-1)
|
||||||
|
{
|
||||||
|
GraphicElement el;
|
||||||
|
el.type = GraphicElement::G_BOX;
|
||||||
|
el.x1 = chip_info.bel_data[bel.index].x + 0.1;
|
||||||
|
el.x2 = chip_info.bel_data[bel.index].x + 0.9;
|
||||||
|
if (chip_info.bel_data[bel.index].z == 0) {
|
||||||
|
el.y1 = chip_info.bel_data[bel.index].y + 0.10;
|
||||||
|
el.y2 = chip_info.bel_data[bel.index].y + 0.45;
|
||||||
|
} else {
|
||||||
|
el.y1 = chip_info.bel_data[bel.index].y + 0.55;
|
||||||
|
el.y2 = chip_info.bel_data[bel.index].y + 0.90;
|
||||||
|
}
|
||||||
|
el.z = 0;
|
||||||
|
ret.push_back(el);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GraphicElement el;
|
||||||
|
el.type = GraphicElement::G_BOX;
|
||||||
|
if (chip_info.bel_data[bel.index].z == 0) {
|
||||||
|
el.x1 = chip_info.bel_data[bel.index].x + 0.10;
|
||||||
|
el.x2 = chip_info.bel_data[bel.index].x + 0.45;
|
||||||
|
} else {
|
||||||
|
el.x1 = chip_info.bel_data[bel.index].x + 0.55;
|
||||||
|
el.x2 = chip_info.bel_data[bel.index].x + 0.90;
|
||||||
|
}
|
||||||
|
el.y1 = chip_info.bel_data[bel.index].y + 0.1;
|
||||||
|
el.y2 = chip_info.bel_data[bel.index].y + 0.9;
|
||||||
|
el.z = 0;
|
||||||
|
ret.push_back(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bel_type == TYPE_ICESTORM_RAM) {
|
||||||
|
GraphicElement el;
|
||||||
|
el.type = GraphicElement::G_BOX;
|
||||||
|
el.x1 = chip_info.bel_data[bel.index].x + 0.1;
|
||||||
|
el.x2 = chip_info.bel_data[bel.index].x + 0.9;
|
||||||
|
el.y1 = chip_info.bel_data[bel.index].y + 0.1;
|
||||||
|
el.y2 = chip_info.bel_data[bel.index].y + 1.9;
|
||||||
|
el.z = 0;
|
||||||
|
ret.push_back(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<GraphicElement> Chip::getWireGraphics(WireId wire) const
|
||||||
|
{
|
||||||
|
vector<GraphicElement> ret;
|
||||||
|
// FIXME
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<GraphicElement> Chip::getPipGraphics(PipId pip) const
|
||||||
|
{
|
||||||
|
vector<GraphicElement> ret;
|
||||||
|
// FIXME
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<GraphicElement> Chip::getFrameGraphics() const
|
||||||
|
{
|
||||||
|
vector<GraphicElement> ret;
|
||||||
|
|
||||||
|
for (int x = 0; x <= chip_info.width; x++)
|
||||||
|
for (int y = 0; y <= chip_info.height; y++)
|
||||||
|
{
|
||||||
|
GraphicElement el;
|
||||||
|
el.type = GraphicElement::G_LINE;
|
||||||
|
el.x1 = x - 0.05, el.x2 = x + 0.05, el.y1 = y, el.y2 = y, el.z = 0;
|
||||||
|
ret.push_back(el);
|
||||||
|
el.x1 = x, el.x2 = x, el.y1 = y - 0.05, el.y2 = y + 0.05, el.z = 0;
|
||||||
|
ret.push_back(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
420
ice40/chip.h
420
ice40/chip.h
@ -164,12 +164,7 @@ struct BelInfoPOD
|
|||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
BelType type;
|
BelType type;
|
||||||
};
|
int8_t x, y, z;
|
||||||
|
|
||||||
struct WireDelayPOD
|
|
||||||
{
|
|
||||||
int32_t wire_index;
|
|
||||||
float delay;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BelPortPOD
|
struct BelPortPOD
|
||||||
@ -178,36 +173,39 @@ struct BelPortPOD
|
|||||||
PortPin port;
|
PortPin port;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PipInfoPOD
|
||||||
|
{
|
||||||
|
int32_t src, dst;
|
||||||
|
float delay;
|
||||||
|
int8_t x, y;
|
||||||
|
};
|
||||||
|
|
||||||
struct WireInfoPOD
|
struct WireInfoPOD
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
int num_uphill, num_downhill, num_bidir;
|
int num_uphill, num_downhill;
|
||||||
WireDelayPOD *wires_uphill, *wires_downhill, *wires_bidir;
|
int *pips_uphill, *pips_downhill;
|
||||||
|
|
||||||
int num_bels_downhill;
|
int num_bels_downhill;
|
||||||
BelPortPOD bel_uphill;
|
BelPortPOD bel_uphill;
|
||||||
BelPortPOD *bels_downhill;
|
BelPortPOD *bels_downhill;
|
||||||
|
|
||||||
|
float x, y;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int num_bels_384;
|
struct ChipInfoPOD
|
||||||
extern int num_bels_1k;
|
{
|
||||||
extern int num_bels_5k;
|
int width, height;
|
||||||
extern int num_bels_8k;
|
int num_bels, num_wires, num_pips;
|
||||||
|
BelInfoPOD *bel_data;
|
||||||
|
WireInfoPOD *wire_data;
|
||||||
|
PipInfoPOD *pip_data;
|
||||||
|
};
|
||||||
|
|
||||||
extern BelInfoPOD bel_data_384[];
|
extern ChipInfoPOD chip_info_384;
|
||||||
extern BelInfoPOD bel_data_1k[];
|
extern ChipInfoPOD chip_info_1k;
|
||||||
extern BelInfoPOD bel_data_5k[];
|
extern ChipInfoPOD chip_info_5k;
|
||||||
extern BelInfoPOD bel_data_8k[];
|
extern ChipInfoPOD chip_info_8k;
|
||||||
|
|
||||||
extern int num_wires_384;
|
|
||||||
extern int num_wires_1k;
|
|
||||||
extern int num_wires_5k;
|
|
||||||
extern int num_wires_8k;
|
|
||||||
|
|
||||||
extern WireInfoPOD wire_data_384[];
|
|
||||||
extern WireInfoPOD wire_data_1k[];
|
|
||||||
extern WireInfoPOD wire_data_5k[];
|
|
||||||
extern WireInfoPOD wire_data_8k[];
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
@ -218,6 +216,9 @@ struct BelId
|
|||||||
bool nil() const {
|
bool nil() const {
|
||||||
return index < 0;
|
return index < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator==(const BelId &other) const { return index == other.index; }
|
||||||
|
bool operator!=(const BelId &other) const { return index != other.index; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WireId
|
struct WireId
|
||||||
@ -227,6 +228,27 @@ struct WireId
|
|||||||
bool nil() const {
|
bool nil() const {
|
||||||
return index < 0;
|
return index < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator==(const WireId &other) const { return index == other.index; }
|
||||||
|
bool operator!=(const WireId &other) const { return index != other.index; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PipId
|
||||||
|
{
|
||||||
|
int32_t index = -1;
|
||||||
|
|
||||||
|
bool nil() const {
|
||||||
|
return index < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const PipId &other) const { return index == other.index; }
|
||||||
|
bool operator!=(const PipId &other) const { return index != other.index; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BelPin
|
||||||
|
{
|
||||||
|
BelId bel;
|
||||||
|
PortPin pin;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
@ -246,6 +268,14 @@ namespace std
|
|||||||
return wire.index;
|
return wire.index;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<> struct hash<PipId>
|
||||||
|
{
|
||||||
|
std::size_t operator()(const PipId &wire) const noexcept
|
||||||
|
{
|
||||||
|
return wire.index;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
@ -273,65 +303,6 @@ struct BelRange
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
struct AllWireIterator
|
|
||||||
{
|
|
||||||
int cursor;
|
|
||||||
|
|
||||||
void operator++() { cursor++; }
|
|
||||||
bool operator!=(const AllWireIterator &other) const { return cursor != other.cursor; }
|
|
||||||
|
|
||||||
WireId operator*() const {
|
|
||||||
WireId ret;
|
|
||||||
ret.index = cursor;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AllWireRange
|
|
||||||
{
|
|
||||||
AllWireIterator b, e;
|
|
||||||
AllWireIterator begin() const { return b; }
|
|
||||||
AllWireIterator end() const { return e; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
|
||||||
|
|
||||||
struct WireDelay
|
|
||||||
{
|
|
||||||
WireId wire;
|
|
||||||
DelayInfo delay;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct WireDelayIterator
|
|
||||||
{
|
|
||||||
WireDelayPOD *ptr = nullptr;
|
|
||||||
|
|
||||||
void operator++() { ptr++; }
|
|
||||||
bool operator!=(const WireDelayIterator &other) const { return ptr != other.ptr; }
|
|
||||||
|
|
||||||
WireDelay operator*() const {
|
|
||||||
WireDelay ret;
|
|
||||||
ret.wire.index = ptr->wire_index;
|
|
||||||
ret.delay.delay = ptr->delay;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct WireDelayRange
|
|
||||||
{
|
|
||||||
WireDelayIterator b, e;
|
|
||||||
WireDelayIterator begin() const { return b; }
|
|
||||||
WireDelayIterator end() const { return e; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
|
||||||
|
|
||||||
struct BelPin
|
|
||||||
{
|
|
||||||
BelId bel;
|
|
||||||
PortPin pin;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BelPinIterator
|
struct BelPinIterator
|
||||||
{
|
{
|
||||||
BelPortPOD *ptr = nullptr;
|
BelPortPOD *ptr = nullptr;
|
||||||
@ -356,6 +327,75 @@ struct BelPinRange
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct WireIterator
|
||||||
|
{
|
||||||
|
int cursor = -1;
|
||||||
|
|
||||||
|
void operator++() { cursor++; }
|
||||||
|
bool operator!=(const WireIterator &other) const { return cursor != other.cursor; }
|
||||||
|
|
||||||
|
WireId operator*() const {
|
||||||
|
WireId ret;
|
||||||
|
ret.index = cursor;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WireRange
|
||||||
|
{
|
||||||
|
WireIterator b, e;
|
||||||
|
WireIterator begin() const { return b; }
|
||||||
|
WireIterator end() const { return e; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct AllPipIterator
|
||||||
|
{
|
||||||
|
int cursor = -1;
|
||||||
|
|
||||||
|
void operator++() { cursor++; }
|
||||||
|
bool operator!=(const AllPipIterator &other) const { return cursor != other.cursor; }
|
||||||
|
|
||||||
|
PipId operator*() const {
|
||||||
|
PipId ret;
|
||||||
|
ret.index = cursor;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AllPipRange
|
||||||
|
{
|
||||||
|
AllPipIterator b, e;
|
||||||
|
AllPipIterator begin() const { return b; }
|
||||||
|
AllPipIterator end() const { return e; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct PipIterator
|
||||||
|
{
|
||||||
|
int *cursor = nullptr;
|
||||||
|
|
||||||
|
void operator++() { cursor++; }
|
||||||
|
bool operator!=(const PipIterator &other) const { return cursor != other.cursor; }
|
||||||
|
|
||||||
|
PipId operator*() const {
|
||||||
|
PipId ret;
|
||||||
|
ret.index = *cursor;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PipRange
|
||||||
|
{
|
||||||
|
PipIterator b, e;
|
||||||
|
PipIterator begin() const { return b; }
|
||||||
|
PipIterator end() const { return e; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
struct ChipArgs
|
struct ChipArgs
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
@ -371,36 +411,41 @@ struct ChipArgs
|
|||||||
|
|
||||||
struct Chip
|
struct Chip
|
||||||
{
|
{
|
||||||
int num_bels, num_wires;
|
ChipInfoPOD chip_info;
|
||||||
BelInfoPOD *bel_data;
|
|
||||||
WireInfoPOD *wire_data;
|
|
||||||
|
|
||||||
mutable dict<IdString, int> wire_by_name;
|
|
||||||
mutable dict<IdString, int> bel_by_name;
|
mutable dict<IdString, int> bel_by_name;
|
||||||
|
mutable dict<IdString, int> wire_by_name;
|
||||||
|
mutable dict<IdString, int> pip_by_name;
|
||||||
|
|
||||||
Chip(ChipArgs args);
|
Chip(ChipArgs args);
|
||||||
|
|
||||||
void setBelActive(BelId, bool) { }
|
// -------------------------------------------------
|
||||||
bool getBelActive(BelId) { return true; }
|
|
||||||
|
|
||||||
BelId getBelByName(IdString name) const;
|
BelId getBelByName(IdString name) const;
|
||||||
WireId getWireByName(IdString name) const;
|
|
||||||
|
|
||||||
IdString getBelName(BelId bel) const
|
IdString getBelName(BelId bel) const
|
||||||
{
|
{
|
||||||
return bel_data[bel.index].name;
|
assert(!bel.nil());
|
||||||
|
return chip_info.bel_data[bel.index].name;
|
||||||
}
|
}
|
||||||
|
|
||||||
IdString getWireName(WireId wire) const
|
void bindBel(BelId bel, IdString cell)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void unbindBel(BelId bel)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkBelAvail(BelId bel) const
|
||||||
{
|
{
|
||||||
return wire_data[wire.index].name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BelRange getBels() const
|
BelRange getBels() const
|
||||||
{
|
{
|
||||||
BelRange range;
|
BelRange range;
|
||||||
range.b.cursor = 0;
|
range.b.cursor = 0;
|
||||||
range.e.cursor = num_bels;
|
range.e.cursor = chip_info.num_bels;
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,52 +465,8 @@ struct Chip
|
|||||||
|
|
||||||
BelType getBelType(BelId bel) const
|
BelType getBelType(BelId bel) const
|
||||||
{
|
{
|
||||||
return bel_data[bel.index].type;
|
assert(!bel.nil());
|
||||||
}
|
return chip_info.bel_data[bel.index].type;
|
||||||
|
|
||||||
// FIXME: void getBelPosition(BelId bel, float &x, float &y) const;
|
|
||||||
// FIXME: void getWirePosition(WireId wire, float &x, float &y) const;
|
|
||||||
// FIXME: vector<GraphicElement> getBelGraphics(BelId bel) const;
|
|
||||||
// FIXME: vector<GraphicElement> getWireGraphics(WireId wire) const;
|
|
||||||
// FIXME: vector<GraphicElement> getPipGraphics(WireId src, WireId dst) const;
|
|
||||||
// FIXME: vector<GraphicElement> getFrameGraphics() const;
|
|
||||||
|
|
||||||
AllWireRange getWires() const
|
|
||||||
{
|
|
||||||
AllWireRange range;
|
|
||||||
range.b.cursor = 0;
|
|
||||||
range.e.cursor = num_wires;
|
|
||||||
return range;
|
|
||||||
}
|
|
||||||
|
|
||||||
WireDelayRange getWiresUphill(WireId wire) const
|
|
||||||
{
|
|
||||||
WireDelayRange range;
|
|
||||||
range.b.ptr = wire_data[wire.index].wires_uphill;
|
|
||||||
range.e.ptr = wire_data[wire.index].wires_uphill + wire_data[wire.index].num_uphill;
|
|
||||||
return range;
|
|
||||||
}
|
|
||||||
|
|
||||||
WireDelayRange getWiresDownhill(WireId wire) const
|
|
||||||
{
|
|
||||||
WireDelayRange range;
|
|
||||||
range.b.ptr = wire_data[wire.index].wires_downhill;
|
|
||||||
range.e.ptr = wire_data[wire.index].wires_downhill + wire_data[wire.index].num_downhill;
|
|
||||||
return range;
|
|
||||||
}
|
|
||||||
|
|
||||||
WireDelayRange getWiresBidir(WireId wire) const
|
|
||||||
{
|
|
||||||
WireDelayRange range;
|
|
||||||
range.b.ptr = wire_data[wire.index].wires_bidir;
|
|
||||||
range.e.ptr = wire_data[wire.index].wires_bidir + wire_data[wire.index].num_bidir;
|
|
||||||
return range;
|
|
||||||
}
|
|
||||||
|
|
||||||
WireDelayRange getWireAliases(WireId wire) const
|
|
||||||
{
|
|
||||||
WireDelayRange range;
|
|
||||||
return range;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WireId getWireBelPin(BelId bel, PortPin pin) const;
|
WireId getWireBelPin(BelId bel, PortPin pin) const;
|
||||||
@ -473,10 +474,11 @@ struct Chip
|
|||||||
BelPin getBelPinUphill(WireId wire) const
|
BelPin getBelPinUphill(WireId wire) const
|
||||||
{
|
{
|
||||||
BelPin ret;
|
BelPin ret;
|
||||||
|
assert(!wire.nil());
|
||||||
|
|
||||||
if (wire_data[wire.index].bel_uphill.bel_index >= 0) {
|
if (chip_info.wire_data[wire.index].bel_uphill.bel_index >= 0) {
|
||||||
ret.bel.index = wire_data[wire.index].bel_uphill.bel_index;
|
ret.bel.index = chip_info.wire_data[wire.index].bel_uphill.bel_index;
|
||||||
ret.pin = wire_data[wire.index].bel_uphill.port;
|
ret.pin = chip_info.wire_data[wire.index].bel_uphill.port;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -485,10 +487,134 @@ struct Chip
|
|||||||
BelPinRange getBelPinsDownhill(WireId wire) const
|
BelPinRange getBelPinsDownhill(WireId wire) const
|
||||||
{
|
{
|
||||||
BelPinRange range;
|
BelPinRange range;
|
||||||
range.b.ptr = wire_data[wire.index].bels_downhill;
|
assert(!wire.nil());
|
||||||
range.e.ptr = wire_data[wire.index].bels_downhill + wire_data[wire.index].num_bels_downhill;
|
range.b.ptr = chip_info.wire_data[wire.index].bels_downhill;
|
||||||
|
range.e.ptr = range.b.ptr + chip_info.wire_data[wire.index].num_bels_downhill;
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
|
||||||
|
WireId getWireByName(IdString name) const;
|
||||||
|
|
||||||
|
IdString getWireName(WireId wire) const
|
||||||
|
{
|
||||||
|
assert(!wire.nil());
|
||||||
|
return chip_info.wire_data[wire.index].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bindWire(WireId bel, IdString net)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void unbindWire(WireId bel)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkWireAvail(WireId bel) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
WireRange getWires() const
|
||||||
|
{
|
||||||
|
WireRange range;
|
||||||
|
range.b.cursor = 0;
|
||||||
|
range.e.cursor = chip_info.num_wires;
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
|
||||||
|
PipId getPipByName(IdString name) const;
|
||||||
|
|
||||||
|
IdString getPipName(PipId pip) const
|
||||||
|
{
|
||||||
|
assert(!pip.nil());
|
||||||
|
std::string src_name = chip_info.wire_data[chip_info.pip_data[pip.index].src].name;
|
||||||
|
std::string dst_name = chip_info.wire_data[chip_info.pip_data[pip.index].dst].name;
|
||||||
|
return src_name + "->" + dst_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bindPip(PipId bel, IdString net)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void unbindPip(PipId bel)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkPipAvail(PipId bel) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AllPipRange getPips() const
|
||||||
|
{
|
||||||
|
AllPipRange range;
|
||||||
|
range.b.cursor = 0;
|
||||||
|
range.e.cursor = chip_info.num_pips;
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
WireId getPipSrcWire(PipId pip) const
|
||||||
|
{
|
||||||
|
WireId wire;
|
||||||
|
assert(!pip.nil());
|
||||||
|
wire.index = chip_info.pip_data[pip.index].src;
|
||||||
|
return wire;
|
||||||
|
}
|
||||||
|
|
||||||
|
WireId getPipDstWire(PipId pip) const
|
||||||
|
{
|
||||||
|
WireId wire;
|
||||||
|
assert(!pip.nil());
|
||||||
|
wire.index = chip_info.pip_data[pip.index].dst;
|
||||||
|
return wire;
|
||||||
|
}
|
||||||
|
|
||||||
|
DelayInfo getPipDelay(PipId pip) const
|
||||||
|
{
|
||||||
|
DelayInfo delay;
|
||||||
|
assert(!pip.nil());
|
||||||
|
delay.delay = chip_info.pip_data[pip.index].delay;
|
||||||
|
return delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
PipRange getPipsDownhill(WireId wire) const
|
||||||
|
{
|
||||||
|
PipRange range;
|
||||||
|
assert(!wire.nil());
|
||||||
|
range.b.cursor = chip_info.wire_data[wire.index].pips_downhill;
|
||||||
|
range.e.cursor = range.b.cursor + chip_info.wire_data[wire.index].num_downhill;
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
PipRange getPipsUphill(WireId wire) const
|
||||||
|
{
|
||||||
|
PipRange range;
|
||||||
|
assert(!wire.nil());
|
||||||
|
range.b.cursor = chip_info.wire_data[wire.index].pips_uphill;
|
||||||
|
range.e.cursor = range.b.cursor + chip_info.wire_data[wire.index].num_uphill;
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
PipRange getWireAliases(WireId wire) const
|
||||||
|
{
|
||||||
|
PipRange range;
|
||||||
|
assert(!wire.nil());
|
||||||
|
range.b.cursor = nullptr;
|
||||||
|
range.e.cursor = nullptr;
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
|
||||||
|
void getBelPosition(BelId bel, float &x, float &y) const;
|
||||||
|
void getWirePosition(WireId wire, float &x, float &y) const;
|
||||||
|
void getPipPosition(PipId pip, float &x, float &y) const;
|
||||||
|
vector<GraphicElement> getBelGraphics(BelId bel) const;
|
||||||
|
vector<GraphicElement> getWireGraphics(WireId wire) const;
|
||||||
|
vector<GraphicElement> getPipGraphics(PipId pip) const;
|
||||||
|
vector<GraphicElement> getFrameGraphics() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
122
ice40/chipdb.py
122
ice40/chipdb.py
@ -11,16 +11,18 @@ tiles = dict()
|
|||||||
|
|
||||||
wire_uphill = dict()
|
wire_uphill = dict()
|
||||||
wire_downhill = dict()
|
wire_downhill = dict()
|
||||||
wire_bidir = dict()
|
pip_xy = dict()
|
||||||
|
|
||||||
bel_name = list()
|
bel_name = list()
|
||||||
bel_type = list()
|
bel_type = list()
|
||||||
|
bel_pos = list()
|
||||||
|
|
||||||
wire_uphill_belport = dict()
|
wire_uphill_belport = dict()
|
||||||
wire_downhill_belports = dict()
|
wire_downhill_belports = dict()
|
||||||
|
|
||||||
wire_names = dict()
|
wire_names = dict()
|
||||||
wire_names_r = dict()
|
wire_names_r = dict()
|
||||||
|
wire_xy = dict()
|
||||||
|
|
||||||
def cmp_wire_names(newname, oldname):
|
def cmp_wire_names(newname, oldname):
|
||||||
return newname < oldname
|
return newname < oldname
|
||||||
@ -46,11 +48,11 @@ with open(sys.argv[1], "r") as f:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if line[0] == ".buffer":
|
if line[0] == ".buffer":
|
||||||
mode = ("buffer", int(line[3]))
|
mode = ("buffer", int(line[3]), int(line[1]), int(line[2]))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if line[0] == ".routing":
|
if line[0] == ".routing":
|
||||||
mode = ("routing", int(line[3]))
|
mode = ("routing", int(line[3]), int(line[1]), int(line[2]))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if line[0] == ".io_tile":
|
if line[0] == ".io_tile":
|
||||||
@ -82,6 +84,9 @@ with open(sys.argv[1], "r") as f:
|
|||||||
wire_names[wname] = mode[1]
|
wire_names[wname] = mode[1]
|
||||||
if (mode[1] not in wire_names_r) or cmp_wire_names(wname, wire_names_r[mode[1]]):
|
if (mode[1] not in wire_names_r) or cmp_wire_names(wname, wire_names_r[mode[1]]):
|
||||||
wire_names_r[mode[1]] = wname
|
wire_names_r[mode[1]] = wname
|
||||||
|
if mode[1] not in wire_xy:
|
||||||
|
wire_xy[mode[1]] = list()
|
||||||
|
wire_xy[mode[1]].append((int(line[0]), int(line[1])))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if mode[0] == "buffer":
|
if mode[0] == "buffer":
|
||||||
@ -93,17 +98,28 @@ with open(sys.argv[1], "r") as f:
|
|||||||
wire_uphill[wire_b] = set()
|
wire_uphill[wire_b] = set()
|
||||||
wire_downhill[wire_a].add(wire_b)
|
wire_downhill[wire_a].add(wire_b)
|
||||||
wire_uphill[wire_b].add(wire_a)
|
wire_uphill[wire_b].add(wire_a)
|
||||||
|
pip_xy[(wire_a, wire_b)] = (mode[2], mode[3])
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if mode[0] == "routing":
|
if mode[0] == "routing":
|
||||||
wire_a = int(line[1])
|
wire_a = int(line[1])
|
||||||
wire_b = mode[1]
|
wire_b = mode[1]
|
||||||
if wire_a not in wire_bidir:
|
|
||||||
wire_bidir[wire_a] = set()
|
if wire_a not in wire_downhill:
|
||||||
if wire_b not in wire_bidir:
|
wire_downhill[wire_a] = set()
|
||||||
wire_bidir[wire_b] = set()
|
if wire_b not in wire_uphill:
|
||||||
wire_bidir[wire_a].add(wire_b)
|
wire_uphill[wire_b] = set()
|
||||||
wire_bidir[wire_b].add(wire_b)
|
wire_downhill[wire_a].add(wire_b)
|
||||||
|
wire_uphill[wire_b].add(wire_a)
|
||||||
|
pip_xy[(wire_a, wire_b)] = (mode[2], mode[3])
|
||||||
|
|
||||||
|
if wire_b not in wire_downhill:
|
||||||
|
wire_downhill[wire_b] = set()
|
||||||
|
if wire_a not in wire_uphill:
|
||||||
|
wire_uphill[wire_a] = set()
|
||||||
|
wire_downhill[wire_b].add(wire_a)
|
||||||
|
wire_uphill[wire_a].add(wire_b)
|
||||||
|
pip_xy[(wire_b, wire_a)] = (mode[2], mode[3])
|
||||||
continue
|
continue
|
||||||
|
|
||||||
def add_bel_input(bel, wire, port):
|
def add_bel_input(bel, wire, port):
|
||||||
@ -119,6 +135,7 @@ def add_bel_lc(x, y, z):
|
|||||||
bel = len(bel_name)
|
bel = len(bel_name)
|
||||||
bel_name.append("%d_%d_lc%d" % (x, y, z))
|
bel_name.append("%d_%d_lc%d" % (x, y, z))
|
||||||
bel_type.append("ICESTORM_LC")
|
bel_type.append("ICESTORM_LC")
|
||||||
|
bel_pos.append((x, y, z))
|
||||||
|
|
||||||
wire_cen = wire_names[(x, y, "lutff_global/cen")]
|
wire_cen = wire_names[(x, y, "lutff_global/cen")]
|
||||||
wire_clk = wire_names[(x, y, "lutff_global/clk")]
|
wire_clk = wire_names[(x, y, "lutff_global/clk")]
|
||||||
@ -157,6 +174,7 @@ def add_bel_io(x, y, z):
|
|||||||
bel = len(bel_name)
|
bel = len(bel_name)
|
||||||
bel_name.append("%d_%d_lc%d" % (x, y, z))
|
bel_name.append("%d_%d_lc%d" % (x, y, z))
|
||||||
bel_type.append("SB_IO")
|
bel_type.append("SB_IO")
|
||||||
|
bel_pos.append((x, y, z))
|
||||||
|
|
||||||
wire_cen = wire_names[(x, y, "io_global/cen")]
|
wire_cen = wire_names[(x, y, "io_global/cen")]
|
||||||
wire_iclk = wire_names[(x, y, "io_global/inclk")]
|
wire_iclk = wire_names[(x, y, "io_global/inclk")]
|
||||||
@ -185,6 +203,7 @@ def add_bel_ram(x, y):
|
|||||||
bel = len(bel_name)
|
bel = len(bel_name)
|
||||||
bel_name.append("%d_%d_ram" % (x, y))
|
bel_name.append("%d_%d_ram" % (x, y))
|
||||||
bel_type.append("ICESTORM_RAM")
|
bel_type.append("ICESTORM_RAM")
|
||||||
|
bel_pos.append((x, y, 0))
|
||||||
|
|
||||||
if (x, y, "ram/WE") in wire_names:
|
if (x, y, "ram/WE") in wire_names:
|
||||||
# iCE40 1K-style memories
|
# iCE40 1K-style memories
|
||||||
@ -222,63 +241,86 @@ for tile_xy, tile_type in sorted(tiles.items()):
|
|||||||
|
|
||||||
print('#include "chip.h"')
|
print('#include "chip.h"')
|
||||||
|
|
||||||
print("int num_bels_%s = %d;" % (dev_name, num_wires))
|
print("BelInfoPOD bel_data_%s[%d] = {" % (dev_name, len(bel_name)))
|
||||||
print("BelInfoPOD bel_data_%s[%d] = {" % (dev_name, num_wires))
|
|
||||||
for bel in range(len(bel_name)):
|
for bel in range(len(bel_name)):
|
||||||
print(" {\"%s\", TYPE_%s}%s" % (bel_name[bel], bel_type[bel], "," if bel+1 < len(bel_name) else ""))
|
print(" {\"%s\", TYPE_%s, %d, %d, %d}%s" % (bel_name[bel], bel_type[bel],
|
||||||
|
bel_pos[bel][0], bel_pos[bel][1], bel_pos[bel][2],
|
||||||
|
"," if bel+1 < len(bel_name) else ""))
|
||||||
print("};")
|
print("};")
|
||||||
|
|
||||||
wireinfo = list()
|
wireinfo = list()
|
||||||
|
pipinfo = list()
|
||||||
|
pipcache = dict()
|
||||||
|
|
||||||
for wire in range(num_wires):
|
for wire in range(num_wires):
|
||||||
num_uphill = 0
|
|
||||||
num_downhill = 0
|
|
||||||
num_bidir = 0
|
|
||||||
num_bels_downhill = 0
|
|
||||||
|
|
||||||
if wire in wire_uphill:
|
if wire in wire_uphill:
|
||||||
num_uphill = len(wire_uphill[wire])
|
pips = list()
|
||||||
print("static WireDelayPOD wire%d_uphill[] = {" % wire)
|
for src in wire_uphill[wire]:
|
||||||
print(",\n".join([" {%d, 1.0}" % other_wire for other_wire in wire_uphill[wire]]))
|
if (src, wire) not in pipcache:
|
||||||
print("};")
|
pipcache[(src, wire)] = len(pipinfo)
|
||||||
|
pipinfo.append(" {%d, %d, 1.0, %d, %d}" % (src, wire, pip_xy[(src, wire)][0], pip_xy[(src, wire)][1]))
|
||||||
|
pips.append("%d" % pipcache[(src, wire)])
|
||||||
|
num_uphill = len(pips)
|
||||||
|
list_uphill = "wire%d_uppips" % wire
|
||||||
|
print("static int wire%d_uppips[] = {%s};" % (wire, ", ".join(pips)))
|
||||||
|
else:
|
||||||
|
num_uphill = 0
|
||||||
|
list_uphill = "nullptr"
|
||||||
|
|
||||||
if wire in wire_downhill:
|
if wire in wire_downhill:
|
||||||
num_downhill = len(wire_downhill[wire])
|
pips = list()
|
||||||
print("static WireDelayPOD wire%d_downhill[] = {" % wire)
|
for dst in wire_downhill[wire]:
|
||||||
print(",\n".join([" {%d, 1.0}" % other_wire for other_wire in wire_downhill[wire]]))
|
if (wire, dst) not in pipcache:
|
||||||
print("};")
|
pipcache[(wire, dst)] = len(pipinfo)
|
||||||
|
pipinfo.append(" {%d, %d, 1.0, %d, %d}" % (wire, dst, pip_xy[(wire, dst)][0], pip_xy[(wire, dst)][1]))
|
||||||
if wire in wire_bidir:
|
pips.append("%d" % pipcache[(wire, dst)])
|
||||||
num_bidir = len(wire_bidir[wire])
|
num_downhill = len(pips)
|
||||||
print("static WireDelayPOD wire%d_bidir[] = {" % wire)
|
list_downhill = "wire%d_downpips" % wire
|
||||||
print(",\n".join([" {%d, 1.0}" % other_wire for other_wire in wire_bidir[wire]]))
|
print("static int wire%d_downpips[] = {%s};" % (wire, ", ".join(pips)))
|
||||||
print("};")
|
else:
|
||||||
|
num_downhill = 0
|
||||||
|
list_downhill = "nullptr"
|
||||||
|
|
||||||
if wire in wire_downhill_belports:
|
if wire in wire_downhill_belports:
|
||||||
num_bels_downhill = len(wire_downhill_belports[wire])
|
num_bels_downhill = len(wire_downhill_belports[wire])
|
||||||
print("static BelPortPOD wire%d_downbels[] = {" % wire)
|
print("static BelPortPOD wire%d_downbels[] = {" % wire)
|
||||||
print(",\n".join([" {%d, PIN_%s}" % it for it in wire_downhill_belports[wire]]))
|
print(",\n".join([" {%d, PIN_%s}" % it for it in wire_downhill_belports[wire]]))
|
||||||
print("};")
|
print("};")
|
||||||
|
else:
|
||||||
|
num_bels_downhill = 0
|
||||||
|
|
||||||
info = " {"
|
info = " {"
|
||||||
info += "\"%d_%d_%s\", " % wire_names_r[wire]
|
info += "\"%d_%d_%s\", " % wire_names_r[wire]
|
||||||
info += "%d, %d, %d, " % (num_uphill, num_downhill, num_bidir)
|
info += "%d, %d, %s, %s, %d, " % (num_uphill, num_downhill, list_uphill, list_downhill, num_bels_downhill)
|
||||||
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 += "%d, " % (num_bels_downhill)
|
|
||||||
|
|
||||||
if wire in wire_uphill_belport:
|
if wire in wire_uphill_belport:
|
||||||
info += "{%d, PIN_%s}, " % wire_uphill_belport[wire]
|
info += "{%d, PIN_%s}, " % wire_uphill_belport[wire]
|
||||||
else:
|
else:
|
||||||
info += "{-1, PIN_NIL}, "
|
info += "{-1, PIN_NIL}, "
|
||||||
|
|
||||||
info += ("wire%d_downbels" % wire) if num_bels_downhill > 0 else "nullptr"
|
info += ("wire%d_downbels, " % wire) if num_bels_downhill > 0 else "nullptr, "
|
||||||
info += "}"
|
|
||||||
|
avg_x, avg_y = 0, 0
|
||||||
|
if wire in wire_xy:
|
||||||
|
for x, y in wire_xy[wire]:
|
||||||
|
avg_x += x
|
||||||
|
avg_y += y
|
||||||
|
avg_x /= len(wire_xy[wire])
|
||||||
|
avg_y /= len(wire_xy[wire])
|
||||||
|
|
||||||
|
info += "%f, %f}" % (avg_x, avg_y)
|
||||||
|
|
||||||
wireinfo.append(info)
|
wireinfo.append(info)
|
||||||
|
|
||||||
print("int num_wires_%s = %d;" % (dev_name, num_wires))
|
print("static WireInfoPOD wire_data_%s[%d] = {" % (dev_name, num_wires))
|
||||||
print("WireInfoPOD wire_data_%s[%d] = {" % (dev_name, num_wires))
|
|
||||||
print(",\n".join(wireinfo))
|
print(",\n".join(wireinfo))
|
||||||
print("};")
|
print("};")
|
||||||
|
|
||||||
|
print("static PipInfoPOD pip_data_%s[%d] = {" % (dev_name, len(pipinfo)))
|
||||||
|
print(",\n".join(pipinfo))
|
||||||
|
print("};")
|
||||||
|
|
||||||
|
print("ChipInfoPOD chip_info_%s = {" % dev_name)
|
||||||
|
print(" %d, %d, %d, %d, %d," % (dev_width, dev_height, len(bel_name), num_wires, len(pipinfo)))
|
||||||
|
print(" bel_data_%s, wire_data_%s, pip_data_%s" % (dev_name, dev_name, dev_name))
|
||||||
|
print("};")
|
||||||
|
122
ice40/main.cc
122
ice40/main.cc
@ -24,6 +24,22 @@
|
|||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
#include "pybindings.h"
|
#include "pybindings.h"
|
||||||
|
|
||||||
|
void svg_dump_el(const GraphicElement &el)
|
||||||
|
{
|
||||||
|
float scale = 10.0, offset = 10.0;
|
||||||
|
std::string style = "stroke=\"black\" stroke-width=\"0.1\" fill=\"none\"";
|
||||||
|
|
||||||
|
if (el.type == GraphicElement::G_BOX) {
|
||||||
|
std::cout << "<rect x=\"" << (offset + scale*el.x1) << "\" y=\"" << (offset + scale*el.y1) <<
|
||||||
|
"\" height=\"" << (scale*(el.y2-el.y1)) << "\" width=\"" << (scale*(el.x2-el.x1)) << "\" " << style << "/>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (el.type == GraphicElement::G_LINE) {
|
||||||
|
std::cout << "<line x1=\"" << (offset + scale*el.x1) << "\" y1=\"" << (offset + scale*el.y1) <<
|
||||||
|
"\" x2=\"" << (offset + scale*el.x2) << "\" y2=\"" << (offset + scale*el.y2) << "\" " << style << "/>\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
@ -32,10 +48,17 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
po::options_description options("Allowed options");
|
po::options_description options("Allowed options");
|
||||||
options.add_options()("help,h","show help");
|
options.add_options()("help,h","show help");
|
||||||
options.add_options()("debug","just a check");
|
options.add_options()("test","just a check");
|
||||||
options.add_options()("gui","start gui");
|
options.add_options()("gui","start gui");
|
||||||
|
options.add_options()("svg","dump SVG file");
|
||||||
options.add_options()("file", po::value<std::string>(), "python file to execute");
|
options.add_options()("file", po::value<std::string>(), "python file to execute");
|
||||||
options.add_options()("version,v","show version");
|
options.add_options()("version,v","show version");
|
||||||
|
options.add_options()("lp384","set device type to iCE40LP384");
|
||||||
|
options.add_options()("lp1k","set device type to iCE40LP1K");
|
||||||
|
options.add_options()("lp8k","set device type to iCE40LP8K");
|
||||||
|
options.add_options()("hx1k","set device type to iCE40HX1K");
|
||||||
|
options.add_options()("hx8k","set device type to iCE40HX8K");
|
||||||
|
options.add_options()("up5k","set device type to iCE40UP5K");
|
||||||
|
|
||||||
po::positional_options_description pos;
|
po::positional_options_description pos;
|
||||||
pos.add("file", -1);
|
pos.add("file", -1);
|
||||||
@ -71,6 +94,29 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ChipArgs chipArgs;
|
||||||
|
chipArgs.type = ChipArgs::HX1K;
|
||||||
|
|
||||||
|
if (vm.count("lp384"))
|
||||||
|
chipArgs.type = ChipArgs::LP384;
|
||||||
|
|
||||||
|
if (vm.count("lp1k"))
|
||||||
|
chipArgs.type = ChipArgs::LP1K;
|
||||||
|
|
||||||
|
if (vm.count("lp8k"))
|
||||||
|
chipArgs.type = ChipArgs::LP8K;
|
||||||
|
|
||||||
|
if (vm.count("hx1k"))
|
||||||
|
chipArgs.type = ChipArgs::HX1K;
|
||||||
|
|
||||||
|
if (vm.count("hx8k"))
|
||||||
|
chipArgs.type = ChipArgs::HX8K;
|
||||||
|
|
||||||
|
if (vm.count("up5k"))
|
||||||
|
chipArgs.type = ChipArgs::UP5K;
|
||||||
|
|
||||||
|
Design design(chipArgs);
|
||||||
|
|
||||||
if (vm.count("gui"))
|
if (vm.count("gui"))
|
||||||
{
|
{
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
@ -80,17 +126,79 @@ int main(int argc, char *argv[])
|
|||||||
return a.exec();
|
return a.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vm.count("debug"))
|
if (vm.count("test"))
|
||||||
{
|
{
|
||||||
ChipArgs chipArgs;
|
int bel_count = 0, wire_count = 0, pip_count = 0;
|
||||||
chipArgs.type = ChipArgs::LP384;
|
|
||||||
|
std::cout << "Checking bel names.\n";
|
||||||
|
for (auto bel : design.chip.getBels()) {
|
||||||
|
auto name = design.chip.getBelName(bel);
|
||||||
|
assert(bel == design.chip.getBelByName(name));
|
||||||
|
bel_count++;
|
||||||
|
}
|
||||||
|
std::cout << " checked " << bel_count << " bels.\n";
|
||||||
|
|
||||||
|
std::cout << "Checking wire names.\n";
|
||||||
|
for (auto wire : design.chip.getWires()) {
|
||||||
|
auto name = design.chip.getWireName(wire);
|
||||||
|
assert(wire == design.chip.getWireByName(name));
|
||||||
|
wire_count++;
|
||||||
|
}
|
||||||
|
std::cout << " checked " << wire_count << " wires.\n";
|
||||||
|
|
||||||
|
std::cout << "Checking pip names.\n";
|
||||||
|
for (auto pip : design.chip.getPips()) {
|
||||||
|
auto name = design.chip.getPipName(pip);
|
||||||
|
assert(pip == design.chip.getPipByName(name));
|
||||||
|
pip_count++;
|
||||||
|
}
|
||||||
|
std::cout << " checked " << pip_count << " pips.\n";
|
||||||
|
|
||||||
|
std::cout << "Checking uphill -> downhill consistency.\n";
|
||||||
|
for (auto dst : design.chip.getWires()) {
|
||||||
|
for (auto uphill_pip : design.chip.getPipsUphill(dst)) {
|
||||||
|
bool found_downhill = false;
|
||||||
|
for (auto downhill_pip : design.chip.getPipsDownhill(design.chip.getPipSrcWire(uphill_pip))) {
|
||||||
|
if (uphill_pip == downhill_pip) {
|
||||||
|
assert(!found_downhill);
|
||||||
|
found_downhill = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(found_downhill);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Checking downhill -> uphill consistency.\n";
|
||||||
|
for (auto dst : design.chip.getWires()) {
|
||||||
|
for (auto downhill_pip : design.chip.getPipsDownhill(dst)) {
|
||||||
|
bool found_uphill = false;
|
||||||
|
for (auto uphill_pip : design.chip.getPipsUphill(design.chip.getPipDstWire(downhill_pip))) {
|
||||||
|
if (uphill_pip == downhill_pip) {
|
||||||
|
assert(!found_uphill);
|
||||||
|
found_uphill = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(found_uphill);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Design design(chipArgs);
|
|
||||||
for (auto bel : design.chip.getBels())
|
|
||||||
printf("%s\n", design.chip.getBelName(bel).c_str());
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vm.count("svg"))
|
||||||
|
{
|
||||||
|
std::cout << "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n";
|
||||||
|
for (auto bel : design.chip.getBels()) {
|
||||||
|
std::cout << "<!-- " << design.chip.getBelName(bel) << " -->\n";
|
||||||
|
for (auto &el : design.chip.getBelGraphics(bel))
|
||||||
|
svg_dump_el(el);
|
||||||
|
}
|
||||||
|
std::cout << "<!-- Frame -->\n";
|
||||||
|
for (auto &el : design.chip.getFrameGraphics())
|
||||||
|
svg_dump_el(el);
|
||||||
|
std::cout << "</svg>\n";
|
||||||
|
}
|
||||||
|
|
||||||
if (vm.count("file"))
|
if (vm.count("file"))
|
||||||
{
|
{
|
||||||
std::string filename = vm["file"].as<std::string>();
|
std::string filename = vm["file"].as<std::string>();
|
||||||
|
@ -52,6 +52,9 @@ void arch_wrap_python() {
|
|||||||
.def("getBels", &Chip::getBels)
|
.def("getBels", &Chip::getBels)
|
||||||
.def("getWires", &Chip::getWires);
|
.def("getWires", &Chip::getWires);
|
||||||
|
|
||||||
WRAP_RANGE(AllWire);
|
WRAP_RANGE(Bel);
|
||||||
|
WRAP_RANGE(BelPin);
|
||||||
|
WRAP_RANGE(Wire);
|
||||||
|
WRAP_RANGE(AllPip);
|
||||||
|
WRAP_RANGE(Pip);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user