- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic to the Top
- Bookmark
- Subscribe
- Printer Friendly Page
how to modify a signal in three different process?
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-30-2011 05:30 AM
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.
Solved! Go to Solution.
Re: how to modify a signal in three different process?
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-30-2011 06:50 AM
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
Re: how to modify a signal in three different process?
[ Edited ]- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-30-2011 09:54 AM - edited 07-30-2011 07:26 PM
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
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.
Re: how to modify a signal in three different process?
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-30-2011 03:47 PM
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;
back to VHDL school
[ Edited ]- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-30-2011 04:02 PM - edited 07-30-2011 06:17 PM
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
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.
Re: back to VHDL school
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-30-2011 06:29 PM
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.
Re: back to VHDL school
[ Edited ]- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-30-2011 06:53 PM - edited 07-30-2011 07:32 PM
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
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.
Re: how to modify a signal in three different process?
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-30-2011 08:35 PM
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
back to hardware school
[ Edited ]- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-30-2011 09:31 PM - edited 07-30-2011 09:33 PM
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
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.
Re: how to modify a signal in three different process?
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-31-2011 02:43 PM
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;











