mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-16 00:15:01 -04:00
improved label checking
This commit is contained in:
parent
58c427b107
commit
a1cdf04bae
@ -421,8 +421,9 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Prin
|
|||||||
* Renames the names in this model to satisfy constrains of the final target language.
|
* Renames the names in this model to satisfy constrains of the final target language.
|
||||||
*
|
*
|
||||||
* @param renaming the renaming algorithm
|
* @param renaming the renaming algorithm
|
||||||
|
* @throws HDLException HDLException
|
||||||
*/
|
*/
|
||||||
public void rename(HDLModel.Renaming renaming) {
|
public void rename(HDLModel.Renaming renaming) throws HDLException {
|
||||||
for (HDLPort p : outputs)
|
for (HDLPort p : outputs)
|
||||||
p.rename(renaming);
|
p.rename(renaming);
|
||||||
for (HDLPort p : inputs)
|
for (HDLPort p : inputs)
|
||||||
@ -434,6 +435,20 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Prin
|
|||||||
n.rename(renaming);
|
n.rename(renaming);
|
||||||
|
|
||||||
hdlEntityName = renaming.checkName(hdlEntityName);
|
hdlEntityName = renaming.checkName(hdlEntityName);
|
||||||
|
|
||||||
|
checkUnique(getPorts());
|
||||||
|
checkUnique(listOfNets);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkUnique(Collection<? extends HasName> names) throws HDLException {
|
||||||
|
HashSet<String> set = new HashSet<>();
|
||||||
|
for (HasName hn : names) {
|
||||||
|
String name = hn.getName();
|
||||||
|
if (set.contains(name))
|
||||||
|
throw new HDLException(Lang.get("err_namesAreNotUnique_N", name));
|
||||||
|
else
|
||||||
|
set.add(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -178,8 +178,9 @@ public class HDLModel implements Iterable<HDLCircuit> {
|
|||||||
* Renames the signals in this model
|
* Renames the signals in this model
|
||||||
*
|
*
|
||||||
* @param renaming the renaming algorithm
|
* @param renaming the renaming algorithm
|
||||||
|
* @throws HDLException HDLException
|
||||||
*/
|
*/
|
||||||
public void rename(Renaming renaming) {
|
public void renameLabels(Renaming renaming) throws HDLException {
|
||||||
this.renaming = new RenameSingleCheck(renaming);
|
this.renaming = new RenameSingleCheck(renaming);
|
||||||
for (HDLCircuit c : circuitMap.values())
|
for (HDLCircuit c : circuitMap.values())
|
||||||
c.rename(this.renaming);
|
c.rename(this.renaming);
|
||||||
|
@ -14,7 +14,7 @@ import java.util.ArrayList;
|
|||||||
* Represents a net.
|
* Represents a net.
|
||||||
* A net can have only one input and several outputs.
|
* A net can have only one input and several outputs.
|
||||||
*/
|
*/
|
||||||
public class HDLNet implements Printable {
|
public class HDLNet implements Printable, HasName {
|
||||||
private String name;
|
private String name;
|
||||||
private ArrayList<HDLPort> inputs;
|
private ArrayList<HDLPort> inputs;
|
||||||
private HDLPort output;
|
private HDLPort output;
|
||||||
@ -89,9 +89,7 @@ public class HDLNet implements Printable {
|
|||||||
out.print(name).print("->").print(inputs.size());
|
out.print(name).print("->").print(inputs.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @return the name of the net
|
|
||||||
*/
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ import java.io.IOException;
|
|||||||
/**
|
/**
|
||||||
* A port
|
* A port
|
||||||
*/
|
*/
|
||||||
public class HDLPort implements Printable {
|
public class HDLPort implements Printable, HasName {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The ports direction
|
* The ports direction
|
||||||
@ -92,9 +92,7 @@ public class HDLPort implements Printable {
|
|||||||
net.addPort(this);
|
net.addPort(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @return the name of this port
|
|
||||||
*/
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
16
src/main/java/de/neemann/digital/hdl/model2/HasName.java
Normal file
16
src/main/java/de/neemann/digital/hdl/model2/HasName.java
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Helmut Neemann.
|
||||||
|
* Use of this source code is governed by the GPL v3 license
|
||||||
|
* that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
package de.neemann.digital.hdl.model2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemented by classes the needs unique names
|
||||||
|
*/
|
||||||
|
public interface HasName {
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
}
|
@ -83,23 +83,7 @@ public class VHDLGenerator implements Closeable {
|
|||||||
.mergeExpressions()
|
.mergeExpressions()
|
||||||
.nameNets();
|
.nameNets();
|
||||||
|
|
||||||
model.rename(name -> {
|
model.renameLabels(new VHDLRenaming());
|
||||||
if (VHDLKeywords.isKeyword(name))
|
|
||||||
return "p_" + name;
|
|
||||||
else {
|
|
||||||
if (Character.isDigit(name.charAt(0)))
|
|
||||||
name = "n" + name;
|
|
||||||
return name
|
|
||||||
.replace('.', '_')
|
|
||||||
.replace(',', '_')
|
|
||||||
.replace('-', '_')
|
|
||||||
.replace("\u00AC", "not")
|
|
||||||
.replace("~", "not")
|
|
||||||
.replace("=", "eq")
|
|
||||||
.replace("<", "le")
|
|
||||||
.replace(">", "gr");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
out.println("-- generated by Digital. Don't modify this file!");
|
out.println("-- generated by Digital. Don't modify this file!");
|
||||||
out.println("-- Any changes will be lost if this file is regenerated.");
|
out.println("-- Any changes will be lost if this file is regenerated.");
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018 Helmut Neemann.
|
|
||||||
* Use of this source code is governed by the GPL v3 license
|
|
||||||
* that can be found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
package de.neemann.digital.hdl.vhdl2;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of vhdl keywords
|
|
||||||
*/
|
|
||||||
public final class VHDLKeywords {
|
|
||||||
private static final HashSet<String> KEYWORDS = new HashSet<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
Collections.addAll(KEYWORDS,
|
|
||||||
"abs", "access", "after", "alias", "all", "and", "architecture", "array", "assert",
|
|
||||||
"attribute", "begin", "block", "body", "buffer", "bus", "case", "component", "configuration",
|
|
||||||
"constant", "disconnect", "downto", "else", "elsif", "end", "entity", "exit", "file",
|
|
||||||
"for", "function", "generate", "generic", "group", "guarded", "if", "impure", "in",
|
|
||||||
"inertial", "inout", "is", "label", "library", "linkage", "literal", "loop",
|
|
||||||
"map", "mod", "nand", "new", "next", "nor", "not", "null", "of",
|
|
||||||
"on", "open", "or", "others", "out", "package", "port", "postponed", "procedure",
|
|
||||||
"process", "pure", "range", "record", "register", "reject", "rem", "report", "return",
|
|
||||||
"rol", "ror", "select", "severity", "signal", "shared", "sla", "sll", "sra",
|
|
||||||
"srl", "subtype", "then", "to", "transport", "type", "unaffected", "units", "until",
|
|
||||||
"use", "variable", "wait", "when", "while", "with", "xnor", "xor");
|
|
||||||
}
|
|
||||||
|
|
||||||
private VHDLKeywords() {
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean isKeyword(String str) {
|
|
||||||
return KEYWORDS.contains(str.toLowerCase());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
86
src/main/java/de/neemann/digital/hdl/vhdl2/VHDLRenaming.java
Normal file
86
src/main/java/de/neemann/digital/hdl/vhdl2/VHDLRenaming.java
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Helmut Neemann.
|
||||||
|
* Use of this source code is governed by the GPL v3 license
|
||||||
|
* that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
package de.neemann.digital.hdl.vhdl2;
|
||||||
|
|
||||||
|
import de.neemann.digital.hdl.model2.HDLModel;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renames the labels to valid VHDL names.
|
||||||
|
*/
|
||||||
|
public class VHDLRenaming implements HDLModel.Renaming {
|
||||||
|
|
||||||
|
private static final HashSet<String> KEYWORDS = new HashSet<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
Collections.addAll(KEYWORDS,
|
||||||
|
"abs", "access", "after", "alias", "all", "and", "architecture", "array", "assert",
|
||||||
|
"attribute", "begin", "block", "body", "buffer", "bus", "case", "component", "configuration",
|
||||||
|
"constant", "disconnect", "downto", "else", "elsif", "end", "entity", "exit", "file",
|
||||||
|
"for", "function", "generate", "generic", "group", "guarded", "if", "impure", "in",
|
||||||
|
"inertial", "inout", "is", "label", "library", "linkage", "literal", "loop",
|
||||||
|
"map", "mod", "nand", "new", "next", "nor", "not", "null", "of",
|
||||||
|
"on", "open", "or", "others", "out", "package", "port", "postponed", "procedure",
|
||||||
|
"process", "pure", "range", "record", "register", "reject", "rem", "report", "return",
|
||||||
|
"rol", "ror", "select", "severity", "signal", "shared", "sla", "sll", "sra",
|
||||||
|
"srl", "subtype", "then", "to", "transport", "type", "unaffected", "units", "until",
|
||||||
|
"use", "variable", "wait", "when", "while", "with", "xnor", "xor");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String checkName(String name) {
|
||||||
|
if (isKeyword(name))
|
||||||
|
return "p_" + name;
|
||||||
|
else {
|
||||||
|
if (Character.isDigit(name.charAt(0)))
|
||||||
|
name = "n" + name;
|
||||||
|
return cleanName(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isKeyword(String str) {
|
||||||
|
return KEYWORDS.contains(str.toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String cleanName(String name) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < name.length(); i++) {
|
||||||
|
char c = name.charAt(i);
|
||||||
|
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'))
|
||||||
|
sb.append(c);
|
||||||
|
else {
|
||||||
|
switch (c) {
|
||||||
|
case '~':
|
||||||
|
case '\u00AC':
|
||||||
|
sb.append("not");
|
||||||
|
break;
|
||||||
|
case '=':
|
||||||
|
sb.append("eq");
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
sb.append("le");
|
||||||
|
break;
|
||||||
|
case '>':
|
||||||
|
sb.append("gr");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (sb.length() > 0 && sb.charAt(sb.length() - 1) != '_')
|
||||||
|
sb.append("_");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (sb.length() > 0 && sb.charAt(sb.length() - 1) == '_')
|
||||||
|
sb.setLength(sb.length() - 1);
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -860,6 +860,7 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
|
|||||||
<string name="err_monoflopRequiresOneClock">Wird ein Monoflop verwendet, muss es genau ein Taktelement geben!</string>
|
<string name="err_monoflopRequiresOneClock">Wird ein Monoflop verwendet, muss es genau ein Taktelement geben!</string>
|
||||||
<string name="err_couldNotCreateElement_N">Konnte kein Element vom Typ "{0}" erzeugen!</string>
|
<string name="err_couldNotCreateElement_N">Konnte kein Element vom Typ "{0}" erzeugen!</string>
|
||||||
<string name="err_centralDefinedRomsAreNotSupported">Zentral definierte ROM-Inhalte werden nicht unterstützt!</string>
|
<string name="err_centralDefinedRomsAreNotSupported">Zentral definierte ROM-Inhalte werden nicht unterstützt!</string>
|
||||||
|
<string name="err_namesAreNotUnique_N">Der Name "{0}" ist nicht eindeutig!</string>
|
||||||
|
|
||||||
<string name="err_errorWritingDataToProcess">Es konnten keine Werte an den externen Prozess übergeben werden!</string>
|
<string name="err_errorWritingDataToProcess">Es konnten keine Werte an den externen Prozess übergeben werden!</string>
|
||||||
<string name="err_errorReadingDataToProcess">Es konnten keine Werte vom externen Prozess gelesen werden!</string>
|
<string name="err_errorReadingDataToProcess">Es konnten keine Werte vom externen Prozess gelesen werden!</string>
|
||||||
|
@ -881,6 +881,7 @@
|
|||||||
<string name="err_errorAnalysingCircuit_N">Error analysing the circuit: {0}</string>
|
<string name="err_errorAnalysingCircuit_N">Error analysing the circuit: {0}</string>
|
||||||
<string name="err_romNeedsALabelToBeExported">Every ROM needs a unique label to be exported!</string>
|
<string name="err_romNeedsALabelToBeExported">Every ROM needs a unique label to be exported!</string>
|
||||||
<string name="err_counterNeedsMoreBits">The counter needs at least two bits.</string>
|
<string name="err_counterNeedsMoreBits">The counter needs at least two bits.</string>
|
||||||
|
<string name="err_namesAreNotUnique_N">The name "{0}" is not unique!</string>
|
||||||
|
|
||||||
<string name="key_AddrBits">Address Bits</string><!-- ROM, RAMDualPort, RAMSinglePort, RAMSinglePortSel, EEPROM -->
|
<string name="key_AddrBits">Address Bits</string><!-- ROM, RAMDualPort, RAMSinglePort, RAMSinglePortSel, EEPROM -->
|
||||||
<string name="key_AddrBits_tt">Number of address bits used.</string>
|
<string name="key_AddrBits_tt">Number of address bits used.</string>
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Helmut Neemann.
|
||||||
|
* Use of this source code is governed by the GPL v3 license
|
||||||
|
* that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
package de.neemann.digital.hdl.vhdl2;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
public class VHDLRenamingTest extends TestCase {
|
||||||
|
|
||||||
|
public void testCheckName() {
|
||||||
|
VHDLRenaming r = new VHDLRenaming();
|
||||||
|
assertEquals("a", r.checkName("a"));
|
||||||
|
assertEquals("n0a", r.checkName("0a"));
|
||||||
|
assertEquals("p_in", r.checkName("in"));
|
||||||
|
assertEquals("a_u_in", r.checkName("a&u(in"));
|
||||||
|
assertEquals("a_in", r.checkName("a&ü(in"));
|
||||||
|
assertEquals("a_o_o", r.checkName("a\"o\"o"));
|
||||||
|
assertEquals("o", r.checkName("\"o\""));
|
||||||
|
assertEquals("o", r.checkName("_o_"));
|
||||||
|
assertEquals("notQ", r.checkName("~Q"));
|
||||||
|
assertEquals("aleb", r.checkName("a<b"));
|
||||||
|
assertEquals("agrb", r.checkName("a>b"));
|
||||||
|
assertEquals("aeqb", r.checkName("a=b"));
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user