The source and/or object code (subsequently referred to as code)
presented in this and subsequent lessons is the property of
saxelec.com 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)
Before we begin timing closure, there is one more issue that we need
to address. The signal "trap" is used both as a clock, and
in logic. Because there is only one register involved, it does meet
the minimum requirements of
rule 3.10. However,
the Xilinx Spartan 6 family will not support this type of construct at
The timing of "trap" is not specified, so a sampling
methodology is not guaranteed to work. The best way to address this
issue is to add another I/O pad to "trap" to support the
clock input. This "clk_trap" I/O pad is then connected
externally to the "trap" I/O pad. That leaves us with the
following HDL source code:
Project Source File with a Separate "clk_trap" Input.
The Xilinx constraints editor requires a fully placed and routed
design. In the Xilinx directory that you created, replace the
current source code with the new code we just developed and
launch ISE. In the lower portion of the left hand window, double click
"Implement Design" and let it run to completion.
Although we still have no synthesis warnings, we do have warnings
from the translate, map, and place and route processes. Let us
examine them and remove as many as possible.
When we look at the translate warnings:
ISE Translate Process Warnings
we can see that they originate from signals that we always force
to zero. We can easily remove the upper 8 bits of
"multiplicand", since the source mux will automatically
force those bits to zero. The carry in for the divider and
adder, the LSb of "daaval" and three of the interrupt
vector bits re a different story. Obviously, the interrupt vector
bits and "daaval" could be addressed in the source mux and
the least significant nibble of the adder changed to eliminate this
warning. But that comes at the cost of added complexity in our
design, making it more difficult to debug and support. Instead, we
will use the one's complement of rst_in_n to drive these bits.
The map warnings:
ISE Map Process Warnings
are a bit more difficult to address. Some of them can be removed
by eliminating the "keep hierarchy" option and allowing
optimization across hierarchal boundaries. This means, however,
subsequent warnings will be more difficult to track down. The issue
involving "clk_x1" is more problematic. Although many
FPGA architectures support inverted clocks directly in their logic,
some, including the Spartan 3A series, do not. In the Spartan 3A
series, clock invert is a function of the digital clock manager
Rather than creating a special case for a single vendor's particular
device family, we devised a conditional compile, whereby we attach
an extra I/O pad to the clk_x1 input to support logic, in this
case a simple inverter. This new I/O pad MUST be connected externally
to the clk_x1 input. The output of this inverter feeds
"x2_pad". For best results, do not use internal pullups
for either "x1" or "clk_x1" so you can adjust
your Pierce oscillator with external component values.
The issue with "restart_7_5" was actually an error. The
"SIM" instruction should report pending interrupts, which,
in the case of restart 7.5 should be the latched state (r7_5_latched),
rather than the state of the input pin.
Many of our other warnings may be eliminated by correcting these
errors and changing our synthesis options. However, there is
another alteration we need to make. Many modern FPGAs feature
block RAM, and even those that don't can emulate block RAM with
just a four logic element delay (with a properly constructed
mux tree). The problem lies with the synthesis software being
able to detect constructs that should be placed into block RAM.
ISE does not detect a block ROM that can be placed into a block
entity if it is too small. This could cause sub-optimal timing
and many logic delays. To avoid this issue, we filled in our
"fmask" table with all possible instruction values. That
leaves us with the following source code:
Project Source File with ISE Translate, Map, Place, and Route
Of course, we need to alter our definitions file to take advantage
of our "clk_x1" correction:
Definitions File to Take Advantage of clk_x1 Correction
We go into our synthesis process properties and set
"-keep_hierarchy" to "No". We also open the
Xilinx specific options and check both
"-equivalent_register_removal". Under the Map Process
Properties, check "-ignore_keep_hierarchy". I also set
"-ol" to "High" and "-cm" to
Now when we rerun "Implement Design" we see that all
warnings have been eliminated.
Applying ISE Constraints
There are several ways to apply constraints to your project when using
the Xilinx "ISE" tool. The first method, called
"XST", allows you to apply certain Xilinx constraints
directly to your HDL code or in an external "XCF" file.
These are primarily synthesis options and location constraints. These
constraints are applied to your HDL source code by the inclusion of
specially formatted notes, macros, or metas. Using these constraints
violates rule 3.8 and are not
reusable. Using an external XCF file is permissible, but we don't
necessarily need it.
We will be using the constraints editor to develop a user constraints
file (UCF) to include in our project. Initially we just want to
set a period for our three clock domains.
The constraints editor is launched by selecting "Constraints
Editor" under the "Tools" pull down menu. You will be
asked if you want to create and add a user constraints file to your
ISE Add UCF Warning
Allow the editor to allow the constraints file to your
project and set the name to "s8085d_r.ucf". The editor
will open to "Timing Constraints" with "Clock
ISE Clock Domain Constraints
We click in the blank row below the "Clock Net *" column
title and get a down arrow. Click on the down arrow to get the clock
net name pull down list. Select "clk_x1" from the list. We
now set the clock period. To meet our requirements, the minimum period
specification is 31.25 ns. I generally go much higher to ensure that
we have plenty of margin. I click in the "Period" column
and get another pull down menu that defaults to nanoseconds, and a
period specification that defaults to 0.0. I set this specification
to 25 nanoseconds (40 MHz) for our initial attempt. We now MUST
set a timespec name. This name MUST meet certain guidelines.
We will use "TS_clk_x1" for the timespec name in order
to meet these requirements.
ISE requires that you validate constraints after each entry. Before we
proceed, we click on the "Validate Constraints" button. This
will fill in the status, duty cycle, and edge fields and remove
clk_x1 from the unconstrained clocks list.
ISE clk_x1 Constraints
It is not really necessary to constrain clk_trap or restart_7_5,
however, we will do it anyway to avoid any warnings. I will set
the period on these clocks to 10ns. When we are complete, we select
"Save" under the "File" pull down menu.
We close the constraints window and rerun "Implement
Design". There are no warnings reported, so we check the
"Timing Constraints" report:
ISE Timing Constraints Report
We see that our design meets our timing requirements for a
40MHz clk_x1. This is more than our initial requirements, so this
is considered a good design for ISE.
Meeting Timing with Quartus
Before we begin setting constraints in Quartus, we want to perform a
full compile with our latest source code. Copy the latest source code
into your Quartus directory and launch Quartus. Then open your
After a successful synthesis has been run, Quartus will not
automatically rerun synthesis, even if the source code has changed.
Before you can compile the design, you must rerun the synthesis
process and stop it before completion. Right click on
"Analysis and Synthesis" and select "Start Again"
from the pull down menu. You will get a warning window explaining
that synthesis was already successfully run. Click the
"Yes" button and allow the process to start. Then click
the "Stop" icon on the top tool bar.
Now we can do the full compile. Double click the arrow next
to "Compile Design" and let the process run to
completion. The only warnings we get will come from the
"Timequest Timing Analyzer". This is because we have
not set our clock constraints, and they defaulted to 100 MHz.
Setting Quartus Constraints
Quartus expects its constraints in a specially formatted file,
usually created by the Synopsis "Symplify" tool. This
constraints file, in "sdc" format, may also be created by
any text editor. At first we only wish to constrain clk_x1, as this
is the only signal where we have a firm specification. Therefore,
we develop the following file:
Before we compile, we have one more correction to do. We cannot
ensure the timing of interrupts in relation to "clk_x1".
"restart_7_5" and "clk_trap" in particular
violate Rule 2.7.
Therefore, we need to resynchronize all interrupts to
"clk_x1" before using them:
Project source file with Interrupt Resynchronization.
We now need to add our constraints file to our project. Under the
"Project" pull down menu, select "Add/Remove Files
In Project". When the "add files" window:
Quartus Add Files Dialog
appears, click on the "..." button next to the
"File Name" entry block to bring up the file browser.
Select "Text Files" from the pull down list in the file
browser. Then locate and select your SDC file and click the
"Open" button. When the file browser window closes, click on
"Add" and the "OK". The constraints file is
now part of your project.
Compile and Check Your "Quartus" Project
We now compile our project with the constraints added. When the
compile is complete, we see the "TimeQuest Timing" folder
highlighted in red. When we open the folder, we see that the only
report highlighted in red is the "Unconstrained Paths".
This indicates that we are meeting timing. We can look under
the "Slow 100 mV 85C" folder at "FMAX" and see
that we are good out to about 43 MHz.
Of course, we still have to check our new source code with ISE,
because our interrupt synchronization changes. When we don that, we
see that our project meets timing requirements in both the
Xilinx Spartan 3A family and the Altera Cyclone IV E family devices.
So we now have a 20 MHz, enhanced, re-targetable 8085A
microprocessor intellectual property that will fit into FPGAs, but is
still a little too large to fit into Altera CPLDs.
Retarget your device for a Xilinx Spartan 6 device. Did you get
any errors? Did your project meet timing? What kind of warnings
did you get?
Why do we need to resynchronize interrupts?
What did we do to the "trap" input? Why?
Why don't we use XST constraints?
How do we add clock constraints for Xilinx? For Altera?
Can you use both clock edges in any FPGA architecture? If not,
how can we get around this?