Saturday, December 31, 2011

Rant about SystemVerilog

Why does SystemVerilog need so many constructs? There is too much overlap.

An interface could almost be a module if you don't need any module instantiations inside. A task or function can exist in classes, interfaces, or modules. Which should they exist in? Call a task from a module or use an interface to control the IOs of the interface? Output an inherited class from the module and call the class' tasks? Use a typed or untyped mailbox? How about using nested classes? Should they be nested or just in a hidden package? Classes in packages or classes at the top-level with include files? What sounds right to you?

Friday, October 14, 2011

Remote desktop & tscon

tscon is the most useful little command that I only recently learned about. It allows you to switch a remote desktop session back to the local console.

I use this to log onto my compute remotely and then switch it back to console when I'm done.

I also used this to get around a FlexLM requirement that wouldn't let me open an application while I was logged on remotely. I wrote a short script that switched back to console and then opened the application. Once I logged back on remotely, the application was open.

anyhow use this:
tscon rdp-tcp#0 /dest:console

If this doesn't work, use:
query session
and then use the rdp session as listed there.

This will switch the desktop back to the console.

Wednesday, August 31, 2011

Actel and Libero IDE

I have been using the SmartFusion FPGA for a while now. The advantage is a built-in Cortex M3. the disadvantage is Actel and their tools.

Actel has violated a rule in design. They over-engineered Libero IDE. Libero attempts to automate constraints. Here-in lies one class of problems.

Libero determines all of your clock constraints from the MSS setup. Those constraints are then hard wired into the Designer project. There is no pdc file to edit for the clock constraints. These constraints can't be edited using Designer's constraint editor because the automatic constraints are read-only.

Why is this bad?

Libero has a bug where it sets the constraint incorrectly if you set the divider of GLx to a non power of 2. Divide GLA by 3 and the constraint is set as if it was divided by 2.

In general, over-engineering complicates both users' and developers' lives. I am referring to customers as the users and the Actel employed programmers as the developers. Over engineering creates for confusion as nothing is intuitive anymore. It also opens the door to many more bugs.

Xilinx is an example of a high quality company that doesn't over-engineer (from what I recall). Their tools are not great, but they leave all of the configuration in your hands. Even if they tried to automate something, they still let you override whatever it is.

Another frustrating problem is how Libero splits constraints into 2 places. I recently configured an MSS I/O to route to the FPGA. I did this because I needed Schmitt Triggers. What is overly confusing is how the default constraints file located under component/work//.pdc is no longer the file for these constraints. What is even more strange is that if you edit that pdc file in the I/O Attribute Editor, you see the MSS I/Os and they offer to enable Schmitt Triggers. Why is that bad? Because they don't work! The moment you attempt to compile in Designer, you get a strange error message telling you how you can't modify these IO settings!

The solution? Under the MSS configurator there is a middle tab for I/O Attributes. Use that tab. That's not all folks! Now you must add a new pdc file to the Designer project. I imagine that if you hit the Designer button in Libero it will add the new pdc file to the Designer project, but as I rarely hit that button, b/c Designer is already open, I can't say whether this is true. But not only must you add this file, you must also remove any reference to the incorrectly placed constraints from the original pdc file. The MSS I/Os must only appear under the MSS pdc file.

Folks at Actel seem to have forgotten what simple and intuitive means. They should refresh their memory.

Tuesday, June 14, 2011

More on metastability

I spoke with the layout guy today, and I've once again had to re-evaluate my understanding. Seems like gates don't propagate metastability. Since gates are railed to VCC and GND, and they don't have internal feedback like flip-flops, metastability is unlikely to propagate through them. This includes regular gates, and buffers, and I'm sure other stuff too.

This means that metastable oscillation is pretty unlikely. Unless of course the output of one flip flop is tied back to its input without going through buffers, or gates.

I guess the only likely issue with metastable flops is the uncertainty of the output. Oh well. I'd still be careful.

Sunday, June 12, 2011

Metastability - what logic and research has led me to believe

A long time ago I began learning about hardware design. This was at a time when I was primarily doing software development. Without formal training, I was relying on the explanations of others, logic, and experimentation. It has been years, and I've advanced quite a ways.

When I started designing, the ideas of synchronization were explained to me. Always double or triple sample signals from external sources, or from other clock domains. As it was explained to me, each flop reduced the chances of metastability by a very large factor. 2 samples were considered enough to lower the chances of metastaibility to almost nothing. 3 flops were even better.

As I got more experience, I got used to only using 2 flops to move between clock domains, or to bring an external signal in. But what was really going on?

There are 2 reasons for synchronization flops.

1. Metastable oscillation. This requires an explanation of metastability.

Metastability is a state whereby a flip-flop will sample an input signal on a clock edge, but the input signal is in a state of transition. This is a common situation when sampling from another clock domain or from an external signal. When a flip-flop samples an input signal that is not stable high or stable low, the flip-flop's output is undefined. Suffice it to say that an undefined output means that the output does not rise or fall as would be expected. The output wavers and takes a while to settle in one state or another.

A metastable flop will settle after a while. The assumed time it takes for a metastable flop to settle is a complete clock period. While a flop-flop is metastable, any flop sampling the metastable flop's output could also go metastable.

A second synchronization flop guarantees a full clock period of time for the output of the first metastable synchronization flop to settle and arrive at the second synchronization flop. As a rule of synchronization, there can be no combinatorial logic between the first and second flops.

Metastable oscillations can occur if there is a path whereby metastability can loop around. This can occur with a single flop, or with a sequence of flops. The simplest example of metastable oscillation can be with one flop. A single flop whose input comes from a mux that has a select signal to choose between an external signal and the flop's own output is prone to metastable oscillation. The flop can be used to sample an input signal, and then hold that value using the select of the input mux. But since the output of this flop is driven back to it's input using a mux, there may not be enough time for the output to settle before it is sampled back into itself.

2. Indeterminate input. When an output from another clock domain or an external signal is input into multiple flops at the same time, there is no guarantee that each flop will settle with the same input value. There are also the risks of metastability propagating through the sampling flops.

Wednesday, June 1, 2011

Can you guess why multicycle constraints are problematic?

As I have been suffering with synthesis tools that don't analyze clock domains during synthesis, I realized a new aspect to this problem. Have you ever designed a module that uses a multicycle path? Well it can cause you real headaches if you're not careful. Imagine this code:

entity demo_module is
port (
clk : in std_logic;
rstn : in std_logic;

sel : in std_logic;
inputa : in std_logic_vector(7 downto 0);
inputb : in std_logic_vector(7 downto 0);
output : out std_logic_vector(7 downto 0)
end entity;

architecture rtl of demo_module is
signal sel_input : std_logic_vector(7 downto 0);
signal input_d : std_logic_vector(7 downto 0);
process(sel, inputa, inputb)
if(sel = '0') then
sel_input <= inputa;
sel_input <= inputb;
end if;
end process;

process(clk, rstn)
if(rstn = '0') then
input_d <= (others => '0');
output <= (others => '0');
elsif(clk'event and clk = '1') then
input_d <= sel_input;
output <= sel_input xor input_d;
end if;
end process;
end rtl;

I'm doing nothing complex here. Using sel to select which of the inputs I'm gonna sample and then output the xor of.

Now let's say that it takes 2 cycles to change inputa or inputb, and I make sure that sel only switches every other cycle. This should be valid. Here's where the problem with synthesis tools come in to play. Synthesis tools can use any method they choose for implementing the sel mux. They do not have to use an actual mux. This could be done using a combination of gates / complex gates. What this means is that even when sel is stable on inputa, a change on inputb can cause a glitch (and vice versa). This is unimportant when inputa and inputb are guaranteed to change within a clock, but this is of vital importance when you want to use a multicycle constraint. The fact that inputa and inputb take more than one cycle to change means that at the clock edge when sel doesn't change (and sel is STABLE), inputa / inputb can be changing and thereby cause a glitch on the output of the muxing process (when done without a mux). This will then create an incorrect read of input_d (the sampled value).


Thursday, May 26, 2011

Another metastability mistake

So I was analyzing my design today and I happened upon another metastability mistake. I built this circuit:
I wanted to synchronize an external signal, but only when enabled. There was a good reason to do this, but I didn't want to risk metastability. I figured that the second flop solved the issue. What I didn't take into account was the feedback path of the first flop when the enable was low. It was theoretically possible that the first flop would oscillate metastable, even if only for l additional clock. Under most conditions you would assume that a single mux would be minor when compared to the full period of the clock and therefore it wouldn't be a problem. But it's not just an additional mux, it is also two wire paths instead of 1. That means that layout tools with a max wire path distance would now be doubled as there is a path from the q to the mux input, and from the mux output to the d. A nice solution was replacing the mux and enable with a clock gate enabled by the enable. At least this way you don't have to worry about the feedback path.
Be sure to balance the clocks!

Tuesday, May 24, 2011

The dangers of asynchronous design...

I have been pushing my own limits in some of my most recent designs. I have been synchronizing less, and I have been building delay dependent logic. This is interesting and challenging at the same time. Building logic that is low-power, efficient, and high speed is not so simple. Here is an example of mistake I caught myself making:

The second ff was gonna be metastable. And the output from the second ff was gonna be synchronized externally. I didn't care what value the second ff got, just that the third ff and the external synchronization flops  would get the same value. What I had forgotten to take into account was how metastability works. I forgot that the second ff can go high during metastability even though it may start and settle low.

 Luckily I caught this soon after I wrote it.

Friday, March 4, 2011

Clock tree synthesis (CTS): ASIC/ASSP vs. FPGA

First time learning experience for me.

Muxing clocks is nothing new to me, I've done this many times. But until now, I've never had to keep both sides synchronous with each other.

process(clkA, clkB, clkSel)
 clkAB <= clkA;
 if(clkSel = '1') then
  clkAB <= clkB;
 end if;
end process;

 if(clkA'event and clkA = '1') then
  ffA <= sig_tmpA;
 end if;
end process;

 if(clkB'event and clkB = '1') then
  ffB <= sig_tmpB;
 end if;
end process;

 if(clkAB'event and clkAB = '1') then
   ffAB <= ffA;
  end if;
   ffAB <= ffB;
  end if;
 end if;
end process;

Here's the problem. I want ffAB to be set to the value of ffA when grabA is true and I want ffAB to be set to the value of ffB when grabB is true. This requires having clkAB in phase with clkA when clkSel is 0 and having clkAB in phase with clkB when clkSel is 1. The problem is clock skew. Basically the clkAB clock becomes a delayed version of the source clock. This means that the flip-flops before the clock will change before the flip-flop after the clock mux is able to sample the value. This is a standard hold-time problem. For an ASIC/ASSP, the solution is implemented by the synthesis tools. It is pretty automatic from what I've been led to believe. Perhaps some constraints or switches are required, but in general, if the two clocks are related then the tools will balance the clock trees to make sure of setup and hold times.

On the other hand, an FPGA doesn't work this way. Clocks are routed on a clock network. Creating a clock mux of this sort adds a serious skew to the timing. As I am currently using Actel tools, I am very aware of the lack of any CTS done by the synthesis or place & route tools.

The key to solving these issues (other than manual regioning of individual flip-flops) is to carry the data over the delayed clock boundary by using buffers. BUFD is Actel's buffer primitive, and by using buffers on the data line you can eat from the setup-time and give to your hold-time. Basically take the output of ffA/ffB and add buffers between their Qs and the D of ffAB.

Voila, you have solved the hold time issue.

Another option is to create a copy of clkA and clkB, and delay those copies using a buffer. Then use these copies in your original clkA and clkB processes. This would create a smaller skew. The problem with this mechanism is that you may also want to sample data back from clkAB to clkA/clkB. If you play with the clock only, then it will be difficult to solve the hold problems in both directions. As soon as you solve it in one direction, you most likely will have created it in the other direction.

A good solution would use a combination of shifting the clock a bit, and using buffers to cover any remaining skew. Whatever solution you choose to implement should be done in direct conjunction with the timing analyzer tools. Those tools are your best way of knowing where and when you have setup or hold problems on your system.

Thursday, February 3, 2011

gvim 7.3 64-bit (x64) Windows 7, Vista, XP - w/ silent install & uninstall

This is an update to:

I have been asked over facebook to build gvim 7.3 with silent install and uninstall options. I have modified gvim.nsi to do that. The changes to gvim.nsi are below.

You can download the actual installer with silent support from:
Silent installs with all of the defaults.


"This will install Vim ${VER_MAJOR}.${VER_MINOR} on your computer.$\n Continue?" \
Goto NoAbort
Abort ; causes installer to quit.


"The installation process has been successful. Happy Vimming! \
$\n$\n Do you want to see the README file now?" /SD IDNO IDYES YesReadme
Goto NoReadme
Exec '$0\gvim.exe -R "$0\README.txt"'


"Vim ${VER_MAJOR}.${VER_MINOR} has been (partly) removed from your system" /SD IDOK


"Would you like to delete $0?$\n \
$\nIt contains the Vim executables and runtime files." /SD IDNO IDYES YesRemoveExes
Goto NoRemoveExes
Delete /REBOOTOK $0\*.dll


"Remove all files in your $1\vimfiles directory?$\n \
$\nCAREFUL: If you have created something there that you want to keep, click No" /SD IDNO IDYES NoFin
Goto Fin
RMDir /r $1\vimfiles


"Would you like to remove $0?$\n \
$\nIt contains your Vim configuration files!" /SD IDNO IDYES YesDelete
Goto NoDelete
RMDir /r $0 ; skipped if no