Why not every if can have else?

3

I'm exploring a little bit about FPGA and wanted to do something pretty simple, a button that when clicked would change status .

Ignoring the other problems in logic itself, the fact that caught my attention was that it does not even "compile":

if rising_edge(clk) then
   status <= '1';
else 
   status <= '0';
end if;

This returns me an error:

  

[Synth 8-27] else clause after check for clock not supported

In addition to two other bugs:

  

[Synth 8-285] failed synthesizing module 'out'
  [Common 17-69] Command failed: Synthesis failed - please see the console or run log file for details

I'm using a Xilinx Artix-7, using Vivado 2017.1, if this is something important.

This is totally strange, I always start from the beginning that all if could have a else , but it seems not so.

Why does this occur? And in what other conditions can else not be used?

    
asked by anonymous 21.08.2017 / 15:29

2 answers

1

There are some further complicators on the issue of "reading" a button that will interfere with the result, especially deboucing to remove mechanical button noises, but I will not go into these details in the answer. p>

For more information: Debounce Logic Circuit (with VHDL example)

As I've commented, this strangeness is caused whenever you try to parse the VHDL code as a program and not as an electronic circuit (this is why # that VHDL should not be considered a programming language). Make the code snippet below:

if rising_edge(clk) then
    status <= '1';
else
     status <= '0';
end if;

It does not make much sense when analyzing the circuit that this should generate. Basically the code is saying: the status signal should receive the value '1' whenever there is a positive transition in the clk sign and in all other cases it should receive '0' . When the clk sign stabilizes at '1' after the transition will already characterize a other case , entering else ; that is, ideally the signal transition time is 0, so the status signal would be at the high logic level for a time equal to 0. The synthesizer can not understand this and generates the error.

For easier visualization, we can actually draw the circuit. When you want to change the state of a signal based on the change of state of another signal you are working with registers. That is, the if part would generate the following circuit:

Thatisnothingmorethanaregisterthatassignsthe'1'valuetothestatussignalwheneverthereisapositivetransitioninclk.Notethatthereisnowaytogenerateacircuitthatisthenegationofrising_edgeexpressiontogeneratetheelsecircuit,andconsideringthatthedurationtimeofthe'1'valuewouldbe0inthissituation,itwouldbeequalto'0'always,whatwouldgeneratethecircuit:

Whatdoesnotmakesense,sincethestatussignwouldgettwodistinctvalues,'1'and'0',ineverypositivetransitionofclk.

Butitisinterestingtonotethatthisisespeciallytruewhenyouaredealingwithtransitionsinif.Ifyouonlytreatthevalue,thesynthesizerwillusuallyunderstandwhatyouwanttodoandwillsynthesizetheappropriatecircuit.Averysimplebuttonexamplewouldbetocheck,witheachpositivetransitionofclk,ifthelogicallevelofthebuttonis0¹and,whenitdoes,setthevalueofstatusto'1'.

process(clk)beginifrising_edge(clk)thenifbutton='0'thenstatus<='1';elsestatus<='0';endif;endif;endprocess;

Thecircuitgeneratedbythiscodeis:

Noticethatthegeneratedcircuitwillbeonlyaflip-floptypeDwheretheinputwillbethedeniedvalueofbuttonandtheoutputwillbestatus.Ifyoudothesimulation,youwillseethatthevalueofstatuswillalwaysbe'1'whilebuttonis'0'(pressed),wherestatustransitionswillbesynchronoustoclkduetotheregister.

Notice that the status sign is changed to '1' only in the positive transition of clk after button is '0' precisely because it is synchronous to clk . The same happens at the end, when status is changed to 0 .

Notes:

  • I have considered that the button is pressed as logic level 0 because this is the most common implementation on the development boards ( pull-down circuit).
  • 21.08.2017 / 16:35
    0

    The problem is not in the if/else syntax but in the <= comparison operator you are using in place of the := assignment operator, such as:

    if rising_edge(clk) then
       status := '1';
    else 
       status := '0';
    end if;
    
        
    21.08.2017 / 16:04