Sign In

Don't have a Xilinx account yet?

  • Choose to receive important news and product information
  • Gain access to special content
  • Personalize your web experience on Xilinx.com

Create Account

Username

Password

Forgot your password?
XClose Panel
Xilinx Home
Reply
Regular Contributor
black_flowers
Posts: 59
Registered: ‎06-27-2009
0
Accepted Solution

how to modify a signal in three different process?

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.

 

escanear0006.jpg
Expert Contributor
gszakacs
Posts: 5,265
Registered: ‎08-14-2007
0

Re: how to modify a signal in three different process?

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
Expert Contributor
eteam00
Posts: 7,505
Registered: ‎07-21-2009

Re: how to modify a signal in three different process?

[ Edited ]

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.
Regular Contributor
black_flowers
Posts: 59
Registered: ‎06-27-2009
0

Re: how to modify a signal in three different process?

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;

 

Expert Contributor
eteam00
Posts: 7,505
Registered: ‎07-21-2009
0

back to VHDL school

[ Edited ]

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.
Regular Contributor
black_flowers
Posts: 59
Registered: ‎06-27-2009
0

Re: back to VHDL school

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.

 

Expert Contributor
eteam00
Posts: 7,505
Registered: ‎07-21-2009

Re: back to VHDL school

[ Edited ]

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.
Expert Contributor
gszakacs
Posts: 5,265
Registered: ‎08-14-2007

Re: how to modify a signal in three different process?

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
Expert Contributor
eteam00
Posts: 7,505
Registered: ‎07-21-2009
0

back to hardware school

[ Edited ]

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.
Regular Contributor
black_flowers
Posts: 59
Registered: ‎06-27-2009
0

Re: how to modify a signal in three different process?

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