Skip to content

Commit

Permalink
restructured reset handling in rtl output so signals w/o reset are moved
Browse files Browse the repository at this point in the history
out of else block (part of issue #62)
  • Loading branch information
Scott Nellenbach committed Jun 16, 2019
1 parent 48aeea5 commit ac16336
Show file tree
Hide file tree
Showing 29 changed files with 1,151 additions and 1,412 deletions.
1 change: 0 additions & 1 deletion src/ordt/output/FieldProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,6 @@ else if (pList.hasProperty("dontcompare")) {

// set interrupt enable/mask reference
if (pList.hasProperty("enable")) {
if (getInstancePath().contains("global")) System.out.println("FieldProperties extractProperties: setting enable on inst=" + getInstancePath() + ", enable=" + pList.getProperty("enable") );
setRef(RhsRefType.INTR_ENABLE, pList.getProperty("enable"), pList.getDepth("enable"));
}
else if (pList.hasProperty("mask")) {
Expand Down
35 changes: 16 additions & 19 deletions src/ordt/output/systemverilog/SystemVerilogDecodeModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,6 @@ private String getGroupPrefix(boolean isPrimary) {
/** generate common internal pio interface code */
private void generateCommonPio(AddressableInstanceProperties topRegProperties) {
String grpName = "pio i/f";
String rstGrpName = "pio i/f (reset signal = " + builder.getDefaultReset() + ")";
String optGrpName = (ExtParameters.sysVerResetAllOutputs())? rstGrpName : grpName; // selectable block group

// add internal registered input sigs
this.addScalarReg("pio_write_active"); // write indication
Expand All @@ -187,19 +185,19 @@ private void generateCommonPio(AddressableInstanceProperties topRegProperties) {
this.addVectorReg("pio_dec_write_data_d1", 0, builder.getMaxRegWidth()); // input write data capture register

// pio read/write actives - enabled by ext re/we and disabled when ack/nack
this.addResetAssign(rstGrpName, builder.getDefaultReset(), "pio_write_active <= " + ExtParameters.sysVerSequentialAssignDelayString() + " 1'b0;");
this.addResetAssign(rstGrpName, builder.getDefaultReset(), "pio_read_active <= " + ExtParameters.sysVerSequentialAssignDelayString() + " 1'b0;");
this.addRegAssign(rstGrpName, "pio_write_active <= " + ExtParameters.sysVerSequentialAssignDelayString() + " pio_write_active ? pio_no_acks : pio_activate_write;"); // active stays high until ack/nack
this.addRegAssign(rstGrpName, "pio_read_active <= " + ExtParameters.sysVerSequentialAssignDelayString() + " pio_read_active ? pio_no_acks : pio_activate_read;");
this.addResetAssign(grpName, builder.getDefaultReset(), "pio_write_active <= " + ExtParameters.sysVerSequentialAssignDelayString() + " 1'b0;");
this.addResetAssign(grpName, builder.getDefaultReset(), "pio_read_active <= " + ExtParameters.sysVerSequentialAssignDelayString() + " 1'b0;");
this.addRegAssign(grpName, "pio_write_active <= " + ExtParameters.sysVerSequentialAssignDelayString() + " pio_write_active ? pio_no_acks : pio_activate_write;"); // active stays high until ack/nack
this.addRegAssign(grpName, "pio_read_active <= " + ExtParameters.sysVerSequentialAssignDelayString() + " pio_read_active ? pio_no_acks : pio_activate_read;");

if (mapHasMultipleAddresses()) {
if (ExtParameters.sysVerResetAllOutputs())
this.addResetAssign(rstGrpName, builder.getDefaultReset(), "pio_dec_address_d1 <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + builder.getMapAddressWidth() + "'b0;" );
this.addRegAssign(optGrpName, "pio_dec_address_d1 <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + pioInterfaceAddressName + ";"); // capture address if new transaction
this.addResetAssign(grpName, builder.getDefaultReset(), "pio_dec_address_d1 <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + builder.getMapAddressWidth() + "'b0;" );
this.addRegAssign(grpName, "pio_dec_address_d1 <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + pioInterfaceAddressName + ";"); // capture address if new transaction
}
if (ExtParameters.sysVerResetAllOutputs())
this.addResetAssign(rstGrpName, builder.getDefaultReset(), "pio_dec_write_data_d1 <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + builder.getMaxRegWidth() + "'b0;" );
this.addRegAssign(optGrpName, "pio_dec_write_data_d1 <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + pioInterfaceWriteDataName + ";"); // capture write data if new transaction
this.addResetAssign(grpName, builder.getDefaultReset(), "pio_dec_write_data_d1 <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + builder.getMaxRegWidth() + "'b0;" );
this.addRegAssign(grpName, "pio_dec_write_data_d1 <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + pioInterfaceWriteDataName + ";"); // capture write data if new transaction

// if write enables are specified, then capture
if (hasWriteEnables()) {
Expand All @@ -217,8 +215,8 @@ private void generateCommonPio(AddressableInstanceProperties topRegProperties) {
this.addVectorReg("pio_dec_trans_size_d1", 0, builder.getMaxWordBitSize()); // input trans size capture register
this.addRegAssign(grpName, "pio_dec_trans_size_d1 <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + pioInterfaceTransactionSizeName + ";"); // capture trans size if new transaction
this.addVectorReg(pioInterfaceRetTransactionSizeName, 0, builder.getMaxWordBitSize()); // register the size
this.addResetAssign(rstGrpName, builder.getDefaultReset(), pioInterfaceRetTransactionSizeName + " <= " + ExtParameters.sysVerSequentialAssignDelayString() + "" + builder.getMaxWordBitSize() + "'b0;"); // reset for delayed block select
this.addRegAssign(rstGrpName, pioInterfaceRetTransactionSizeName + " <= " + ExtParameters.sysVerSequentialAssignDelayString() + "reg_width;"); // use pio_width from decode to set
this.addResetAssign(grpName, builder.getDefaultReset(), pioInterfaceRetTransactionSizeName + " <= " + ExtParameters.sysVerSequentialAssignDelayString() + "" + builder.getMaxWordBitSize() + "'b0;"); // reset for delayed block select
this.addRegAssign(grpName, pioInterfaceRetTransactionSizeName + " <= " + ExtParameters.sysVerSequentialAssignDelayString() + "reg_width;"); // use pio_width from decode to set
this.addVectorReg("reg_width", 0, builder.getMaxWordBitSize()); // size of current register
}

Expand Down Expand Up @@ -2554,7 +2552,6 @@ private ExternalInterfaceInfo generateBaseExternalInterface(AddressableInstanceP
String intHwToDecodeTransactionSizeName = addrInstProperties.getFullSignalName(DefSignalType.H2D_RETSIZE) + "_d1"; // size of return read transaction in words

String grpName = "external i/f";
String rstGrpName = "external i/f (reset signal = " + builder.getDefaultReset() + ")";

// register the outputs and assign output reg values
this.addVectorReg(extIf.decodeToHwName, 0, addrInstProperties.getMaxRegWidth());
Expand All @@ -2568,14 +2565,14 @@ private ExternalInterfaceInfo generateBaseExternalInterface(AddressableInstanceP
this.addScalarReg(intDecodeToHwWeName);
this.addScalarReg(intDecodeToHwReName);
// reset output signals
this.addResetAssign(rstGrpName, builder.getDefaultReset(), extIf.decodeToHwWeName + " <= " + ExtParameters.sysVerSequentialAssignDelayString() + " 1'b0;" );
this.addResetAssign(rstGrpName, builder.getDefaultReset(), extIf.decodeToHwReName + " <= " + ExtParameters.sysVerSequentialAssignDelayString() + " 1'b0;" );
this.addResetAssign(grpName, builder.getDefaultReset(), extIf.decodeToHwWeName + " <= " + ExtParameters.sysVerSequentialAssignDelayString() + " 1'b0;" );
this.addResetAssign(grpName, builder.getDefaultReset(), extIf.decodeToHwReName + " <= " + ExtParameters.sysVerSequentialAssignDelayString() + " 1'b0;" );

String ackInhibitStr = "~" + extIf.hwToDecodeAckName + " & ~" + extIf.hwToDecodeNackName;
this.addRegAssign(grpName, extIf.decodeToHwName + " <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + intDecodeToHwName + ";"); // assign next to flop
if (hasWriteEnables()) this.addRegAssign(grpName, extIf.decodeToHwEnableName + " <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + intDecodeToHwEnableName + ";"); // assign next to flop
this.addRegAssign(rstGrpName, extIf.decodeToHwWeName + " <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + intDecodeToHwWeName + " & " + ackInhibitStr + ";"); // assign next to flop
this.addRegAssign(rstGrpName, extIf.decodeToHwReName + " <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + intDecodeToHwReName + " & " + ackInhibitStr + ";"); // assign next to flop
this.addRegAssign(grpName, extIf.decodeToHwWeName + " <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + intDecodeToHwWeName + " & " + ackInhibitStr + ";"); // assign next to flop
this.addRegAssign(grpName, extIf.decodeToHwReName + " <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + intDecodeToHwReName + " & " + ackInhibitStr + ";"); // assign next to flop

// if size of external range is greater than one reg we'll need an external address
if (addrInstProperties.hasExtAddress()) {
Expand All @@ -2594,8 +2591,8 @@ private ExternalInterfaceInfo generateBaseExternalInterface(AddressableInstanceP
this.addRegAssign(grpName, extIf.decodeToHwTransactionSizeName + " <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + intDecodeToHwTransactionSizeName + ";"); // assign next to flop

this.addVectorReg(intHwToDecodeTransactionSizeName, 0, regWordBits);
this.addResetAssign(rstGrpName, builder.getDefaultReset(), intHwToDecodeTransactionSizeName + " <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + regWordBits +"'b0;"); // reset input size flop
this.addRegAssign(rstGrpName, intHwToDecodeTransactionSizeName + " <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + extIf.hwToDecodeTransactionSizeName + ";"); // assign input size to flop
this.addResetAssign(grpName, builder.getDefaultReset(), intHwToDecodeTransactionSizeName + " <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + regWordBits +"'b0;"); // reset input size flop
this.addRegAssign(grpName, intHwToDecodeTransactionSizeName + " <= " + ExtParameters.sysVerSequentialAssignDelayString() + " " + extIf.hwToDecodeTransactionSizeName + ";"); // assign input size to flop
}
return extIf;
}
Expand Down
107 changes: 73 additions & 34 deletions src/ordt/output/systemverilog/common/SystemVerilogRegisters.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import ordt.output.common.MsgUtils;
import ordt.output.common.OutputWriterIntf;
Expand Down Expand Up @@ -61,6 +64,16 @@ public void addReset(String reset, boolean activeLow) {
public HashMap<String, Boolean> getResets() {
return resetActiveLow;
}

/** write out verilog for this set of regs
* @param resolveNames */
public void writeVerilog(int indentLevel) {
for (String regName: registers.keySet()) {
registers.get(regName).writeVerilog(indentLevel);
}
}

// ------------------------------

/** inner class to hold verilog info associated with a register group */
public class VerilogRegInfo {
Expand All @@ -71,6 +84,8 @@ public class VerilogRegInfo {
private List<String> combinAssignList; // list of combinatorial assign statements
private List<String> hiPrecCombinAssignList; // list of high precedence combinatorial assign statements
private List<String> lowPrecCombinAssignList; // list of low precedence combinatorial assign statements
private HashSet<String> signalsWithResetAssigns; // set of signals having a reset assign
private boolean hasSimpleRegAssigns = true; // allow refactoring is only simple assigns

/**
* @param name - name of this reg group
Expand All @@ -83,10 +98,10 @@ public VerilogRegInfo(String name) {
this.combinAssignList = new ArrayList<String>(); // list of combinatorial assign statements
this.hiPrecCombinAssignList = new ArrayList<String>(); // list of high precedence combinatorial assign statements
this.lowPrecCombinAssignList = new ArrayList<String>(); // list of low precedence combinatorial assign statements
this.signalsWithResetAssigns= new HashSet<String>(); // set of signals having a reset assign
}
/** get name
* @return the name
*/

/** get name of this group */
public String getName() {
return name;
}
Expand Down Expand Up @@ -128,14 +143,34 @@ else if (!resetActiveLow.containsKey(reset)) {
}
// add the assign stmt
resetAssignList.get(reset).add(stmt);
// save signals with reset assingment
String assignedSignal = extractAssignedSignalName(stmt);
if (assignedSignal != null) signalsWithResetAssigns.add(assignedSignal);
}

/* extract assigned signal name from a sequential assignment string */
private String extractAssignedSignalName(String stmt) {
Pattern p = Pattern.compile("^\\s*(\\S+)\\s*<=\\s*");
Matcher m = p.matcher(stmt);
if (m.find()) {
String sigName = m.group(1);
return sigName;
}
return null;
}

/** add a sync register assignment
* @param stmt - verilog assignment statement
*/
public void addRegAssign(String stmt) {
// add the assign stmt
regAssignList.add(stmt);
// check for non-simple forms that can not be refactored
String assignedSignal = extractAssignedSignalName(stmt);
if (assignedSignal == null) {
hasSimpleRegAssigns = false;
//System.out.println("VerilogRegInfo addRegAssign: non-simple stmt=" + stmt);
}
}
/** add a list of reg assigns */
public void addRegAssign(List<String> stmts) {
Expand All @@ -155,6 +190,11 @@ public void addCombinAssign(List<String> stmts) {
// add the assign stmt
combinAssignList.addAll(stmts);
}

private boolean hasResetAssigns() {
return !resetAssignList.isEmpty();
}

/** add a combinatorial assignment to one of the hi/low precedence lists
* @param hiPrecedence - true if this statement will have high priority
* @param stmt - verilog assignment statement
Expand All @@ -166,8 +206,7 @@ public void addPrecCombinAssign(boolean hiPrecedence, String stmt) {
else lowPrecCombinAssignList.add(stmt);
}

/** write out high precedence verilog for this reg/group
* @param resolveNames */
/** write out high precedence verilog for this reg/group */
private void writeHiPrecedenceStatements(int indentLevel) {
if (!hiPrecCombinAssignList.isEmpty()) {
Iterator<String> it = hiPrecCombinAssignList.iterator();
Expand All @@ -177,8 +216,7 @@ private void writeHiPrecedenceStatements(int indentLevel) {
}
}

/** write out low precedence verilog for this reg/group
* @param resolveNames */
/** write out low precedence verilog for this reg/group */
private void writeLowPrecedenceStatements(int indentLevel) {
if (!lowPrecCombinAssignList.isEmpty()) {
Iterator<String> it = lowPrecCombinAssignList.iterator();
Expand All @@ -188,8 +226,7 @@ private void writeLowPrecedenceStatements(int indentLevel) {
}
}

/** write out verilog for this reg/group
* @param resolveNames */
/** write out verilog for this reg/group */
public void writeVerilog(int indentLevel) {

// write combinatorial assignment block
Expand All @@ -211,12 +248,13 @@ public void writeVerilog(int indentLevel) {

// write synchronous assignment block
if (!regAssignList.isEmpty()) {
//System.out.println("VerilogRegInfo writeVerilog: assigned reset sigs=" + signalsWithResetAssigns);
writer.writeStmt(indentLevel, "//------- reg assigns for " + name);
String asyncStr = useAsyncResets? genAsyncString() : "";
if (SystemVerilogModule.isLegacyVerilog()) writer.writeStmt(indentLevel++, "always @ (posedge " + clkName + asyncStr + ") begin");
else writer.writeStmt(indentLevel++, "always_ff @ (posedge " + clkName + asyncStr + ") begin");
boolean hasResets = writeRegResets(indentLevel, resetAssignList);
writeRegAssigns(indentLevel, hasResets, regAssignList);
writeRegResets(indentLevel, resetAssignList);
writeRegAssigns(indentLevel, regAssignList);
writer.writeStmt(--indentLevel, "end");
writer.writeStmt(indentLevel, "");
}
Expand All @@ -231,50 +269,51 @@ private String genAsyncString() {
}
return outStr;
}
/** write always block reset stmts
* @param resolveNames */
private boolean writeRegResets(int indentLevel, HashMap<String, List<String>> regResetList) {
/** write always block reset stmts */
private void writeRegResets(int indentLevel, HashMap<String, List<String>> regResetList) {
// write reset assigns for each reset signal
String firstRst = "";
boolean hasResets = false;
for (String reset: regResetList.keySet()) {
if (!regResetList.get(reset).isEmpty()) {
String notStr = (resetActiveLow.get(reset)) ? "! " : "";
hasResets = true;
writer.writeStmt(indentLevel++, firstRst + "if (" + notStr + reset + ") begin");
firstRst = "else ";
Iterator<String> it = regResetList.get(reset).iterator();
while (it.hasNext()) {
String elem = it.next();
writer.writeStmt(indentLevel, elem);
String stmt = it.next();
writer.writeStmt(indentLevel, stmt);
}
writer.writeStmt(--indentLevel, "end");
}
}
return hasResets;
}

/** write always block assign stmts
* @param resolveNames */
private void writeRegAssigns(int indentLevel, boolean hasResets, List<String> regAssignList) {
/** write always block assign stmts */
private void writeRegAssigns(int indentLevel, List<String> regAssignList) {
if (regAssignList.isEmpty()) return;
boolean hasResets = hasResetAssigns();
List<String> movedAssignList = new ArrayList<String>();
if (hasResets) writer.writeStmt(indentLevel++, "else begin");
Iterator<String> it = regAssignList.iterator();
while (it.hasNext()) {
String elem = it.next();
writer.writeStmt(indentLevel, elem);
String stmt = it.next();
// if simple form, move signals without reset assign out of else block
String assignedSignal = extractAssignedSignalName(stmt);
if (hasSimpleRegAssigns && hasResets && !signalsWithResetAssigns.contains(assignedSignal)) {
//System.out.println("VerilogRegInfo writeRegAssigns: signal=" + assignedSignal + " has no reset and will be moved out of else block");
movedAssignList.add(stmt);
}
else writer.writeStmt(indentLevel, stmt);
}
if (hasResets) writer.writeStmt(--indentLevel, "end");
// move non-reset assigns out of else block
it = movedAssignList.iterator();
while (it.hasNext()) {
String stmt = it.next();
writer.writeStmt(indentLevel, stmt);
}
if (hasResets) writer.writeStmt(--indentLevel, "end");
}

}
} // end VerilogRegInfo

/** write out verilog for this set of regs
* @param resolveNames */
public void writeVerilog(int indentLevel) {
for (String regName: registers.keySet()) {
registers.get(regName).writeVerilog(indentLevel);
}
}

}
Loading

0 comments on commit ac16336

Please sign in to comment.