mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-14 23:36:27 -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.
|
||||
*
|
||||
* @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)
|
||||
p.rename(renaming);
|
||||
for (HDLPort p : inputs)
|
||||
@ -434,6 +435,20 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Prin
|
||||
n.rename(renaming);
|
||||
|
||||
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
|
||||
*
|
||||
* @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);
|
||||
for (HDLCircuit c : circuitMap.values())
|
||||
c.rename(this.renaming);
|
||||
|
@ -14,7 +14,7 @@ import java.util.ArrayList;
|
||||
* Represents a net.
|
||||
* 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 ArrayList<HDLPort> inputs;
|
||||
private HDLPort output;
|
||||
@ -89,9 +89,7 @@ public class HDLNet implements Printable {
|
||||
out.print(name).print("->").print(inputs.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of the net
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import java.io.IOException;
|
||||
/**
|
||||
* A port
|
||||
*/
|
||||
public class HDLPort implements Printable {
|
||||
public class HDLPort implements Printable, HasName {
|
||||
|
||||
/**
|
||||
* The ports direction
|
||||
@ -92,9 +92,7 @@ public class HDLPort implements Printable {
|
||||
net.addPort(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of this port
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
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()
|
||||
.nameNets();
|
||||
|
||||
model.rename(name -> {
|
||||
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");
|
||||
}
|
||||
});
|
||||
model.renameLabels(new VHDLRenaming());
|
||||
|
||||
out.println("-- generated by Digital. Don't modify this file!");
|
||||
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_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_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_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_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_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_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