Sequential Logic Synthesis (part II)


Index

o Review
o Vars vs. signals
o Async. vs. synchronous processes
o FF and latch inference restrictions
o FSM synthesis
o Data-dependent vs. computable loops
o Resource allocation and register sharing
o To probe further

Review

o Variables
o Only used in processes and subprograms
o ASssigned values immediately (signals are scheduled)
o Can be avoided but simulate faster
o Example (with variable update):
signal data: Bit_vector (0 to 7);
parity_in, parity_out: Bit;
process
    variable : Bit;
begin
tmp:= `0'; -- 0 xor a = a
for i in 0 to 7 loop
    tmp:= tmp xor data(i);
end loop;
parity_out <= (tmp = parity_in);
end process;
o The same example (using signals - one assignment):
signal data: Bit_vector (0 to 7);
parity_in, parity_out: Bit;
signal tmp: Bit_vector (0 to 7);
process
begin
tmp(0) <= `0';
for i in 0 to 6 loop -- why not 7?
    tmp(i+1) <= tmp(i) xor data(i);
end loop;
parity_out <= (tmp(7) = parity_in);
end process;
o What is better style?

Inferring Synchronous Logic

o Why avoid explicit register instantiation
o (+ve) <edge> (clk is one bit encodable):
o clk'event and clk='1'
o not clk'stable and clk='1'
o Two forms (<edge> cannot be used as on operand):
o wait until <edge>;
o if <edge> ....
o Do not assign to/from clock signals!
o If more than one clocks, use different processes for each
o Signals stored in FFs:
o Signals driven by the process
o Variables that are read before they are set
o Implicit/explicit state vectors
entity countMod10 is
port (clear: in Bit;
      clk: in Bit;
      count: buffer Integer range 0 to 9); 
end countMod10;
      
architecture rtl of countMod10 is
begin
process
begin
        wait until (clk'event and clk='1');
        if (clear='1' or count >=9) then count<=0;
        else count <= count+1;
        end if;
end process;
end rtl;
o Why use buffer
o What if wait <edge> is missing?

Review of FF inference

o Basic_DFF:
process (clk,data)
begin
   if (clk'event and clk='1') then
      q<=data;
   end if;
end process;
o DFF with asynchronous reset (only one in a process):
prosess(clk,reset_low,sync_data)
begin
   if reset_low='0' then
        q<='0';
   elsif (clk'event and clk='1') then
        q<=sync_data;
   end if;
end process;
o DFF with synchronous reset:
process (reset_low,clk,sync_data)
begin
    if (clk'event and clk='1') then
          if reset_low='0' then
               q<='0';
          else q<=sync_data;
          end if;
     end if;
  end process;
o In general, if <edge> more flexible than wait <edge> but more dangerous:
o Do NOT use more than one if <edge> expressions in a process
o BUT you can use many wait on the same <edge>
o Do NOT assign a value to a variable/signal on a FALSE branch of an if <edge> expression

Data dependencies in Sequential processes

process (clk,reset)
begin
    if (reset='0') then
       rega <= "0000";
       regb <= "0000";
       regc <= "0000";
    elsif (clk'event and clk='1') then
       rega <= data;
       regb <= rega + "0001";
       regc <= regb + "0001";
    end if;
end process;

Signals are ``updated'' once at the end of process body - the above VHDL fragment results in the pipeline:


FSM synthesis

o Use two processes to avoid registering output
o Experiment with other encodings (one-hot)
entity MEALY is            
port(X, CLOCK, RESET: in BIT;
       Z: out BIT);
end;
architecture BEHAVIOR of MEALY is
  type STATE_TYPE is (S0, S1, S2, S3);
  signal CURRENT_STATE, NEXT_STATE: STATE_TYPE;
  attribute STATE_VECTOR : STRING;
  attribute STATE_VECTOR of BEHAVIOR : architecture is "CURRENT_STATE";
begin
  COMBIN: process(CURRENT_STATE, X)
  begin
    case CURRENT_STATE is
      when S0 =>
        if X = '0' then
          Z <= '0';
          NEXT_STATE <= S0;
        else
          Z <= '1';
          NEXT_STATE <= S2;
        end if;
      when S1 =>
        if X = '0' then
          Z <= '0';
          NEXT_STATE <= S0;
        else
          Z <= '0';
          NEXT_STATE <= S2;
        end if;
      when S2 =>
        if X = '0' then
          Z <= '1';
          NEXT_STATE <= S2;
        else
          Z <= '0';
          NEXT_STATE <= S3;
        end if;
       when S3 =>
        if X = '0' then
          Z <= '0';
          NEXT_STATE <= S3;
        else
          Z <= '1';
          NEXT_STATE <= S1;
        end if;
    end case;
  end process;
 
  -- Process to hold synchronous elements (flip-flops)
  SYNCH: process(CLOCK, RESET)
  begin -- async. reset
    if (RESET = '0' ) then
      CURRENT_STATE <= S0;
    elsif (CLOCK'EVENT AND CLOCK = '1') then
      CURRENT_STATE <= NEXT_STATE;
    end if;
  end process;
end BEHAVIOR;

Data dependable loops

o Recursive Fibonacci:
fib 0 = 1
fib 1 = 1
fib (n+2) = fib (n+1) + fib (n)
o Tail recursive:
fib x = fib' (x,1,1)
fib' (x,y,z) 
  = if x=N then y else
    fib' (x+1,z,y+z)
o Iterative:
fib' (x,y,z:Integer) return Integer
 is  while (x<N) do
        {x <= x + 1;
         y <= z;
         z <= y + z
        };
     return y
o HW never stops!
Use completion signal (done) to signify when the result is valid. How do you ``start''?
o VHDL code
o all branches must be synchronized!
o initialization of registers to a known state before loop
o
o Use for .. loops for computable iteration
o Caution: synchronization is not allowed by Synopsys inside for loops.
(may lead to race conditions)
The fibonacci implementation

Resource allocation

o Use control flow to share operations:
if (cond='1') then
   Z <= A + B;
else
   Z <= A + C;
o Transformed to (one addition):
Z1 <=A;
if (cond='1') then
   Z2 <= B;
else
   Z2 <= C;
Z <= Z1 + Z2;
o Data flow conflicts cancel this transformation
o Avoid combinational feedback
o Registers whose lifetimes are distinct can be also shared.
o You can override automatic allocation
o Coding style implies structure:
z <= a + b + c + d;
z < (a + b) + (c + d);
o Can be overriden.

To probe further

o Transparent latches - two phase clock systems
Synopsys cannot borrow time (yet)
o Tristate logic inference (useful for Xilinx)
o Application note for Register balancing
o Conformance of simulation with synthesis results
o Different synthesis subsets (Cadence Synergy vs. Synopsys)
o Generally, only Synchronous logic is supported
o Clock gating is VERY dangerous - use EN
o Synthesized logic may have glitches
o Hold times cannot be guaranteed by routing
o Optimization and technology mapping



BACK TO THE TABLE OF CONTENTS



Last Modified: December 21/1995