Coding for Reuse Course - Module 4 Lesson 1
Synthesis Part 1

Up until now, we have been performing a purely theoretical exercise; using simulation only. Bear in mind, also, we have yet to simulate every single instruction. Some simulators, especially IVERILOG, are not very good at detecting and informing of connectivity errors. That's not their job. Most connectivity errors still comply with basic Verilog rules. Order of evaluation of certain constructs also plays a part. Synthesis tools, on the other hand, are sensitive to connectivity errors; since thet have to map and route signals. Therefore, they usely feature more extensive syntax checks. They also may generate other warnings or errors during mapping and/or routing.

In this lesson we will study how to synthesize and debug our design with various different vendor's tools.

For demonstration purposes, I have chosen to use the latest free versions of ISE from Xilinx and Quartus from Altera. To follow along, I suggest that you download and install these software packages now.

License Terms  

The source and/or object code (subsequently referred to as code) presented in this and subsequent lessons is the property of and owner who retains copyright protection. This code in whole or in part is licensed only for single copy per user, non-commercial use; except in the case of educational institutions, where a license of single copy per student, only as part of course curricula, is permitted.

Donald Gerard Polak (owner)

Starting an ISE Project  

Let's start by debugging our project using the Xilinx ISE tool. We will use a low cost device, the Spartan 3, XC3S200AN, in a FBGA, 256-pin package that will fit in the width profile of the original 40-pin DIP package; i.e. it can be placed on an adapter assembly to build a drop-in replacement.

We start by launching the ISE tool. If there is no current project, you can just select the "New Project" button. Otherewise select the "File" pulldown menu on the top bar and then select "New Project" from the pull down list.

When the new project dialog box opens, assign a name to your project. This is usually the top level module name, so we enter s8085d_r. When you are using ISE, there are no particular restrictions on the project name, but many other synthesizers require the project name to match the name of the top level module. Get into the habit of naming your projects after the name of the top level module to avoid future issues. You will notice that as you fill in the project name, it is automatically appended to the location and working directory names. This is an effect particular to ISE, and some designers prefer it that way. However, if you let ISE create these new directories, it will impede updating the original source and re-synthesizing. I usually go to the location and working directory names and removing the concatenated project name.

ISE New Project Dialog

You may also write a comment about you IP in this window. When you are finished, click the next button to proceed to the assignment dialog.

The assignment dialog allows you to set the target device, simulation tool, language, and cerain other values. We are not using an evaluation board, so we set that value to "None". To get to the Spartan3AN family you can either set the "Product Category" to "All" or "General Purpose". Set the device family to "Spartan3A and Spartan3AN". Now set the device to "XC3S200AN". This device is only currently available in the FTG256 package, so it should default. We wnat to select the fastest speed grade, "-4".

There is only one synthesis option, "XST (VHDL/Verilog)" so you don't have to worry about it. I also let the simulator default, but if you wish to use it, set this value to "ModelSIM-SE Verilog". Obviously you need to set the preferred language to "Verilog". Property specification may be defaulted to "Store All Values". We want "Manual Compile Order" and "Message Filtering" turned off.

The current ANSI VHDL standard is VHDL-93 so, therefore, this is what we have selected for the VHDL analysis standard. For this project this value is meaningless, so you can just choose the default.

ISE Assignment Dialog

Once you have completed making your assignments, click the "NEXT" button. a project summary box will then appear. If you are satisfied with the summary, click the "FINISH" button to create your project.

Adding Source Files  

Before we add our source to the project, we want to enter a line into it so it will automatically load our definitions file. Although ISE can process the definitions separately, some synthesis tools will not process files that do not contain any RTL code.

We need to enter the following line into our source file, prior to the first module declaration :

`include "s8085d_d.v"

Now that we have our source code ready, we need to include it in our project. To add files to a design, you may click on the design tab in the lower portion of the left hand window and the click on the second icon from the top in the sidebar tools.

ISE Add File to Design

As an alternative, you may select the "Project" pull down menu on the rop menu bar, and then selct "Add Source" from the menu options.

Either method opens a standard window "Open File" browser dialog. Using the file browser, selct the directory wher you placed your files, and then add your source file to the design. For our first synthesis, we are nor adding any constraints, so this is the only file you need to add at this point.

Setting ISE Synthesis Options  

Before we can begin synthesis, we need to set certain ISE options. Because we are using coded fields and direct output signals in our state machines, we need to set FSM encoding to "User". ISE also has a tendantcy to build mux trees out of certain Verilog constructs, so I generally turn off automatic mux extraction.

On the left hand menu. right click over "Synthesis - XST". When the pull down menu appears, select "Process Properties". The synthesis options dialog will appear with "Synthesis Options" selected. Set "-opt mode" to "Speed$quot; and "-opt level" to "High". To assist in debug, we want to set the "-keep hierarchy" option to "Yes". You may let all the other options default.

We now select the "HDL Options" category from the option menu on the left hand side. We set the "-fsm_extract, -fsm_encoding" property to "User" and the "-safe_implementation" style to "No". The "-vldcase" option should be "Full - Parallel" and both "-mux_extract" and "-decoder_extract" set to "No". All other properties may be defaulted.

To prevent certain untraceable errors, we must also go to the "Xillinx Specific Options" and disable equivalent register removal. Once you have set the process properties properly, click on "OK" to update the values and close the dialog.

ISE HDL Options
ISE Synthesis  

Now we can run our first synthesis and start removing synthesizer errors. First we select the "Project" pull down menu on the top bar. From the pull down menu select "Design Summary/Reports". Now we cursor over "Synthesize - XST" on the left hand menu, and double click.

Oh oh, we have some errors, Who would have guessed that we would have synthesis errors in 13,000 lines of code? Anyhow, let's look at them.

ISE has several methods to view these errors. You may scroll the console window at the bottom of your screen and look for them. This method is handy when you are trying to locate the particular module where the error occurred. You may also click on the "Errors" tab at the bottom of the left hand window. There are also two separate links in the design summary report window to look at these errors. If you require the full information concerning the error you can look at the synthesis report under "Detailed Reports". You should try every method so you are familiar with them.

When we look at the errors using the "Errors" tab from the bottom of the left hand menu; and view the following:

ISE First Synthesis Errors

We can see a couple of signals that don't appear in the module declarations. We must first examine the module itself, to see if we are still using that signal in the module. If we aren't then remove that signal from the input or output signal list and make sure that no module instantiations include it in their instantiation signal list. If we are, then we need to add it to the module declaration, and make sure that it also connected in any module instantiations.

On line 3346, "addend1" is an artifact of the movement of that signal to "source_sel_r" in module 3, lesson 1. We simply want to remove that signal from the output declarations in "dest_sel_r".

We see something similar going on with the "sel_inc" signal on line 6130 in "sequencer_r". Signal development was moved to "inc_log_r" in module 2, lesson 2, bit, again, we left an artifact. Just as in the former case, we want to remove it from the output declarations.

When we make these corrections and rerun synthesis, we get the following errors and warnings:

ISE Second Pass Synthesis Warnings

When we start analyzing at these errors and warnings, we see that we have intp in the output list in "aequencer_r". Even though it is not tied to any output logic, the synthesizer will tie it to ground and drive it as an output anyway. Therefore we need to transfer it to the input list and remove the "wire" declaration for "intp" in "sequencer_r".

We also observe that we accidently duplicated the mux for temp upper source in the lower source mux portion of "source_sel_r". We have to remove this extra occurrence.

There were some duplicated case statements in the microcode state machine. These extra cases also have to be removed.

"int_trap" appears as an input to module "int_xlat_r", but is not needed, since this is the default vector. It can be removed from this module port list, input list, and the module instantiation.

We see that "add_of" is missing from the carry calculations in "flag_logic_r". We need "add_of" to calculate the carry for sixteen-bit add and subtract operations. "sel16" is used to choose between "add_cy" and "add_of" for carry calculations.

We brought all eight of the current flags into "alu_r" and "flag_logic_r". However, we are only using the auxiliary carry flag, the carry flag, and the negative operation flag. All the rest are left dangling. Therefore we need to only bring in the flags taht we are actuallly using. This involve creating additional input signal names to attach the flags, and changing the module port lists, the module input lists, and the module instantiations for all affected modules.

In this fix, remember to apply the conditional compiles to the negative operation flag, because it is only used for the S8085C and S8085D models.

This same scenario is present in "sequencer_r" and "flags_r". The "pmatch" signal equations use all flags, except the auxiliary carry and negative operation flags. In addition, we did not use the flag position parameters to denote the flags we do use. This is poor coding practice. Therefore, we just create new signal names and bring in only the flags we do use and rewite the equations appropriately.

The signal "multplicand" was a spelling error. The remainder of the connectivity warnings were artifacts of earlier architectures. Once we correct these warnings, we are left with the following source code:

Updated project source file.

Now, when we rerun the synthesis, we get the following warnings:

ISE New Synthesis Warnings

Although these are warnings, they concern combinatorial loops. Combinatorial loops discovered during synthesis are particularly bad. Although ISE could potentially handle these loops correctly, The routing of these loops could cause unacceptable delays in all other logic, logical errors, and/or propagation glitches. They must be eliminated.

Eliminating Combinatorial Loops  

We can see from these warnings that the sources of these loops originate for modules "serial_r" and "dest_sel_r"; but not much else. We also need to look at the signals involved. On the center pane of the ISE screen look for the box next to "Detailed Reports" and click on it until the minus sign ('-') appears in the box. You should now see "Synthesis Report" appear as one of the options under "Detailed Reports". When you click on this option you will see the full text of the synthesis report.

Scroll through the report until you see the warnings. They will have a highlighted hyperlink, so they are easely visible. Do not click on the hyperlink, as it will only give you a generic explanation of the error. Instead, scroll horizontally to the signal list. I generally copy the signal list into a word processor (jEdit) and break the signal list apart so there is one signal per line. Do this with all the warnings. When we follow these instructions we get the following:

Combinatorial loop signals.

In the first loop we see "swint" appear several times. We also see the interrupt vector signals appear. Both originate from a direct decode of the instruction latch. ThHe instruction latch is a transparent latch, and the source is the destination bus. the results of the decode feed the destination bus, hence a combinatorial loop. To fix this issue we can source the instruction latch directly from the address/data pins. This fix has the added advantage of faster instruction decodes.

In the second loop we see several signals associated with the adder, the incrementer and "res_dest" which is only used in flag generation. This indicates that there is an issue with the flags. When we start digging deeper, we find that there are also issues with the flags from the "DSUB" instruction and the carry from the logical instructions and the "DADx" instructions.

Part of the problem is the flag load enable. Currently this signal loads the flags from the destination bus. However, the flags also are used to create signals on the destination bus. There is also minimum justification for using a separate "res_dest" bus to generate flags. The suspect flags are carry, auxiliary carry, and unsigned indicator.

We address these issues by adding a separate mux to handle flag load enable. This mux is fed from the modified flags and the address/data bus. We also update the flag mask generation logic, replace the "res_dest" bus with the "dest" bus, add auxiliary carry generation to the logical block, and fix the adder and incrementer blocks to generate carry, overflow, and unsigned indicator flags. We also update "flags_r" to fix the flag masks.

The third loop indicates the same issue that we saw in the first loop. We see "swino[1]" appear several times. Fixing the first loop should also fix this one

Once we have made the required changes we obtain the following code:

New project source file.

When we rerun the synthesis with this new code, we see that we have successfully eliminated all warnings and errors.

  1. What must we do to the FSM options? Why? How?

  2. Download ISE and create a project.

  3. How can you access the synthesis report?

  4. What problems can combinatorial loops cause?