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'
valuetothestatus
signalwheneverthereisapositivetransitioninclk
.Notethatthereisnowaytogenerateacircuitthatisthenegationofrising_edge
expressiontogeneratetheelse
circuit,andconsideringthatthedurationtimeofthe'1'
valuewouldbe0inthissituation,itwouldbeequalto'0'
always,whatwouldgeneratethecircuit:
Whatdoesnotmakesense,sincethestatus
signwouldgettwodistinctvalues,'1'
and'0'
,ineverypositivetransitionofclk
.
Butitisinterestingtonotethatthisisespeciallytruewhenyouaredealingwithtransitionsinif
.Ifyouonlytreatthevalue,thesynthesizerwillusuallyunderstandwhatyouwanttodoandwillsynthesizetheappropriatecircuit.Averysimplebuttonexamplewouldbetocheck,witheachpositivetransitionofclk
,ifthelogicallevelofthebuttonis0¹and,whenitdoes,setthevalueofstatus
to'1'
.
process(clk)beginifrising_edge(clk)thenifbutton='0'thenstatus<='1';elsestatus<='0';endif;endif;endprocess;
Thecircuitgeneratedbythiscodeis:
Noticethatthegeneratedcircuitwillbeonlyaflip-floptypeDwheretheinputwillbethedeniedvalueofbutton
andtheoutputwillbestatus
.Ifyoudothesimulation,youwillseethatthevalueofstatus
willalwaysbe'1'
whilebutton
is'0'
(pressed),wherestatus
transitionswillbesynchronoustoclk
duetotheregister.
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).