How to avoid glitches in the output of the state machine FSM?

write in front

        本文参考自《Coding And Scripting Techniques For FSM Designs WithSynthesis-Optimized, Glitch-Free Outputs》--Clifford E. Cummings。

        It mainly describes how to avoid FSM output glitches. In the text, the black text is the content, and the light blue font is my long-winded text. If you need the original article in English, you can comment and leave an email to me.

        Suggested reading first: FPGA State Machines (One-Segment, Two-Segment, Three-Segment), Moore, and Mealy


1.0 Introduction 

        A state machine design using a hardware description language (HDL) can take many forms such as Verilog, so are all forms good for synthesis? This article describes some common coding styles and highlights two coding styles that use register outputs and are well suited for general-purpose synthesis techniques. 

        This article will briefly describe the coding style for generating combinatorial logic outputs, then elaborate on the coding style for generating register outputs, and describe why the coding style for register outputs generally favors synthesis strategies. 

2.0 Basic FSM Structure 

        A typical block diagram of a finite state machine (FSM) is shown in Figure 1. 

  • A Moore state machine is a state machine whose output is simply a function of the current state. 
  • A Mealy state machine is a state machine whose output is a function of the current state and the input. 

        Both Moore and Mealy FSM have been successfully implemented in digital design. How to generate output for these state machines is an interesting topic. Outputs are sometimes generated by combinatorial logic based on comparisons to a set of states, while other times outputs can be derived directly from individual state bits.

        The code in Example 1 uses the generic, efficient Verilog coding style to implement the state diagram shown in Figure 2.

 

        This coding style is sometimes referred to as the double always-block state machine coding style with continuously assigned outputs. The first always block in this example is used to generate the sequential state register, the second always block is used to generate the next state logic of the combination, and the continuous assignment is used to generate the combinational output logic.

        The code in Example 2 uses the same basic logic at synthesis as in Example 1, but the generation of the output is done by moving the output equation into the same always block used to generate the combinatorial next-state logic. This is a commonly used double always block coding style.

        The combined output generated by these two coding styles (Example 1 and Example 2) has two major drawbacks: 

  1. Combined outputs may glitch between states. 
  2. The combined output consumes a fraction of the total clock cycles available to the logic blocks driven by the FSM outputs. 

        When using combinational logic to generate block outputs, the receiving block has less time to pass the signal through the input and additional combinational logic before a valid clock edge arrives. 

        This code style can be regarded as a three-stage state machine, but the output is directly assigned using the assign statement, and all its outputs are combinational logic. As we all know, the biggest problem with combinational logic as the output is that it is prone to glitches, which leads to system errors. But does this method often appear in multiple situations where state machines are used to solve problems? In practical use, this method is not recommended. A three-stage state machine with sequential logic outputs is generally used to remove glitches and improve timing.

3.0 Comprehensive division 

        A common and proven technique for partitioning a design for synthesis is to partition the design so that all outputs are registered and all combinational logic is at the inputs of the block, as shown in Figure 3. This is also sometimes referred to as "cloud-register" partitioning. 

         

        A variation on the same synthesis technique is to partition the design so that all combinational logic resides on the inputs or between register stages within the module, as shown in Figure 4.

        This technique is important not because it necessarily makes the design better, but because it greatly simplifies the task of constrained synthesis design. 

        Designs can and have been successfully completed using combinational logic on the inputs and outputs of block partitions, but such designs complicate the task of constraining the design to meet timing requirements. 

        As shown in Figure 5, if a design requires a clock period of 10ns, and if the output combinational logic of block A consumes 3.5ns, then the inputs of blocks C and D and some inputs of block E must be limited to use only 6.5ns (including register setup time).

        If block B consumes 5ns in the output combinational logic, the other inputs of block E must be limited to use only 5ns (including the setup time of the registers).

        For this simple 5-module design, the task of making these constraints is not too difficult, but you can imagine having to constrain many inputs on tens or hundreds of modules in a larger design and make sure all constraints are It's a lot of work to get it right. This is also one of the reasons for registering the output of the module.

        In timing analysis and constraints, we know to meet the setup and hold times of the registers. If there is too long combinational logic at the input of the register (that is, the number of logic stages is too large and the combinational logic delay is long), the setup time slack will be compressed, resulting in tight timing. Adding registers at the output of combinational logic is a common timing optimization method. It can cut off the long combinational logic and divide it into several segments, so as to deliver the scarce slack to each link, but it will also delay the output of the system ( latency) becomes larger. In addition, adding register outputs can also effectively filter out glitches.

4.0 Comprehensive time budget 

        In the paper titled "Evolvable Makefiles and Scripts for Synthesis", an ingenious time budgeting technique is described for synthesizing many modules by constraining inputs and outputs to sequential modules and applying time budget allocation to purely combinatorial modules . A technique similar to that described by Ekstrandh and Bell becomes easier to implement if the pure combinational logic blocks are removed and the outputs of all timing blocks are registered. 

        One of the main arguments against registered outputs is that the inputs of multiple receiving modules may require redundant combinatorial logic. Conversely, moving combinatorial logic from some block outputs to receiving blocks' inputs may help come up with a different, more optimal design partition. 

        The best reason to move combinatorial logic out of the block output is that it significantly reduces synthesis scripting, making it easier to meet overall timing constraints. Tight constraints on the output combinatorial logic in the driving block and strict timing constraints on the input combinatorial logic in the receiving block generally do not result in the same efficient logic, if all combinatorial logic can be optimized with larger overall timing constraints, then The same valid logic is deduced.

5.0 Registering FSM Outputs 

        Two good ways to code the FSM so that all module outputs are registered:

  1. Generate and register "next- outputs "
  2. Encode the state variable so that each output is one of the encoded bits that register the state variable

         This method is the best three-stage state machine method, register output, synchronous and glitch-free, which is conducive to timing closure.

5.1 FSM of three always blocks ( three-segment state machine )

        The first method commonly used to register FSM outputs is to write two always block FSMs, the same as in example 1, but instead of using continuous assignment to generate outputs, a third block is coded as a sequential always block to register "next outputs" , as shown in Example 3. 

        This approach requires careful coding, as this style forces the engineer to examine the current state and inputs to determine what the "next outputs" will be. This approach is a bit error prone, but works fine if the output is encoded correctly.

        The block diagram in Figure 6 shows two sequential logic blocks and one combinational logic block generated by three always blocks. 

5.2 Output encoding FSM 

        A second interesting way to register the FSM output is to choose a state encoding that forces the output to be driven by the individual status register bits, as shown in the block diagram of Figure 7.

        The following steps outline a structured approach to encoding the output as part of the state encoding: 

        1. Count the number of outputs (x) and the number of states (y) in the state machine and make a table with y+1 rows and x+1 columns. 

        2. Starting from the second row in the left column, all FSM states are listed, moving down the column for each state in the state machine. This will populate the left column except the upper left column cells.

 

        3. Starting from the first row and second column, moving to the right, put each FSM output column as a separate column heading.

        4. Place a "1" in each output column where the listed state's output is high and a "0" in each output column where the listed state's output is low. 

        

 

        5. After filling the entire table, search for more output patterns that are the same in more than one state. If there are no repeating patterns, use the output pattern from the table as the state encoding. If all encodings are unique, no additional status bits are needed, and each status bit represents not only part of the status encoding, but what will become the register output bit. 

        Note: FSM input does not affect state encoding. Only the number of states and outputs affect the state encoding. 

        In general, the output mode will not be unique to any one state and requires the following additional steps: 

        6. Circle the repeated output patterns in the table as shown in Table 1. 

        7. If there are two identical output modes, an extra status bit is required to create a unique status encoding. If there are three or four identical output patterns, two additional status bits are required to create a unique status encoding. If there are five to eight identical output patterns, three additional status bits are required to create unique status codes, etc.

        8. Add a blank column between the state name column and the first output column and label this column as "x0". Add another column for each additional desired status bit, label each column as "x1", "x2", etc.

 

 

        Pad the added columns with all zeros except the circled redundant coded row. Add binary codes to extra columns of redundant code rows to create unique state codes, as shown in Figure 10.

        The state codes in Table 3 will now be used for Verilog parameter assignments to define each state code. 

        Now that the output has been incorporated into the state encoding, one or more consecutive assignment statements can directly drive the output, where the actual state bits are used to drive the output. Since no additional glue logic is required to drive the output, the output will now be glitch-free. 

        The output of a Verilog state machine can now be easily encoded by bit selection assignments from the state vector to each output, or by concatenating all outputs together into one continuous assignment and assigning all valid state bits to the outputs, as shown in in example 4. If additional state bits are required to create a unique state encoding, the output bits will be the LSB of the state vector. 

        This method seems to say a lot, but in fact, if you look closely, you will know that it is very simple: directly connect the output to the reg variable state using assign. Since multiple states are set according to the number of redundancy, there is no combinatorial operation on the output logic. for example: 

        The rd output in the above figure is both 1 in the state READ and the state DLY, so there must be a combinational logic-OR operation when using assgin directly.

        After using the above method, there are two redundant states: READ, DLY, then the reg variable state is expanded by 1 bit to represent, so that the two redundant variables can be directly distinguished without using combinational logic. The essence of this method is to encode the state and encode the output information into the state variable. I personally feel that this method is not very practical, it is better to use one-hot code.

6.0 Mealy output

        Asynchronous Mealy output violates the comprehensive guidelines for dividing the design into "cloud-register" groupings. An asynchronous Mealy output is the output of a function of the current state and one or more inputs, which requires combinational logic to be placed on the Mealy output
, following the registers to form a combinational logic cloud, as shown in the block diagram of Figure 11 for the FSM module. 

 

        It is often feasible to move the asynchronous Mealy output from the FSM module to the input or inputs of one or more modules (such as modules C and D shown in Figure 12) that will be driven by the Mealy output. 

 

        Transferring the Mealy logic from the output of the FSM module to the input of the driver module may result in extra logic being inferred because logic must be taken from a single output "cloud" and added to possibly multiple input "clouds". Small unwanted increases due to adding redundant logic can often be offset by massive simplification of design effort and synthesis scripts. 

7.0 Conclusion 

  •  Dividing the design so that there is no combinational logic on the output of the FSM significantly simplifies the task of synthesizing a multi-block design. 

  • Encoding the FSM with registered outputs eliminates combinatorial output logic. 

  • Encoding the FSM with a registered output ensures that the output is glitch-free. 

  • The output encoding FSM style is an efficient technique for encoding the FSM to drive the registered output directly from the status register bits.

Guess you like

Origin blog.csdn.net/wuzhikaidetb/article/details/124263245