VHDL coding tips and tricks: Can you change a signal at both positive and negative edges of the clock?
Contact me for VHDL or Verilog projects and assignments

Friday, March 5, 2010

Can you change a signal at both positive and negative edges of the clock?

Consider the following code:

signal c : std_logic_vector(3 downto 0):="0000";

process(clk)
begin
    c <= c +'1';
end process;

This code is supposed to work as a simple 4 bit counter, counting at both negative and positive edge of the clock.The design works perfectly in the simulation level. But when you synthesize this code you will get the following warnings :

WARNING:Xst:647 - Input clk is never used. This port will be preserved and left unconnected if it belongs to a top-level block or it belongs to a sub-block and the hierarchy of this sub-block is preserved.
WARNING:Xst:2170 - Unit test : the following signal(s) form a combinatorial loop: Madd_c4.
WARNING:Xst:2170 - Unit test : the following signal(s) form a combinatorial loop: Madd_c6.
WARNING:Xst:2170 - Unit test : the following signal(s) form a combinatorial loop: Madd_c_cy<0>.

Normally most of the warnings can be neglected during synthesis without posing any critical problems. But in this case "the input clk is never used" cannot be ignored. This warning tells us that the design will not work as we expect it to work. It is just a combinatorial circuit with feedback.

Now if you write the code in the following way then you will get a synthesis error.

process(clk)
begin
    if(rising_edge(clk)) then   -- for posedge
        c <= c +'1';
    end if;
    if(falling_edge(clk)) then  --for negedge
        c <= c +'1';
    end if;
end process;

"Signal c cannot be synthesized, bad synchronous description. The description style you are using to describe a synchronous element (register, memory, etc.) is not supported in the current software release."

This code clearly shows that it is not possible to change a signal at both negative and positive edge of the clock. Xilinx ISE either synthesizes it in a different way or it gives an error.

One reader asked in the comment section, why does the following code synthesis correctly?

PROCESS(A, B)
BEGIN
    if A = '1then
        C <= B;
    else
        C <= (others => 'Z');
    end if;
END PROCESS;

The answer is that in the above code, we are not trying to implement a sequential circuit, but a combinatorial circuit. On the simulation level, any change in A or B will trigger the PROCESS. And on synthesis level, the circuit is implemented using a LUT(look up table) rather than a flipflop. 


3 comments:

  1. ok but what about:

    bla : PROCESS(A, B)
    BEGIN
    if A = '1' then
    C <= B;
    else
    C <= (others => 'Z');
    end if;
    END PROCESS;

    that synthesizes fine for me

    ReplyDelete
    Replies
    1. this will work fine because you havnt used it as a clock. you are not doing edge detection here. but only level detection of A and B.

      Delete
  2. actually in spartan and virtex series board do not have dual edge sensitive flipflop. Once hardware is unavailable how could u implement it. But I got an information that in cool runner series board u can implement this logic.
    But u can consider two separate process where one is rising edge sensitive and other one is negative edge sensitive

    ReplyDelete