mirror of
https://github.com/YosysHQ/nextpnr.git
synced 2026-01-11 23:53:21 +00:00
himbaechel: Extend API to enable cell delay override (#1535)
This commit is contained in:
parent
322ad920b3
commit
82f8ff7cad
@ -454,14 +454,13 @@ TimingPortClass Arch::lookup_port_tmg_type(int type_idx, IdString port, PortType
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: adding uarch overrides for these?
|
bool Arch::get_cell_delay_default(const CellInfo *cell, IdString fromPort, IdString toPort, DelayQuad &delay) const
|
||||||
bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayQuad &delay) const
|
|
||||||
{
|
{
|
||||||
if (cell->timing_index == -1)
|
if (cell->timing_index == -1)
|
||||||
return false;
|
return false;
|
||||||
return lookup_cell_delay(cell->timing_index, fromPort, toPort, delay);
|
return lookup_cell_delay(cell->timing_index, fromPort, toPort, delay);
|
||||||
}
|
}
|
||||||
TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const
|
TimingPortClass Arch::get_port_timing_class_default(const CellInfo *cell, IdString port, int &clockInfoCount) const
|
||||||
{
|
{
|
||||||
if (cell->timing_index == -1)
|
if (cell->timing_index == -1)
|
||||||
return TMG_IGNORE;
|
return TMG_IGNORE;
|
||||||
@ -474,7 +473,7 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
|
|||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port, int index) const
|
TimingClockingInfo Arch::get_port_clocking_info_default(const CellInfo *cell, IdString port, int index) const
|
||||||
{
|
{
|
||||||
TimingClockingInfo result;
|
TimingClockingInfo result;
|
||||||
NPNR_ASSERT(cell->timing_index != -1);
|
NPNR_ASSERT(cell->timing_index != -1);
|
||||||
|
|||||||
@ -864,13 +864,25 @@ struct Arch : BaseArch<ArchRanges>
|
|||||||
// Attempt to look up port type based on timing database
|
// Attempt to look up port type based on timing database
|
||||||
TimingPortClass lookup_port_tmg_type(int type_idx, IdString port, PortType dir) const;
|
TimingPortClass lookup_port_tmg_type(int type_idx, IdString port, PortType dir) const;
|
||||||
|
|
||||||
|
bool get_cell_delay_default(const CellInfo *cell, IdString fromPort, IdString toPort, DelayQuad &delay) const;
|
||||||
|
TimingPortClass get_port_timing_class_default(const CellInfo *cell, IdString port, int &clockInfoCount) const;
|
||||||
|
TimingClockingInfo get_port_clocking_info_default(const CellInfo *cell, IdString port, int index) const;
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayQuad &delay) const override;
|
bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayQuad &delay) const override
|
||||||
|
{
|
||||||
|
return uarch->getCellDelay(cell, fromPort, toPort, delay);
|
||||||
|
};
|
||||||
// Get the port class, also setting clockInfoCount to the number of TimingClockingInfos associated with a port
|
// Get the port class, also setting clockInfoCount to the number of TimingClockingInfos associated with a port
|
||||||
TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const override;
|
TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const override
|
||||||
|
{
|
||||||
|
return uarch->getPortTimingClass(cell, port, clockInfoCount);
|
||||||
|
};
|
||||||
// Get the TimingClockingInfo of a port
|
// Get the TimingClockingInfo of a port
|
||||||
TimingClockingInfo getPortClockingInfo(const CellInfo *cell, IdString port, int index) const override;
|
TimingClockingInfo getPortClockingInfo(const CellInfo *cell, IdString port, int index) const override
|
||||||
|
{
|
||||||
|
return uarch->getPortClockingInfo(cell, port, index);
|
||||||
|
};
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
void init_tiles();
|
void init_tiles();
|
||||||
|
|||||||
@ -214,6 +214,8 @@ NPNR_PACKED_STRUCT(struct SpeedGradePOD {
|
|||||||
RelSlice<PipTimingPOD> pip_classes;
|
RelSlice<PipTimingPOD> pip_classes;
|
||||||
RelSlice<NodeTimingPOD> node_classes;
|
RelSlice<NodeTimingPOD> node_classes;
|
||||||
RelSlice<CellTimingPOD> cell_types;
|
RelSlice<CellTimingPOD> cell_types;
|
||||||
|
|
||||||
|
RelPtr<uint8_t> extra_data;
|
||||||
});
|
});
|
||||||
|
|
||||||
NPNR_PACKED_STRUCT(struct ConstIDDataPOD {
|
NPNR_PACKED_STRUCT(struct ConstIDDataPOD {
|
||||||
|
|||||||
@ -87,6 +87,21 @@ bool HimbaechelAPI::getClusterPlacement(ClusterId cluster, BelId root_bel,
|
|||||||
|
|
||||||
void HimbaechelAPI::expandBoundingBox(BoundingBox &bb) const { ctx->BaseArch::expandBoundingBox(bb); }
|
void HimbaechelAPI::expandBoundingBox(BoundingBox &bb) const { ctx->BaseArch::expandBoundingBox(bb); }
|
||||||
|
|
||||||
|
bool HimbaechelAPI::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayQuad &delay) const
|
||||||
|
{
|
||||||
|
return ctx->get_cell_delay_default(cell, fromPort, toPort, delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
TimingPortClass HimbaechelAPI::getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const
|
||||||
|
{
|
||||||
|
return ctx->get_port_timing_class_default(cell, port, clockInfoCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
TimingClockingInfo HimbaechelAPI::getPortClockingInfo(const CellInfo *cell, IdString port, int index) const
|
||||||
|
{
|
||||||
|
return ctx->get_port_clocking_info_default(cell, port, index);
|
||||||
|
}
|
||||||
|
|
||||||
HimbaechelArch *HimbaechelArch::list_head;
|
HimbaechelArch *HimbaechelArch::list_head;
|
||||||
HimbaechelArch::HimbaechelArch(const std::string &name) : name(name)
|
HimbaechelArch::HimbaechelArch(const std::string &name) : name(name)
|
||||||
{
|
{
|
||||||
@ -118,4 +133,5 @@ HimbaechelArch *HimbaechelArch::find_match(const std::string &device)
|
|||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
|||||||
@ -118,6 +118,11 @@ struct HimbaechelAPI
|
|||||||
|
|
||||||
virtual void drawGroup(std::vector<GraphicElement> &g, GroupId group, Loc loc) {};
|
virtual void drawGroup(std::vector<GraphicElement> &g, GroupId group, Loc loc) {};
|
||||||
|
|
||||||
|
// Cell delay
|
||||||
|
virtual bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayQuad &delay) const;
|
||||||
|
virtual TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const;
|
||||||
|
virtual TimingClockingInfo getPortClockingInfo(const CellInfo *cell, IdString port, int index) const;
|
||||||
|
|
||||||
// Routing methods
|
// Routing methods
|
||||||
virtual void expandBoundingBox(BoundingBox &bb) const;
|
virtual void expandBoundingBox(BoundingBox &bb) const;
|
||||||
// --- Flow hooks ---
|
// --- Flow hooks ---
|
||||||
|
|||||||
@ -665,6 +665,7 @@ class SpeedGrade(BBAStruct):
|
|||||||
pip_classes: list[Optional[PipTiming]] = field(default_factory=list)
|
pip_classes: list[Optional[PipTiming]] = field(default_factory=list)
|
||||||
node_classes: list[Optional[NodeTiming]] = field(default_factory=list)
|
node_classes: list[Optional[NodeTiming]] = field(default_factory=list)
|
||||||
cell_types: list[CellTiming] = field(default_factory=list) # sorted by (cell_type, variant) ID tuple
|
cell_types: list[CellTiming] = field(default_factory=list) # sorted by (cell_type, variant) ID tuple
|
||||||
|
extra_data: object = None
|
||||||
|
|
||||||
def finalise(self):
|
def finalise(self):
|
||||||
self.cell_types.sort(key=lambda ty: ty.type_variant)
|
self.cell_types.sort(key=lambda ty: ty.type_variant)
|
||||||
@ -683,11 +684,19 @@ class SpeedGrade(BBAStruct):
|
|||||||
bba.label(f"{context}_cell_types")
|
bba.label(f"{context}_cell_types")
|
||||||
for i, t in enumerate(self.cell_types):
|
for i, t in enumerate(self.cell_types):
|
||||||
t.serialise(f"{context}_cellty{i}", bba)
|
t.serialise(f"{context}_cellty{i}", bba)
|
||||||
|
if self.extra_data is not None:
|
||||||
|
self.extra_data.serialise_lists(f"{context}_extra_data", bba)
|
||||||
|
bba.label(f"{context}_extra_data")
|
||||||
|
self.extra_data.serialise(f"{context}_extra_data", bba)
|
||||||
def serialise(self, context: str, bba: BBAWriter):
|
def serialise(self, context: str, bba: BBAWriter):
|
||||||
bba.u32(self.name.index) # speed grade idstring
|
bba.u32(self.name.index) # speed grade idstring
|
||||||
bba.slice(f"{context}_pip_classes", len(self.pip_classes))
|
bba.slice(f"{context}_pip_classes", len(self.pip_classes))
|
||||||
bba.slice(f"{context}_node_classes", len(self.node_classes))
|
bba.slice(f"{context}_node_classes", len(self.node_classes))
|
||||||
bba.slice(f"{context}_cell_types", len(self.cell_types))
|
bba.slice(f"{context}_cell_types", len(self.cell_types))
|
||||||
|
if self.extra_data is not None:
|
||||||
|
bba.ref(f"{context}_extra_data")
|
||||||
|
else:
|
||||||
|
bba.u32(0)
|
||||||
|
|
||||||
class TimingPool(BBAStruct):
|
class TimingPool(BBAStruct):
|
||||||
def __init__(self, strs: StringPool):
|
def __init__(self, strs: StringPool):
|
||||||
@ -755,6 +764,9 @@ class TimingPool(BBAStruct):
|
|||||||
self.speed_grades[self.speed_grade_idx[speed_grade]].cell_types.append(cell)
|
self.speed_grades[self.speed_grade_idx[speed_grade]].cell_types.append(cell)
|
||||||
return cell
|
return cell
|
||||||
|
|
||||||
|
def get_speed_grade(self, grade: str):
|
||||||
|
return self.speed_grades[self.speed_grade_idx[grade]]
|
||||||
|
|
||||||
def finalise(self):
|
def finalise(self):
|
||||||
for sg in self.speed_grades:
|
for sg in self.speed_grades:
|
||||||
sg.finalise()
|
sg.finalise()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user