cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Adventurer
Adventurer
22,636 Views
Registered: ‎06-27-2009

how to modify a signal in three different process?

Jump to solution

i don't know whether it is possible or not. But i need to create the vhdl configuration shown in the attached image. It's a simple circuit that i have implement in a microcontroller and now i'm trying to implement in an fpga in vhdl code. It's basically a timer with one inc button one dec button, one timer and one lcd for showing the current value of "time".

 

I decided to implement it in vhdl this way (the same shown in the picture):

 

one process for inc button

another process for dec button

another for timer (this process decrement the "tiempo" signal each second)

 

a signal called "tiempo" that contains the value of the current time and wich should be modified into each of the three proceses.

 

and finally an lcd in for showing the value of the "tiempo" signal.

 

I tryed to implement this in vhdl with multiple process that drives the same signal and i get a synthesis error:

"this signal is connected to multiple drivers"  for the "tiempo" signal.

 

So, what would be the right approach for this purppose?

 

thanks.

 

Tags (1)
escanear0006.jpg
0 Kudos
1 Solution

Accepted Solutions
Highlighted
Professor
Professor
29,472 Views
Registered: ‎08-14-2007

Some comments on the code:

 

1)  Although your process is not "synchronous" it is sequential.  i.e. you are inferring

storage elements.  This is called an asynchronous sequential state machine.  It is

considered bad practice in an FPGA because it will be implemented with look-up

tables and probably won't behave like the simulation.

 

2) You could easily accomplish what you want with a synchronous process.  Change

your variables to signals, make the process depend only on clock, and surround

the logic with if rising_edge (CLK_50MHz) then    - - -   end if;  Then you can

get rid of the vClockAnterior signal because you have already detected the edge

of CLK_50MHZ using a real flip-flop structure.

 

Note that while a D flip-flop is itself a piece of asynchronous sequential logic, in

the FPGA the flip-flops are hard functions which have been designed to have

extremely high performance.  The LUT-based functions your code infers will

have extremely poor performance if it works at all.  An FPGA is not really a

gate array but a logic cell array, where the logic cell consists of LUTs and flip-flops.

Trying to build sequential logic from "gates" doesn't work well because the

gates are mapped into LUTs.

 

As Bassman is fond of saying:  Think Hardware!

 

Regards,

Gabor

-- Gabor

View solution in original post

24 Replies
Highlighted
Professor
Professor
22,634 Views
Registered: ‎08-14-2007

For synthesis, each process is considered a "driver" of a signal.  You cannot connect multiple

"drivers" because each acts like a logic gate with active output drive.  So no, you cannot drive

the same signal from multiple processes.

 

On the other hand you can make one process as large as you like.  In a typical synchronous

system you could do everything in one process whose only trigger is the clock.  Within that

process you can place the logic for increment, the logic for decrement, and the logic for

timer.  If more than one of these logic blocks assigns a value to "tiempo" on the same

clock cycle, then the last one will "win."  That is on any given clock cycle the process runs

through in the order written, and the value at the end of the process is the actual value

assigned for that clock cycle.

 

If you were using multiple processes because you wanted to trigger on multiple events

like rising_edge (inc_button), rising_edge (dec_button), etc.  Then you should be aware

that there are no flip-flops that can produce the logic you describe directly.  For slow inputs

like pushbuttons, you should sample the state of the button with the clock and then use

logic to determine that the current state of the button does not match its previous state.

Also, unless your button has hardware debouncing, you need to filter the button using

logic to prevent detection of multiple edges when pressed (Google for "debounce").

 

HTH,

Gabor

-- Gabor
Highlighted
Instructor
Instructor
22,632 Views
Registered: ‎07-21-2009

one process for inc button

another process for dec button

another for timer (this process decrement the "tiempo" signal each second)

a signal called "tiempo" that contains the value of the current time and wich should be modified into each of the three proceses.

When you come home from work:

1.  Your daughter asks you to play 'hide and seek'

2.  Your wife asks you to wash the dishes

3.  You are tired and want to take a nap

 

You cannot do all three things at once, and you must decide between daughter, wife, and you (tired).  The same is true for your TIEMPO counter.  You must bring INC, DEC, and TIMER together in a single logic process to determine what to do with TIEMPO.

 

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
Highlighted
Adventurer
Adventurer
22,624 Views
Registered: ‎06-27-2009

ok, o followed your advice (gszakacs) and i did everything in one process. So i can't use the input signals (inc,dec,clk) as "events" or "rising edges". I use a variable to store the last value of the signal in order not to enter the "if" clause more than once, each time i press the buttom. I will also need a kind of wait statment in order to avoid "debouncing", but i'll do it later. So now i have a problem with my code. I don't know why it's entering the conditional "if's" that i have for detecting button pressed. It's happening at the very beginning of the process. I mean: once i start the program i have detected that the program is entering those if statements even thought button are not pressed at all. But only at the beginning because once the program has started it doesn't happens and it only enters the if's when the buttons are pressed, as expected. I have pulled down the pushbuttons on the constraint editor. Where can be the problem?

 

this the "main" code:  (thanks in advance)

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.numeric_std.all;
use work.my_components.all;

entity lcd is
port(
	inc:in std_logic;
	dec:in std_logic;
	start:in std_logic;
   CLK_50MHZ:in std_logic;
   LCD_E:out std_logic;
   LCD_RS:out std_logic;
   LCD_RW:out std_logic;
   LCD_D:out std_logic_vector(3 downto 0);
	led:out std_logic
);
end lcd;

architecture Behavioral of lcd is
signal tiempo : std_logic_vector(31 downto 0):= "00000000000000000000000000000000";
--shared variable vTiempo: integer:=0;
begin
lcd:component lcd_write_number_test port map(CLK_50MHZ,tiempo,LCD_E,LCD_RS,LCD_RW,LCD_D);
temporizacion: process(CLK_50MHZ,inc,dec,start)
variable cuenta: natural:=0;
variable vClockAnterior: boolean :=false;
variable vIncAnterior: boolean :=false;
variable vDecAnterior: boolean :=false;
variable vStartAnterior: boolean :=false;
variable vEstadoTemporizando: boolean :=false;

begin
if (CLK_50MHZ='1') then
	if(not vClockAnterior) then
		vClockAnterior:=True;
		if (cuenta<50000000) then --we need to count to 50000000 in order to get 1 second.
		cuenta:=cuenta + 1;
		else
			tiempo<=tiempo-1;
		cuenta:=0;
		end if;
	end if;
else
vClockAnterior:=False;
end if;

if (inc='1') then
	if(not vIncAnterior) then
	vIncAnterior:=True;
	tiempo<=tiempo+1;
	end if;
else
	vIncAnterior:=False;
end if;

if (dec = '1') then
	if (not vDecAnterior) then
	vDecAnterior:=True;
	tiempo<=tiempo-1;
	end if;
else
	vDecAnterior:=False;
end if;

end process temporizacion;
end Behavioral;

 

0 Kudos
Highlighted
Instructor
Instructor
22,620 Views
Registered: ‎07-21-2009

If a process is clocked (synchronous), only the clock (and any asynchronous set/reset) should be in the process sensitivity list.

 

If infering positive-edge triggerred registers, use the if rising_edge(CLK_50MHZ) construct, rather than if (CLK_50MHZ='1') (which will infer a LATCH rather than a register).

 

You have other problems with your use of VHDL code, too many to list.  Looks very much like you need to spend more time improving your mastery of VHDL.

 

Your short code snippet has but one comment.  The intent of your code is uncertain, and this makes it more difficult to help you (other than ask 'what are you trying to do?').

 

I think working face-to-face with someone who can give you solid and detailed review and advice on your design would be a big help to you.  Trying to learn VHDL through an online forum is not easy or efficient.

 

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
0 Kudos
Highlighted
Adventurer
Adventurer
22,607 Views
Registered: ‎06-27-2009

it's not a sincronous process. Even thought it's a clock signal i'm not using it as a clock for the process. It's a very simple process to implement into a microcontroller, but i'm just trying it into an fpga. I know it's difficult to figure out what i'm trying to do, because it's not a typical vhdl implementation. I dare to say that vhdl it's not the best way to implement this application. I'm just trying to discover whether it is possible or not. This is not a combinational circuit nor a state machine neither. I need to increment/decrement a temp value so those signals are asinchronous. And i have a timer, that's why i need the clk signal. I also need the clk signal for typing on the lcd. So i will try some more for get the program working this way. If it's not possible i will try with an structural description where i'll be using components instead of process. And if i can't get it working either,  i will give up.

You have mentioned something about using "rising_edge" but i cannot use more than one on the same process, besides if i change a variable or signal value into the if clause of a "rising_edge" event i couldn't modify the same vasiable later in another part of the process.

 

Excuse me for not writting comments on my code, tomorrow i will put again my code, this time with comments,

thanks.

 

0 Kudos
Highlighted
Instructor
Instructor
22,605 Views
Registered: ‎07-21-2009

it's not a synchronous process

 

I think posting a more elaborate description of how your code works is an excellent idea.  I would like to hear from you why an asynchronous design has advantages over a synchronous design.

 

Be forewarned, most of the folks on this forum -- those to whom you are looking for review and advice -- are completely unenthusiastic about intentionally asynchronous FPGA design in most applications.  More often than not, the asynchronous designs posted in these forums are the works of designers who underestimate the complexities and uncertainties of asynchronous design, while also failing to grasp the simplicity and certainty of synchronous design.

 

If you are interested in a mini-design-review, please be prepared to defend your design.  And we (most of us) will try to be 'gentle' with you.

 

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
Highlighted
Professor
Professor
29,473 Views
Registered: ‎08-14-2007

Some comments on the code:

 

1)  Although your process is not "synchronous" it is sequential.  i.e. you are inferring

storage elements.  This is called an asynchronous sequential state machine.  It is

considered bad practice in an FPGA because it will be implemented with look-up

tables and probably won't behave like the simulation.

 

2) You could easily accomplish what you want with a synchronous process.  Change

your variables to signals, make the process depend only on clock, and surround

the logic with if rising_edge (CLK_50MHz) then    - - -   end if;  Then you can

get rid of the vClockAnterior signal because you have already detected the edge

of CLK_50MHZ using a real flip-flop structure.

 

Note that while a D flip-flop is itself a piece of asynchronous sequential logic, in

the FPGA the flip-flops are hard functions which have been designed to have

extremely high performance.  The LUT-based functions your code infers will

have extremely poor performance if it works at all.  An FPGA is not really a

gate array but a logic cell array, where the logic cell consists of LUTs and flip-flops.

Trying to build sequential logic from "gates" doesn't work well because the

gates are mapped into LUTs.

 

As Bassman is fond of saying:  Think Hardware!

 

Regards,

Gabor

-- Gabor

View solution in original post

Highlighted
Instructor
Instructor
22,592 Views
Registered: ‎07-21-2009

As Bassman is fond of saying:  Think Hardware!

 

I think this is the quintessential message of your post, Gabor.

 

it's not a sincronous process... It's a very simple process to implement into a microcontroller, but i'm just trying it into an fpga.

 

black_flowers doesn't yet appreciate that the microcontroller process implementation is indeed synchronous.  In other words, the premise for his asynchronous design is flawed, and his translation from microncontroller to FPGA is fundamentally incorrect.

 

Do you remember the movie "The Matrix"?  When opening one's eyes to the reality of 'hardware', it reminds me of this scene.  And I quote from the scene:

 

Remember, all I'm offering is the truth, nothing more.

 

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
0 Kudos
Highlighted
Adventurer
Adventurer
22,582 Views
Registered: ‎06-27-2009

thanks!!

 

I've finally implemented it as a synchronous system. More or les as a states machine with some extra if's and signals.

It's actually working but... perhaps it's not correct at all, please if you notice any mistake, or this is not the best way, please let me know.

It's more or less like the attached diagram. And this is the vhdl code.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.numeric_std.all;
use work.my_components.all;

entity lcd is
port(
	inc:in std_logic;
	dec:in std_logic;
	start:in std_logic;
   CLK_50MHZ:in std_logic;
   LCD_E:out std_logic;
   LCD_RS:out std_logic;
   LCD_RW:out std_logic;
   LCD_D:out std_logic_vector(3 downto 0);
	led:out std_logic
);
end lcd;

architecture Behavioral of lcd is
TYPE TipoEstados IS (Esperando,Temporizando);  -- we only need two states
signal tiempo : std_logic_vector(31 downto 0):= "00000000000000000000000000000000";
--signal tiempo is declared as a 32 bit std_logic_vector since the lcd works with 32bit values (this is how it's originally designed)
signal EstadoActual: TipoEstados;
begin

lcd:component lcd_write_number_test port map(CLK_50MHZ,tiempo,LCD_E,LCD_RS,LCD_RW,LCD_D);
-- the lcd is always connected to "tiempo" signal so it's showing at every moment the time value (in seconds)
logica_estado: process(CLK_50MHZ,inc,dec,start,EstadoActual)
variable cuenta: natural:=0;
variable vIncAnterior: boolean:=false;
variable vDecAnterior: boolean:=false;

begin

	if(rising_edge(CLK_50MHZ)) then
		case (EstadoActual) is
		when Esperando =>
			led<='0';  -- the led is the only output signal, which is on only when is "timing"
			if(start='1')then EstadoActual<= Temporizando; -- when we press star buttom "timing" begins.
			end if;
			if(inc='1')then -- when press the inc button,signal tiempo is increased.
				if(not vIncAnterior) then 
					tiempo<=tiempo+1;
					vIncAnterior:=true;
				end if;
			else
			vIncAnterior:=false;
			end if;
			if(dec='1')then    -- when press dec, tiempo is decreased
				if(not vDecAnterior) then 
					tiempo<=tiempo-1;
					vDecAnterior:=true;
				end if;
			else
			vDecAnterior:=false;
			end if;
		when Temporizando =>  
			led<='1';
			if (cuenta<50000000) then   -- we count to 50000000 in order to get one second.
				cuenta:=cuenta + 1;
			else
				cuenta:=0;
				tiempo<=tiempo-1;   --so each second we decrease tiempo signal.
			end if;
			if(tiempo<=0)then EstadoActual<= Esperando;  --when the time is over we come back to Waitting state(Esperando).
			end if;
		end case;
	end if;

end process logica_estado;
end Behavioral;

 

 

escanear0007.jpg
0 Kudos
Highlighted
Instructor
Instructor
19,064 Views
Registered: ‎07-21-2009

From post #5 in this thread:

If a process is clocked (synchronous), only the clock (and any asynchronous set/reset) should be in the process sensitivity list.

 

I am unfamiliar with VHDL 'natural'.  I'm wondering why 'cuenta' is cast as 'natural' instead of 26-bit 'signal'.

 

If signals 'inc', 'dec', and 'start' are asynchronous inputs, they must be aligned to CLK_50MHZ clock domain before they are used by the state machine.  If they are not aligned to the state machine clock, they will cause the state machine to 'lock up'.  If they are switch inputs, they must also be de-bounced.

 

The inputs 'inc' and 'dec' are ignored while 'cuenta is counting.  Short assertion pulses on these inputs may not be recognised.

 

If 'tiempo' is a synchronous counter, your code permits 'tiempo' to decrement to -1 in both state machine states.  Perhaps you wish 'tiempo' to decrement no further than '0'.

 

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
0 Kudos
Highlighted
Adventurer
Adventurer
19,059 Views
Registered: ‎06-27-2009

If a process is clocked (synchronous), only the clock (and any asynchronous set/reset) should be in the process sensitivity list.

and what happens with the input singnals?. I have seen a lot of state machines that includes those input signals in the sensitivity list. There are another way of doing it with two processes, one for "combinational logic" with signal inputs in the sensitivty list, and the other for "state memory"  with only clock and reset on the sensitivity list. But i don't know why i can't get this configuration working. I'm having trouble with this two process configuration in some other simple state machines, i have in mind to ask about that topic in another thread. So i can only do it with one process and with all input signals on the sensitivity list.

 

I could use 26-bit 'signal, there's no reason for using natural.

 

I can't understand what you mean with align those signals with CLK_50MHZ. What's this exactly??

And of course, the inputs are push-buttons so they need to be debounced, but i haven't done it yet.

 

And finally i don't really mind that the tiempo signal takes negative values.

 

once again, thanks for your help.

 

0 Kudos
Highlighted
Instructor
Instructor
19,057 Views
Registered: ‎07-21-2009

I can't understand what you mean with align those signals with CLK_50MHZ. What's this exactly??

 

  • You have an async input signal used by two different registers, A and B.
  • The interconnect delay from input pin to register A is longer than the interconnect delay from input pin to register B.
  • Register A 'sees' a delayed version of the async input.
  • On any given rising clock edge, register A may 'see' a different level for the async input than register B, because of the difference in propagation delays from input pin to register input.

 

This problem is easily fixed by registering the async input, and using only the registered copy of the input throughout your design.  The registered copy of the async input is synchronous to the clock domain.  It is aligned with the clock.

 

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
0 Kudos
Highlighted
Instructor
Instructor
19,056 Views
Registered: ‎07-21-2009

If a process is clocked (synchronous), only the clock (and any asynchronous set/reset) should be in the process sensitivity list.

and what happens with the input singnals?. I have seen a lot of state machines that includes those input signals in the sensitivity list.

 

Correct me if I'm wrong (I'm not a VHDL wizard), but everything within this IF-THEN statement

 

if(rising_edge(CLK_50MHZ)) then

 

is clocked and synchronous (not combinatorial).

 

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
0 Kudos
Highlighted
Professor
Professor
19,044 Views
Registered: ‎08-14-2007

If a process is clocked (synchronous), only the clock (and any asynchronous set/reset) should be in the process sensitivity list.

and what happens with the input singnals?

 

All inputs are only sampled on the clock edge.  This physically matches the nature of real

D flip-flops in the hardware.  They should not be in the list because your actual hardware

will not change state if some input other than the clock changes state, only at the clock

edge.  A sensitivity list does not describe all of the inputs to the logic (necessarily) but only

those that "trigger" the process to run.  A flip-flop is only triggered on a clock edge or

possibly during assertion of asynchronous set/reset.  And in the reset case there should

be no sensitivity to other inputs (that would describe a D latch instead of a set or reset).

 

I have seen a lot of state machines that includes those input signals in the sensitivity list.

 

I would look again at those state machines.  Either they use two processes, one clocked with just the

clock and perhaps reset in the sensitivity list and one combinatorial with all inputs in the sensitivity list,

or they should use only one clocked process with just the clock and possibly reset in the sensitivity

list.  A clocked process that includes more signals in the list is wrong for synthesis, because it will

not match the simulation behavior.  In essence, synthesis uses standard templates to infer clocked

logic which ignore other signals in the list, and others to infer combinatorial logic which assume all

inputs are in the list.  Any code which doesn't match this paradigm has a chance of working differently

in hardware than in simulation.

 

-- Gabor

-- Gabor
Highlighted
Adventurer
Adventurer
19,036 Views
Registered: ‎06-27-2009

yes you are right, they used two process indeed but they were using clk,reset and NextState in the sensitivity list, so i suppose that NextState shouldn't be at sensitivity list neither.

 

So, i changed the sensitivity list and now it looks like this:

logica_estado: process(CLK_50MHZ)

 is it totally correct now?

Or course i need to add something for debouncing the inputs but i prefer to do it later.

 

And about the comment of eteam: "This problem is easily fixed by registering the async input, and using only the registered copy of the input throughout your design.  The registered copy of the async input is synchronous to the clock domain.  It is aligned with the clock."  I'm not very sure i have totally understood the reason why;  but i suppose that it's in order to avoid changes in inputs once we are into the process, is it right?

 

And finally i'm not very sure that the timer implementation was completely right for an fpga, is it?

0 Kudos
Professor
Professor
19,031 Views
Registered: ‎08-14-2007

The best way to see if your code is correct is to simulate it.  I would expect that you'd

find at least one problem if you had simulated:

 

signal EstadoActual: TipoEstados; -- Uninitialized state variable used in a process with no reset

signal EstadoActual: TipoEstados := Esperando; - Initialize the state variable for both simulation and synthesis

 

The point Bob made about asynchronous inputs is not easy to understand and often

misinterpreted as being a "metastability" problem.  What you need for this code to work well

is "clean" signals from the pushbuttons.  You can do this in a separate "debounce" process.

A typical switch debouncer simply samples the switch at a rate slow enough that bouncing

will settle out between two sample times.  You can think of a mechanical switch turning

on like dropping a ball on the ground.  The switch is on while the ball touches the ground.

If the ball takes two seconds to finish bouncing and come to rest on the ground, then you

can "sample" the ball (is it on the ground now?) no more often than once every two seconds

and be sure that your sample will only go from 0 (not on the ground) to 1 (on the ground) once.

Note that any sample before the ball is dropped is guaranteed to be 0.  Any sample after

the ball comes to rest is guaranteed to be 1.  A sample taken while the ball is bouncing

can be 0 or 1.  The sampling period should be st such that at most one sample will be

taken while the ball bounces.  So if the red sample is taken while the ball bounces you have

 

00001111111

or

00000111111

 

In either case you only have a single transition from 0 to 1.  If you sample too fast, you

can have more than one "red" sample allowing:

 

00001011111

 

 

 

Hope this explains the problems.

 

-- Gabor

-- Gabor
0 Kudos
Highlighted
Instructor
Instructor
19,026 Views
Registered: ‎07-21-2009

And about the comment of eteam: "This problem is easily fixed by registering the async input, and using only the registered copy of the input throughout your design.  The registered copy of the async input is synchronous to the clock domain.  It is aligned with the clock."  I'm not very sure i have totally understood the reason why;  but i suppose that it's in order to avoid changes in inputs once we are into the process, is it right?

 

Let me try to explain once again.  Here is a snippet of your code:

 

if(inc='1')then -- when press the inc button,signal tiempo is increased.
   if(not vIncAnterior) then
   tiempo<=tiempo+1;
   vIncAnterior:=true;
   end if;

 

Notice that the multi-bit counter tiempo and the state bit vIncAnterior all change state on the same clock edge, based (in part) on the asynchronous input inc.

 

What is the timing relationship between the signal inc and the clock edge used to change tiempo and vIncAnterior?  It's unknown and variable, of course, because inc  is an asynchronous input.

 

Each of the registers must be directly or indirectly connected to the inc input signal, and these connections vary in length, depending on where the various registers are located in the FPGA.

 

Let's say the propagation delay (mostly interconnect) between the inc package pin and the registers for tiempo and vIncAnterior is as short as 1nS for the shortest connection and as long as 2nS for the longest connection.

 

If the signal inc changes from '0' to '1' only 3nS before the clock rising edge, then all the registers will see a '1' when they are clocked.  If the signal inc changes from '0' to '1' only 1.5nS before the clock rising edge, then some of the registers will see a '1' when they are clocked, because the propagation delay from inc package pin to register input is nice and short.  Some of the registers will see a '0' when they are clocked, because the propagation delay from inc package pin to register input is longer.

 

Because of the variation in propagation delays between the inc input pin and the register inputs, some register bits will 'see' the inc signal change on one clock rising edge and other register bits will see the inc signal change on the next clock rising edge.

 

What do you think would happen to the tiempo counter if some of the counter bits 'incremented' in one clock cycle and the rest of the counter bits 'incremented' in the next clock cycle?

 

Does this make sense?

 

The solution is to register the inc input signal, and use the registered copy of the inc signal for all of the registers which use the inc signal.  The registered copy of the inc signal is aligned to the clock rising edge.  Changes of the registered copy of the inc signal can be guaranteed to reach all of the register bits in the same clock cycle.

 

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
Highlighted
Historian
Historian
19,014 Views
Registered: ‎02-25-2008

@eteam00 wrote:

From post #5 in this thread:

If a process is clocked (synchronous), only the clock (and any asynchronous set/reset) should be in the process sensitivity list.

 

I am unfamiliar with VHDL 'natural'.  I'm wondering why 'cuenta' is cast as 'natural' instead of 26-bit 'signal'.


Type natural is a non-negative integer, essentially integer range 0 to 2**32-1. I use natural for counters pretty much all the time (except of course when the count must be negative). The caveats with natural are:

 

a) it actually holds 31 bits of information even though it's 32 bits wide, and

b) when you use it, since it is by default 32-bits wide, you should constrain it with a range so you don't get a whole lot of unused flipflops and your comparators don't get huge and all of the other reasons to constrain it.

 

And it is better to use natural (or integer, or unsigned), than rely on std_logic_arith and its crappy functions for incrementing and decrementing std_logic_vectors, which are not "numerics" in the sense that the bit sequence 1001 doesn't necessarily mean 9. It might be negative.

----------------------------Yes, I do this for a living.
0 Kudos
Highlighted
Historian
Historian
19,012 Views
Registered: ‎02-25-2008

@black_flowers wrote:

 There are another way of doing it with two processes, one for "combinational logic" with signal inputs in the sensitivty list, and the other for "state memory"  with only clock and reset on the sensitivity list. 

 


That's called a "two-process state machine," and you should never ever ever use them in any design ever.

----------------------------Yes, I do this for a living.
0 Kudos
Highlighted
Adventurer
Adventurer
12,799 Views
Registered: ‎06-27-2009

great! i'm glad to hear that i should not use two process state machine, since i'm having  trouble with this kind of configuration with  other programs.

0 Kudos
Highlighted
Adventurer
Adventurer
12,795 Views
Registered: ‎06-27-2009

@eteam00 wrote:

 

Let me try to explain once again.  Here is a snippet of your code:

 

if(inc='1')then -- when press the inc button,signal tiempo is increased.
   if(not vIncAnterior) then
   tiempo<=tiempo+1;
   vIncAnterior:=true;
   end if;

 

Notice that the multi-bit counter tiempo and the state bit vIncAnterior all change state on the same clock edge, based (in part) on the asynchronous input inc.

 

What is the timing relationship between the signal inc and the clock edge used to change tiempo and vIncAnterior?  It's unknown and variable, of course, because inc  is an asynchronous input.

 

Each of the registers must be directly or indirectly connected to the inc input signal, and these connections vary in length, depending on where the various registers are located in the FPGA.

 

Let's say the propagation delay (mostly interconnect) between the inc package pin and the registers for tiempo and vIncAnterior is as short as 1nS for the shortest connection and as long as 2nS for the longest connection.

 

If the signal inc changes from '0' to '1' only 3nS before the clock rising edge, then all the registers will see a '1' when they are clocked.  If the signal inc changes from '0' to '1' only 1.5nS before the clock rising edge, then some of the registers will see a '1' when they are clocked, because the propagation delay from inc package pin to register input is nice and short.  Some of the registers will see a '0' when they are clocked, because the propagation delay from inc package pin to register input is longer.

 

Because of the variation in propagation delays between the inc input pin and the register inputs, some register bits will 'see' the inc signal change on one clock rising edge and other register bits will see the inc signal change on the next clock rising edge.

 

What do you think would happen to the tiempo counter if some of the counter bits 'incremented' in one clock cycle and the rest of the counter bits 'incremented' in the next clock cycle?

 

Does this make sense?

 

The solution is to register the inc input signal, and use the registered copy of the inc signal for all of the registers which use the inc signal.  The registered copy of the inc signal is aligned to the clock rising edge.  Changes of the registered copy of the inc signal can be guaranteed to reach all of the register bits in the same clock cycle.

 

-- Bob Elkind


yes, i have done it like this. I added some variables at the beginning of the process for storing the input values like this:

logica_estado: process(CLK_50MHZ)
variable vTiempo:integer:=0;
variable cuenta: natural:=0;
variable vIncAnterior: boolean:=false;
variable vDecAnterior: boolean:=false;
variable vInc,vDec,vStart: std_logic;

begin
	vInc:=Inc; vDec:=Dec; vStart:=Start

...
...

 i allways do it, when working with microcontrollers, when i need to check the input values in different parts of the program; and thus avoiding changes on the inputs into the same cycle of the program.

 

I also noticed that this instruction was creating trouble:

tiempo<=tiempo-1;

 So now i use a variable instead of the tiempo signal, and i assign it to the tiempo signal at the end of the process like this:

            if(vDec='1')then    
                if(not vDecAnterior) then
                    vTiempo:=vTiempo-1;
                    vDecAnterior:=true;
                end if;
            else
            vDecAnterior:=false;
            end if; ... ... end if; tiempo<=conv_std_logic_vector(vTiempo, 32); end process logica_estado; end Behavioral;

 Seems be some kind of trouble when decreasing std_logic_vector() value. However the problem it's only when decreasing with the push-button, because when decreasing from the timer process it was not problem at all; strange.

0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
12,788 Views
Registered: ‎01-03-2008
A push button without debounce logic may generate multiple edges.
------Have you tried typing your question into Google? If not you should before posting.
Too many results? Try adding site:www.xilinx.com
0 Kudos
Highlighted
Teacher
Teacher
12,784 Views
Registered: ‎09-09-2010

@bassman59 wrote:

 

And it is better to use natural (or integer, or unsigned), than rely on std_logic_arith and its crappy functions for incrementing and decrementing std_logic_vectors, which are not "numerics" in the sense that the bit sequence 1001 doesn't necessarily mean 9. It might be negative.


That's why some of us use numeric_std, and define internal signals as signed or unsigned as appropriate.


------------------------------------------
"If it don't work in simulation, it won't work on the board."
0 Kudos
Highlighted
Historian
Historian
12,777 Views
Registered: ‎02-25-2008

@rcingham wrote:

@bassman59 wrote:

 

And it is better to use natural (or integer, or unsigned), than rely on std_logic_arith and its crappy functions for incrementing and decrementing std_logic_vectors, which are not "numerics" in the sense that the bit sequence 1001 doesn't necessarily mean 9. It might be negative.


That's why some of us use numeric_std, and define internal signals as signed or unsigned as appropriate.


That was implicit in my statement. I'm kinda astonished that the IEEE ratified the new versions of the std_logic_arith libraries (whatever they're called) that allow the ridiculous std_logic_arith lossage to continue. But I'm not on the committee and I don't have to use the new crap anyway.

----------------------------Yes, I do this for a living.
0 Kudos