#include "ReferenceInterface.h"
#include "AbstractBlock.h"
+#include "BlockParameter.h"
ReferenceInterface::ReferenceInterface(AbstractBlock* _owner) throw(Exception) : AbstractInterface(_owner) {
if (_owner->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE));
}
ReferenceInterface::ReferenceInterface(AbstractBlock* _owner,
- const QString& _name, const QString&_type,
- const QString& _width,
+ const QString& _name,
int _direction,
int _purpose,
+ const QString& _type,
+ const QString& _width,
+ int _endianess,
int _multiplicity)
-throw (Exception) : AbstractInterface(_owner, _name, _type, _width, _direction, _purpose) {
+throw (Exception) : AbstractInterface(_owner, _name, _direction, _purpose, _type, _width) {
if (_owner->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE));
multiplicity = _multiplicity;
+
+ if (purpose == Control) {
+ // override some attributes with forced values
+ type = Boolean;
+ width = "1";
+ multiplicity = 1;
+ }
if (direction == InOut) {
multiplicity = 1;
}
else if (txt == "reset") {
return Reset;
}
- if (txt == "wb") {
+ else if (txt == "wb") {
return Wishbone;
- }
+ }
return Data;
}
}
return mult;
}
+
+int ReferenceInterface::getClockDomain() throw(Exception) {
+
+ throw(Exception(IFACE_INVALID_TYPE,this));
+}
+
+/* NOTE on clock associated to each interface:
+
+ Each interface must be associated to a clock so that blast can determine
+ if there are no problems with clocks domains. This clock must correspond to
+ the name of a clock interface owned by the same block or to a user parameter
+ for which the value indicate the clock frequency. This latter case is used only
+ for input interfaces of blocks that will be directly linked to the outside of top group
+ (NB: directly only means that there are no others functional blocks between the
+ mentionnned block and the outside, but it can be within subgroups) and with these interfaces
+ that receives a data signal synchronized on an outside clock that is not provided to the design.
+ For example, on the APF27 board, there is a link between imx and spartan 3 and signals are at 133MHz.
+ But there is no clock provided to the FPGA.
+
+ Reference blocks are created with:
+ - input clocks are associated to themselves.
+ - output clocks are associated to one of the clock.
+ - reset are associated to one of the clock (since they are generated
+ by clkrstgen, they are really synchronized with a clock)
+ - all other signals are associated to one of the clock or to a parameter
+ The name of the associated clock is given in the xml description file. If not
+ indicated it is by default the name of the input clock. In case of there are
+ several input clocks, the xml is incoherent if other signal do not indicate the name of
+ the associated clock.
+
+ Functional block are created by cloning a reference thus they follow the same rules as
+ reference blocks.
+
+ A group is created with interfaces that have an inherited clock name thus, setting a name
+ is meaningless and an iterative process must be used to retrieve the clock domain from
+ the interface that is connected from the group interface (cf. GroupBlock::getClockDomain())
+
+ The following method checks if these rules are applied correctly.
+
+*/
+bool ReferenceInterface::checkSetClockIface(QString _name) {
+
+ /* 3 cases :
+ - this is a clock input: name must be the same as the iface name
+ - this is an output clock or reset: name must be an existing clock name.
+ - other cases: name must ba a parameter name or an exisiting clock name
+
+ NB: if it's a parameter it must be prepend with a $.
+ */
+ if ((purpose == Clock) && (direction == Input)) {
+ if (_name == name) {
+ clkIfaceName = _name;
+ clkIfaceType = ClockName;
+ return true;
+ }
+ }
+ else if ((purpose == Reset) || ((purpose == Clock) && (direction == Output))) {
+ QList<AbstractInterface*> clocks = owner->getInterfaces(Input, Clock);
+ foreach(AbstractInterface* iface, clocks) {
+ if (iface->getName() == _name) {
+ clkIfaceName = _name;
+ clkIfaceType = ClockName;
+ return true;
+ }
+ }
+ }
+ else {
+ if (_name.at(0) == '$') {
+ _name.remove(0,1);
+ QList<BlockParameter* > params = owner->getUserParameters();
+ foreach(BlockParameter* p, params) {
+ if (p->getName() == _name) {
+ clkIfaceName = _name;
+ clkIfaceType = ParameterName;
+ return true;
+ }
+ }
+ }
+ else {
+ QList<AbstractInterface*> clocks = owner->getInterfaces(Input, Clock);
+ foreach(AbstractInterface* iface, clocks) {
+ if (iface->getName() == _name) {
+ clkIfaceName = _name;
+ clkIfaceType = ClockName;
+ return true;
+ }
+ }
+ }
+ }
+ clkIfaceName = "";
+ clkIfaceType = NoName;
+ return false;
+}
+