Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
12 years ago

Is there a performance difference between variables vs direct assignments

Several years ago I wrote a small (I thought) 8-bit micro-controller core called the Open8. The current model is based very closely on the old Arc-lite/V8 instruction set, though I've modified a few instructions to be more useful. It's been a handy micro for doing packet generation, programmable state machines, etc. However, the fMax of designs using it has always been low in the target devices (usually a Cyclone III)

I observed that most of the timing issues were related to the ALU, specifically where the instruction decoder was setting up the ALU, so I set about to pipeline that code a bit more heavily. In the process, I moved from a two-process model, where the combinatorial logic was in a separate process, to a one-process model. For most designs, this seemed to perk up the synthesis results nicely, and I did get a nice speed boost, but I'm wondering if I have created a new limitation in the process.

To avoid redesigning everything from scratch, I opted to use variables where I had previously used signals between two separate processes. So, for example, instead of using Cache_Ctrl <= CACHE_PREFETCH; in the separate combinatorial process, I used Cache_Ctrl := CACHE_PREFETCH in the single clocked process. As an aside, I initialize all variables to their most common value at the top of the code, and modify it as needed in each state. Below the FSM code is the code that manages these subsystems. This works fine, and the processor core is running in hardware.

To be clear, this is what I am doing:


  CPU_Proc: process( Clock, Reset )
    variable IC              : CACHE_MODES;
...
  begin
    if( Reset = Reset_Level )then
...
    elsif( rising_edge(Clock) )then
      IC                     := CACHE_IDLE;
...
      case( CPU.State )is
... (snippet from within primary FSM)
-------------------------------------------------------------------------------
-- Program Control (BR0_C1, BR1_C1, DBNZ_C1, JMP )
-------------------------------------------------------------------------------
        when BRN_C1 =>
          if( CPU.Flags(Reg) = CPU.Opcode(0) )then
            IC               := CACHE_IDLE;
            PC.Offset        := CPU.Operand1;
            CPU.State        <= PIPE_FILL_0;
          else
            IC               := CACHE_INSTR;
            CPU.State        <= INSTR_DECODE;
          end if;
...
-------------------------------------------------------------------------------
-- Instruction/Operand caching for pipelined memory access
-------------------------------------------------------------------------------
      case IC is
        when CACHE_INSTR =>
          CPU.Opcode         <= Rd_Data(7 downto 3);
          CPU.SubOp_p0       <= Rd_Data(2 downto 0);
          CPU.SubOp_p1       <= Rd_Data(2 downto 0) + 1;
          if( CPU.Cache_Valid = '1' )then
            CPU.Opcode       <= CPU.Prefetch(7 downto 3);
            CPU.SubOp_p0     <= CPU.Prefetch(2 downto 0);
            CPU.SubOp_p1     <= CPU.Prefetch(2 downto 0) + 1;
            CPU.Cache_Valid  <= '0';
          end if;
        when CACHE_OPER1 =>
          CPU.Operand1       <= Rd_Data;
        when CACHE_OPER2 =>
          CPU.Operand2       <= Rd_Data;
        when CACHE_PREFETCH =>
          CPU.Prefetch       <= Rd_Data;
          CPU.Cache_Valid    <= '1';
        when CACHE_INVALIDATE =>
          CPU.Cache_Valid    <= '0';
        when CACHE_IDLE =>
          null;
      end case;
...
  end if;
end process;

I'm just not clear on whether or not this coding style may be causing synthesis issues.

Thanks for any advice!

-Seth

13 Replies