![]() |
|
|
|
#1 |
|
Posts: n/a
|
"Simon" <> wrote in message
news:bthb7n$kt7$... > I have a state machine which is coded like so: > > if rising_edge(CLK) then > case state is > when xyz => > OUT <= '1'; > state <= xyxyxy; > when xyxyxy => > OUT <= '0'; > etc > The problem is the output doesn't seem to happen in the state it should, Yes it does - but it doesn't happen in the state you WANT > instead it seems to happen in the next state. So in the above example the > signal OUT is set to 1 in state xyxyxy. Yup. That's what you asked for. > Does anyone have any idea on what I'm doing wrong? How can I make the > output change in the state? I guess you want the output to be a function of the state. But that's not what you wrote. Think about... > case state is > when xyz => > OUT <= '1'; > state <= xyxyxy; This code is executed at the moment of a clock edge. "case state" is testing "state" as it was JUST BEFORE the clock edge; but assignments to "state" and "OUT" are scheduling an update to those signals that will take place JUST AFTER the clock edge (the "next state" values). Not surprisingly, when you look at the code, "OUT" will transition to '1' at exactly the same time that "state" transitions to xyxyxy. There are numerous solutions. Here are three of the most familiar: (1) Set up your value of OUT at the same time as you transition INTO a state. That way, OUT is active in the same clock as the chosen state. But it's horrible to write, because you have to locate every transition into the state, everywhere in the state machine. (2) Take the assignments to OUT right outside the clocked state machine block, and create a separate COMBINATIONAL process to decode outputs from the state. This is the classic "Moore" architecture, but it has the disadvantage that there is now some intervening combinational logic between registers and outputs. (3) Arrange the state values to be named constants of std_logic_vector type (instead of enumerations). Now you can set up the bit-patterns of the state values so that some of the state bits are exactly your required output bits. This is cute because your main state machine code doesn't have to worry about outputs at all - they come along for the ride, together with the state value - but it's a little hard to maintain, and you have to choose all the state values yourself instead of leaving it to the synthesis tool. And here's a less familiar version, which I think is rather nice... process (clock, reset) type StateType is (state, names, here); variable state: StateType; begin if reset = '1' then -- reset everything state := IDLE; OUT <= '0'; elsif rising_edge(clock) then -- We do this in two stages. -- First, update the state variable: case state is when xyz => if Trigger then state := pqr; end if; when pqr => ...... end case; -- Now that the state variable ALREADY has its new -- (next-state) value, we can decode it to provide -- registered outputs: case state is when xyz => OUT <= '1'; -- OUT will be set during state xyz when others => OUT <= '0'; end case; end if; -- clocked logic end process; This approach has some nice advantages. The state type and variable are hidden within the state machine process, and don't pollute the rest of the architecture body. Because "state" is a variable, VHDL updates it immediately on assignment; hence, in the second part of the clocked process, "state" is in fact representing the next-state value (state register D inputs) rather than the current state register value. This "sneak preview" of the next state allows you to set up registered outputs in a nice clear way. And of course you don't need to mess around creating yet another signal to hold the next-state value. HTH -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK Tel: +44 (0)1425 471223 mail: Fax: +44 (0)1425 471573 Web: http://www.doulos.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated. |
|
|
|
#2 |
|
Posts: n/a
|
Hi
I have a state machine which is coded like so: if rising_edge(CLK) then case state is when xyz => OUT <= '1'; state <= xyxyxy; when xyxyxy => OUT <= '0'; etc etc etc The problem is the output doesn't seem to happen in the state it should, instead it seems to happen in the next state. So in the above example the signal OUT is set to 1 in state xyxyxy. Does anyone have any idea on what I'm doing wrong? How can I make the output change in the state? Thanks in advance. |
|
|
|
#3 |
|
Posts: n/a
|
Jonathan Bromley wrote: > And here's a less familiar version, which I think is > rather nice... Familiar to some, "nice" and logical. > -- Now that the state variable ALREADY has its new > -- (next-state) value, we can decode it to provide > -- registered outputs: Yes. Using process variables makes synthesis do some work and allows the designer to follow value changes by just looking at the code. > case state is > when xyz => > OUT <= '1'; -- OUT will be set during state xyz > when others => > OUT <= '0'; > end case; > > end if; -- clocked logic > end process; > > This approach has some nice advantages. The state > type and variable are hidden within the state machine > process, and don't pollute the rest of the architecture > body. Yes. Nice and logical. The designer can fearlessly use variable names like i, n, state, count, etc without interacting with other processes. While variable values are hidden to other processes, they can be viewed as simulation waveforms. > Because "state" is a variable, VHDL updates it > immediately on assignment; hence, in the second part > of the clocked process, "state" is in fact representing > the next-state value (state register D inputs) rather > than the current state register value. This "sneak > preview" of the next state allows you to set up > registered outputs in a nice clear way. And of course > you don't need to mess around creating yet another > signal to hold the next-state value. Well said. Process variables are the most logical way to describe state information. -- Mike Treseler |
|
|
|
#4 |
|
Posts: n/a
|
Mike Treseler a écrit:
> [...] > > Well said. Process variables are the most logical > way to describe state information. Indeed. I like it very much. I wonder why nobody ever tought this to me... It was always the same old two processes scheme. Thanks a lot Jonathan. -- ____ _ __ ___ | _ \_)/ _|/ _ \ Adresse de retour invalide: retirez le - | | | | | (_| |_| | Invalid return address: remove the - |_| |_|_|\__|\___/ |
|
|
|
#5 |
|
Posts: n/a
|
Nicolas Matringe wrote:
> Mike Treseler a écrit: > >> > [...] > >> >> Well said. Process variables are the most logical >> way to describe state information. > > > Indeed. I like it very much. > I wonder why nobody ever tought this to me... It was always the same old > two processes scheme. Here's my take on possible reasons for that one: - lack of "software" talent in the hardware design community. Many hardware designers refuse to appreciate the full value of nice code and powerful synthesis tools. They want to see their registers, muxes and adders jumping right out of their code. This sad attitude is called "hardware thinking" and is used as an excuse to avoid having to understand what a synthesis tool can do. The EDA vendors didn't help, as their software talent is in tool development, not applications engineering. - bad influence of Verilog. The most popular HDL on the planet doesn't make the distinction between variables and signals. Combined with the absence of a decent delta cycle mechanism, the result is eternal confusion about the semantics of "blocking" and "non-blocking" assignments, to newbies and experts alike. A popular "solution" in the Verilog community is to simply ban the discussed coding style altogether! (In Verilog speaky-speaky, this would sound "you shouldn't mix blocking and non-blocking assignments in the same always block.") Therefore, suppose you would code the example in Verilog and post it to comp.lang.verilog as an example of good style. Here's what might happen. You may be insulted to be a junior designer without the slightest clue on hardware design. You may be bombarded with links to award winning papers by Cliff Cummings that will help you to overcome your bad habits. You may be urged to take a training course ("Advanced Verilog Techniques For Ex-VHDL Designers"). On the other hand, the chance of an enthusiastic reaction such as yours, from someone that has seen the light, is very low, I believe. Makes you wonder where the multimillion dollar mistake exactly is. Regards, Jan -- Jan Decaluwe - Resources bvba - http://jandecaluwe.com Losbergenlaan 16, B-3010 Leuven, Belgium Bored with EDA the way it is? Check this: http://jandecaluwe.com/Tools/MyHDL/Overview.html |
|
|
|
#6 |
|
Posts: n/a
|
"Jan Decaluwe" <> wrote in
message news:... > Here's my take on possible reasons for that one: > > - lack of "software" talent in the hardware design community. "Insight" rather than "talent", maybe? Many people don't feel as strongly as they should about notions of locality and self-sufficiency in programming, and these are ideas that are quite hard to explain and exemplify. > - bad influence of Verilog. > The most popular HDL on the planet doesn't make the distinction > between variables and signals. Well... it can be asked so to do, by a very simple ruse: * signals are implemented either as nets, or as regs defined at the module level. Such regs must be assigned-to using nonblocking assignments within a clocked process if they represent flip-flops, but using delayless blocking assignments within a combinational process. * variables are implemented as regs assigned-to using delayless blocking assignment within a named begin..end; such regs may never be accessed from outside their named begin..end scope. > A popular "solution" in the Verilog community is to simply ban the > discussed coding style altogether! (In Verilog speaky-speaky, > this would sound "you shouldn't mix blocking and non-blocking > assignments in the same always block.") In fairness, there are plenty of VHDL authors/trainers who similarly aim to ban such coding style. The Openmore standard, and several in-house standards, mandate this "solution"; it's equivalent to denying a VHDL programmer the use of variables. Grrr. Sadly, at least one ASIC synthesis tool won't accept the "variable-like" Verilog style at all, so the forces of darkness think that they have justification for their prejudices. > Therefore, suppose you would code the example in Verilog and > post it to comp.lang.verilog as an example of good style. Here's > what might happen. You may be insulted by a junior designer > without the slightest clue on hardware design. You may be > bombarded with links to award winning papers by Cliff Cummings > that will help you to overcome your bad habits. You may be urged > to take a training course ("Advanced Verilog Techniques > For Ex-VHDL Designers"). Tee hee. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK Tel: +44 (0)1425 471223 mail: Fax: +44 (0)1425 471573 Web: http://www.doulos.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated. |
|
|
|
#7 |
|
Posts: n/a
|
"Simon" <> wrote in message news:<bthb7n$kt7$>...
> Hi > > I have a state machine which is coded like so: > > if rising_edge(CLK) then > case state is > when xyz => > OUT <= '1'; > state <= xyxyxy; > when xyxyxy => > OUT <= '0'; > etc > etc > etc > > > The problem is the output doesn't seem to happen in the state it should, > instead it seems to happen in the next state. So in the above example the > signal OUT is set to 1 in state xyxyxy. > > Does anyone have any idea on what I'm doing wrong? How can I make the > output change in the state? > > Thanks in advance. Simon, I almost always use two-process state machines (very simple example below). If I want a clocked output (say a d flip-flop) I use a flop external to the state machine and control it from the state machine. I have also controlled counters in a similar manner. This is a very flexible way of doing it at the cost of some added complexity in the code--not necessarily in the synthesized result. Charles -->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>> -- State Machine A clocking and initialization -->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>> a_clking : process( a_clk, clr_l, a_next_state ) begin if rising_edge( a_clk ) then if clr_l = '0' then a_pres_state <= a_state1; else a_pres_state <= a_next_state; end if; end if; end process a_clking; -->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>> -- State Machine A state transition and output control -->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>> -- ffa_q is the output of d flip-flop a -- d_ffa is the d input of d flip-flop a a_trans : process( a_pres_state, ffa_q, some_input ) begin case a_pres_state is --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% when a_state1 => --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% cycle_machine_b <= '0'; a_state_num <= 1; d_ffa <= 0; --clr d flop a a_next_state <= a_state2; --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% when a_state2 => --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% cycle_machine_b <= '0'; a_state_num <= 2; if some_input = '1' then d_ffa <= '1'; --set flop a a_next_state <= a_state3; else d_ffa <= '0'; --clr d flop a a_next_state <= a_state2; end if; --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% when a_state3 => --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% cycle_machine_b <= '0'; a_state_num <= 3; d_ffa <= ffa_q;--hold flop a a_next_state <= a_state4; --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% when a_state4 => --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% cycle_machine_b <= '0'; a_state_num <= 4; d_ffa <= ffa_q; --hold flop a a_next_state <= a_state5; --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% when a_state5 => --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% cycle_machine_b <= '1'; a_state_num <= 5; d_ffa <= '0'; --clr flop a a_next_state <= a_state1; --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% when others => --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% a_next_state <= a_state1; --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% end case; end process a_trans; |
|
|
|
#8 |
|
Posts: n/a
|
Hi,
Id like to add one possible reason, which was the lack of proper education in the old days. Pretty much everybody who was involved with HDL till about 10 years ago was self-taught. And while design sizes grew rapidly, the methodologies stayed the same, to put it shortly. But, I wouldn't give that much credit to the software people either, in my experience they have made gazillion more unforgivable errors with poor code than hardware guys ever will regards, juza "Jan Decaluwe" <> wrote in message news:... > Nicolas Matringe wrote: > > Mike Treseler a écrit: > > > >> > > [...] > > > >> > >> Well said. Process variables are the most logical > >> way to describe state information. > > > > > > Indeed. I like it very much. > > I wonder why nobody ever tought this to me... It was always the same old > > two processes scheme. > > Here's my take on possible reasons for that one: > > - lack of "software" talent in the hardware design community. > > Many hardware designers refuse to appreciate the full value > of nice code and powerful synthesis tools. They want to see > their registers, muxes and adders jumping right out of their code. > This sad attitude is called "hardware thinking" and is used > as an excuse to avoid having to understand what a synthesis tool > can do. > > The EDA vendors didn't help, as their software talent is > in tool development, not applications engineering. > > - bad influence of Verilog. > > The most popular HDL on the planet doesn't make the distinction > between variables and signals. Combined with the absence of a > decent delta cycle mechanism, the result is eternal confusion > about the semantics of "blocking" and "non-blocking" assignments, > to newbies and experts alike. > > A popular "solution" in the Verilog community is to simply ban the > discussed coding style altogether! (In Verilog speaky-speaky, > this would sound "you shouldn't mix blocking and non-blocking > assignments in the same always block.") > > Therefore, suppose you would code the example in Verilog and > post it to comp.lang.verilog as an example of good style. Here's > what might happen. You may be insulted to be a junior designer > without the slightest clue on hardware design. You may be > bombarded with links to award winning papers by Cliff Cummings > that will help you to overcome your bad habits. You may be urged > to take a training course ("Advanced Verilog Techniques > For Ex-VHDL Designers"). > > On the other hand, the chance of an enthusiastic reaction such > as yours, from someone that has seen the light, is very low, > I believe. Makes you wonder where the multimillion dollar > mistake exactly is. > > Regards, Jan > > -- > Jan Decaluwe - Resources bvba - http://jandecaluwe.com > Losbergenlaan 16, B-3010 Leuven, Belgium > Bored with EDA the way it is? Check this: > http://jandecaluwe.com/Tools/MyHDL/Overview.html > |
|
|
|
#9 |
|
Posts: n/a
|
jussi l wrote:
> Hi, > > Id like to add one possible reason, which was the lack of proper education > in the old days. Pretty much everybody who was involved with HDL till about > 10 years ago was self-taught. And while design sizes grew rapidly, the > methodologies stayed the same, to put it shortly. If that were the case, one could reasonably expect the situation to be better now. But it isn't. Most books, papers, methodolodogy guides and training courses are "hardware thinking" (in the bad sense) centric, and therefore quite boring and unimaginative. At least in the old days, there was some room for experimentation - a freedom that you may no longer have now (if you want the job). To verify/falsify this claim, try to provide me with a link to an educational reference that advocates the coding style that was proposed in this thread (using variables for process state). Then compare it with the number of references that advocate a coding style that would make the former one impossible. As my count stands at approximately 1 against (all - 1), I'll stick to my original 2 reasons for now. Regards, Jan -- Jan Decaluwe - Resources bvba - http://jandecaluwe.com Losbergenlaan 16, B-3010 Leuven, Belgium Bored with EDA the way it is? Check this: http://jandecaluwe.com/Tools/MyHDL/Overview.html |
|
|
|
#10 |
|
Junior Member
Join Date: Feb 2008
Posts: 2
|
While this method is giving me excellent results with the XST synthesizer, Modelsim doesn't seem to recognize the code as an FSM. This is ruining my RTL simulation and making it very difficult to debug this design. I have to add a test std_logic_vector and change its value in each state to get enough info for debug. (The FSM state vars don't show up.)
|
|
|
|
![]() |
| Thread Tools | Search this Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| combinational lock state machine | harikanth | General Help Related Topics | 0 | 04-06-2009 04:38 AM |
| Using BRAM in state machines | zoki111 | Hardware | 0 | 09-18-2007 08:38 AM |
| Judge: File-swapping tools are legal | Citizen Bob | DVD Video | 140 | 11-08-2006 05:42 PM |
| BUSH WILL LIKELY INSTALL A DRAFT | Jas | DVD Video | 165 | 10-20-2004 08:39 PM |
| Panasonic S25 DVD player w/o S-video output - will its replacement have S-video? | Mark | DVD Video | 1 | 02-11-2004 03:19 PM |