
spinal.core.internals.VerilogBase.scala Maven / Gradle / Ivy
/* *\
** _____ ____ _____ _____ __ **
** / ___// __ \/ _/ | / / | / / HDL Core **
** \__ \/ /_/ // // |/ / /| | / / (c) Dolu, All rights reserved **
** ___/ / ____// // /| / ___ |/ /___ **
** /____/_/ /___/_/ |_/_/ |_/_____/ **
** **
** This library is free software; you can redistribute it and/or **
** modify it under the terms of the GNU Lesser General Public **
** License as published by the Free Software Foundation; either **
** version 3.0 of the License, or (at your option) any later version. **
** **
** This library is distributed in the hope that it will be useful, **
** but WITHOUT ANY WARRANTY; without even the implied warranty of **
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU **
** Lesser General Public License for more details. **
** **
** You should have received a copy of the GNU Lesser General Public **
** License along with this library. **
\* */
package spinal.core.internals
import spinal.core._
trait VerilogTheme{
def tab = " "
def porttab = ""
def maintab = ""
}
class Tab2 extends VerilogTheme {
override def tab = " "
override def porttab = " "
override def maintab = " "
}
class Tab4 extends VerilogTheme {
override def tab = " "
override def porttab = ""
override def maintab = ""
}
trait VerilogBase extends VhdlVerilogBase{
var globalPrefix = ""
val theme = new Tab2 //TODO add into SpinalConfig
def expressionAlign(net: String, section: String, name: String) = {
f"$net%-10s $section%-8s $name"
}
def emitExpressionWrap(e: Expression, name: String): String = {
// s" wire ${emitType(e)} ${name};\n"
if (!e.isInstanceOf[SpinalStruct]) {
val isReg = e.isInstanceOf[Multiplexer]
theme.maintab + expressionAlign(if(isReg) "reg" else "wire", emitType(e), name) + ";\n"
} else
theme.maintab + expressionAlign(e.asInstanceOf[SpinalStruct].getTypeString, "", name) + ";\n"
}
def emitExpressionWrap(e: Expression, name: String, nature: String): String = {
// s" $nature ${emitType(e)} ${name};\n"
theme.maintab + expressionAlign(nature, emitType(e), name) + ";\n"
}
def emitClockEdge(clock: String, edgeKind: EdgeKind): String = {
s"${
edgeKind match {
case RISING => "posedge"
case FALLING => "negedge"
}
} ${clock}"
}
def emitResetEdge(reset: String, polarity: Polarity): String = {
s"${
polarity match {
case HIGH => "posedge"
case LOW => "negedge"
}
} ${reset}"
}
def emitQuotedString(string: String): String = {
"\"" + string.replace("\"", "\\\"") + "\""
}
def emitSyntaxAttributes(attributes: Iterable[Attribute]): String = {
val values = for (attribute <- attributes if attribute.attributeKind() == DEFAULT_ATTRIBUTE) yield attribute match {
case attribute: AttributeString => attribute.getName + " = " + emitQuotedString(attribute.value)
case attribute: AttributeInteger => attribute.getName + " = " + attribute.value.toString
case attribute: AttributeFlag => attribute.getName
}
if(values.isEmpty) return ""
"(* " + values.reduce(_ + " , " + _) + " *) "
}
def emitCommentAttributes(attributes: Iterable[Attribute]): String = {
val values = for (attribute <- attributes if attribute.attributeKind() == COMMENT_ATTRIBUTE) yield attribute match {
case attribute: AttributeString => attribute.getName + " = " + emitQuotedString(attribute.value)
case attribute: AttributeInteger => attribute.getName + " = " + attribute.value.toString
case attribute: AttributeFlag => attribute.getName
}
if(values.isEmpty) return ""
" /* " + values.reduce(_ + " , " + _) + " */ "
}
def emitCommentEarlyAttributes(attributes: Iterable[Attribute]): String = {
val values = for (attribute <- attributes if attribute.attributeKind() == COMMENT_TYPE_ATTRIBUTE) yield attribute match {
case attribute: AttributeString => attribute.getName + " = " + emitQuotedString(attribute.value)
case attribute: AttributeInteger => attribute.getName + " = " + attribute.value.toString
case attribute: AttributeFlag => attribute.getName
}
if(values.isEmpty) return ""
" /* " + values.reduce(_ + " , " + _) + " */ "
}
def emitEnumLiteral[T <: SpinalEnum](senum: SpinalEnumElement[T], encoding: SpinalEnumEncoding, prefix: String = "`"): String = {
// prefix + senum.spinalEnum.getName() + "_" + encoding.getName() + "_" + senum.getName()
var prefix_fix = prefix;
if(prefix=="`" && !senum.spinalEnum.isGlobalEnable) prefix_fix = ""
if(senum.spinalEnum.isPrefixEnable) {
val withEncoding = senum.spinalEnum.defaultEncoding != encoding && (senum.spinalEnum.defaultEncoding == native && encoding != binarySequential)
prefix_fix + globalPrefix + senum.spinalEnum.getName() + (if(withEncoding) "_" + encoding.getName() else "") + "_" + senum.getName()
} else {
prefix_fix + globalPrefix + senum.getName()
}
}
def emitEnumType[T <: SpinalEnum](senum: SpinalEnumCraft[T], prefix: String): String = emitEnumType(senum.spinalEnum, senum.getEncoding, prefix)
def emitEnumType(senum: SpinalEnum, encoding: SpinalEnumEncoding, prefix: String = "`"): String = {
// prefix + senum.getName() + "_" + encoding.getName() + "_type"
val bitCount = encoding.getWidth(senum)
s"[${bitCount - 1}:0]"
}
def getReEncodingFuntion(spinalEnum: SpinalEnum, source: SpinalEnumEncoding, target: SpinalEnumEncoding): String = {
s"${globalPrefix}${spinalEnum.getName()}_${source.getName()}_to_${target.getName()}"
}
def emitStructType(struct: SpinalStruct): String = {
return struct.getTypeString
}
def emitType(e: Expression): String = e.getTypeObject match {
case `TypeBool` => ""
case `TypeBits` => emitRange(e.asInstanceOf[WidthProvider])
case `TypeUInt` => emitRange(e.asInstanceOf[WidthProvider])
case `TypeSInt` => emitRange(e.asInstanceOf[WidthProvider])
case `TypeEnum` => e match {
case e : EnumEncoded => emitEnumType(e.getDefinition, e.getEncoding)
}
case `TypeStruct` => emitStructType(e.asInstanceOf[SpinalStruct])
}
def emitDirection(baseType: BaseType) = baseType.dir match {
case `in` => "input "
case `out` => "output"
case `inout` => "inout "
case _ => throw new Exception("Unknown direction"); ""
}
def emitRange(node: WidthProvider) = s"[${node.getWidth - 1}:0]"
def signalNeedProcess(baseType: BaseType): Boolean = {
if(baseType.isReg) return true
if(baseType.dlcIsEmpty || baseType.isAnalog) return false
if(!baseType.hasOnlyOneStatement || baseType.head.parentScope != baseType.rootScopeStatement) return true
return false
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy