Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

VHDL and VERILOG FSM encoding

Status
Not open for further replies.

shaiko

Advanced Member level 5
Joined
Aug 20, 2011
Messages
2,644
Helped
303
Reputation
608
Reaction score
297
Trophy points
1,363
Activity points
18,302
Is it possible to control the encoding style (one-hot,gray,binary, etc...) of your FSM using your HDL code ?
 

The question refers to synthesis tool behaviour, you need to consult the manuals.

I can tell about Altera Quartus. If a FSM is recognized by the design compiler, it overrides the encoding in the state variable definition and uses either the default one state hot encoding or a specific user setting. User settings can be applied e.g. by synthesis attributes in HDL code.

The requirements for FSM recognition are discussed in the software manual, you can also refer to language templates.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
FvM,
You say:
it overrides the encoding in the state variable definition
What do you mean by overides?
What is the default for the state variables that's overwritten?
 

FvM,
You say:

What do you mean by overides?
What is the default for the state variables that's overwritten?

Most likely you'll either write a state machine using Binary Coded states in your HDL code or (more commonly) an enumerated data type, this is what gets overridden.

In actual synthesis however, you'll find One-Hot encoding used by the synthesis tool (by default). In Quartus for example try this - design a state machine, compile it, and then go to 'Netlist Viewers' under 'Tools', select 'State Machine Viewer'. It will show your state machine transitions at first. There's a tab near the bottom labeled 'Encoding', click on it, you'll see your FSM is actually One-Hot encoded.

Also see this for more info:
http://quartushelp.altera.com/11.1/mergedProjects/hdl/vhdl/vhdl_file_dir_enum_encoding.htm
 
Last edited:

Most likely you'll either write a state machine using Binary Coded states in your HDL code
How?
Please post an example...
 

Is it possible to control the encoding style (one-hot,gray,binary, etc...) of your FSM using your HDL code ?
There are 'not guaranteed to be portable' ways using attributes, consult the synthesis tool of choice for information.

A portable method to define it in VHDL is

Code:
type t_MYSTATES is(Idle, Run, Stop);
type encoding_array is array(t_MYSTATES) of std_logic_vector(2 downto 0);
constant encode : encoding_array := (Idle => "000", Run  => "010", Stop => "100");

Kevin Jennings
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
How?
Please post an example...


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
module SPORT_BUS(
            OSC_CLK,
            TSCLK0,         //4MHz DSP clk     
            TFS0,           //DSP stobe 
            DT0PRI,         //DSP Serial data input
            REC_DATA,       //8bit receive  data buffer
            RSCLK0,         //4MHz FPGA clk
            RFS0,           //FPGA storbe
            DR0PRI,         //FPGA Serail data output
            TR_DATA,        //8bit transmit data buffer
            RESET,          //global reset
            START,          //start tx
            NEW_REC,        //New data is ready
            READY
            );
 
 
input           OSC_CLK;
input           TSCLK0;              
input           TFS0;           
input           DT0PRI;
input           RESET;
input           START;         
input   [7:0]   TR_DATA;        
 
output          RSCLK0;         
output          RFS0;           
output          DR0PRI;
output          NEW_REC;
output  [7:0]   REC_DATA;
output          READY;
 
 
wire            OSC_CLK;
wire            TSCLK0;             
wire            TFS0;            
wire            DT0PRI;         
wire            RESET;      
wire            RSCLK0;         
wire            RFS0;           
wire            START;
wire            NEW_REC;         
wire    [7:0]   TR_DATA;     
 
 
reg     [7:0]   REC_DATA;
reg     [13:0]  state1;
reg     [13:0]  state2;
reg             DR0PRI;
reg             READY;
reg             tsclk0_sampled2;
reg             tsclk0_sampled;
 
//assign  RSCLK0  =   TSCLK0;
assign  RSCLK0  =   tsclk0_sampled;
//                        s
//                        t
//                        r--1hot--43210;
parameter   idle    = 14'b00000000000000;
parameter   tx1     = 14'b11000000000010;
parameter   tx2     = 14'b00100000000011;
parameter   tx3     = 14'b00010000000100;
parameter   tx4     = 14'b00001000000101;
parameter   tx5     = 14'b00000100000110;
parameter   tx6     = 14'b00000010000111;
parameter   tx7     = 14'b00000001001000;
parameter   tx8     = 14'b00000000101001;
 
parameter   rx_dly  = 14'b00000000010011;
parameter   rx1     = 14'b01000000001010;
parameter   rx2     = 14'b00100000001011;
parameter   rx3     = 14'b00010000001100;
parameter   rx4     = 14'b00001000001101;
parameter   rx5     = 14'b00000100001110;
parameter   rx6     = 14'b00000010001111;
parameter   rx7     = 14'b00000001010000;
parameter   rx8     = 14'b10000000110001;
 
always  @(posedge   OSC_CLK or negedge  RESET)
    if(!RESET)
        begin
            tsclk0_sampled  <=  1'h0;
            tsclk0_sampled2 <=  1'h0;
        end
    else
        begin
            tsclk0_sampled2 <=  TSCLK0;  
            tsclk0_sampled  <=  tsclk0_sampled2;  
        end
//RX SPORT section   
     
always @(negedge    /*TSCLK0*/tsclk0_sampled2 or negedge   RESET)
    if(!RESET)
        begin
            state2  <=  14'h0;
        end
    else
        begin
            case(state2)
                idle:
                        if(TFS0)
                            state2   <=  rx_dly;
                        else
                            begin
                                state2  <=  idle;
                            end
                            
                rx_dly: state2   <=  rx1;
                rx1:    state2   <=  rx2;
                rx2:    state2   <=  rx3;
                rx3:    state2   <=  rx4;
                rx4:    state2   <=  rx5;
                rx5:    state2   <=  rx6;
                rx6:    state2   <=  rx7;
                rx7:    state2   <=  rx8;
                rx8: begin
                          if(TFS0)
                            state2   <=  rx_dly;
                          else
                            state2   <=  idle;
                        end    
                default:  state2   <=  idle;
            endcase
        end
 
//TX SPORT section
 
always @(posedge    RSCLK0 or negedge   RESET)
    if(!RESET)
        begin
            state1  <=  14'h0;
            DR0PRI  <=  1'h0;
            READY   <=  1'h1;
        end
    else
        begin
            case(state1)
                idle:   begin
                            READY   <=  1'h1;
                            if(START)
                                begin
                                    state1   <=  tx1;
                                end
                            else
                                begin
                                    state1  <=  idle;
                                    DR0PRI  <=  1'h0;
                                end
                        end    
                tx1:    begin
                            READY   <=  1'h0;
                            state1  <=  tx2;
                            DR0PRI  <=  TR_DATA[7];
                        end
                tx2:    begin
                            state1   <=  tx3;
                            DR0PRI  <=  TR_DATA[6];
                        end
                tx3:    begin
                            state1   <=  tx4;
                            DR0PRI  <=  TR_DATA[5];
                        end
                tx4:    begin
                            state1   <=  tx5;
                            DR0PRI  <=  TR_DATA[4];
                        end
                tx5:    begin
                            state1   <=  tx6;
                            DR0PRI  <=  TR_DATA[3];
                        end
                tx6:    begin
                            state1   <=  tx7;
                            DR0PRI  <=  TR_DATA[2];
                        end
                tx7:    begin
                            state1   <=  tx8;
                            DR0PRI  <=  TR_DATA[1];
                        end
                tx8:    begin
                            DR0PRI  <=  TR_DATA[0];
                          /*if(START)
                            begin
                              state1   <=  tx1;
                            end
                          else
                            begin
                                state1  <=  idle;
                            end*/
                            state1  <=  idle;
                        end
                default:  state1   <=  idle;
            endcase
        end
 
 
assign  RFS0    =   state1[13];
assign  NEW_REC =   state2[13];  
 
// RX
 
    always  @(posedge   state2[12])
        begin
            REC_DATA[7]  <=  DT0PRI;
        end
    
    always  @(posedge   state2[11])
        begin
            REC_DATA[6]  <=  DT0PRI;
        end
    
    always  @(posedge   state2[10])
        begin
            REC_DATA[5]  <=  DT0PRI;
        end
    
    always  @(posedge   state2[9])
        begin
            REC_DATA[4]  <=  DT0PRI;
        end
    
    always  @(posedge   state2[8])
        begin
            REC_DATA[3]  <=  DT0PRI;
        end
    
    always  @(posedge   state2[7])
        begin
            REC_DATA[2]  <=  DT0PRI;
        end
    
    always  @(posedge   state2[6])
        begin
            REC_DATA[1]  <=  DT0PRI;
        end
    
    always  @(posedge   state2[5])
        begin
            REC_DATA[0]  <=  DT0PRI;
        end
        
endmodule



This one has binary coded + one-hit neatly mixed. You might find the code familiar. ;)
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
This one has binary coded + one-hit neatly mixed. You might find the code familiar. ;)
I fear the code is far from an instructive FSM example by many details. Referring to the present question, it's difficult to predict how the FSM encoding will be compiled by a synthesis tool. Altera Quartus e.g. doesn't recognize the design as state machine because the usage of individual state variable bits contradicts it's FSM scheme (e.g. assign RFS0 = state1[13];).

Of course the design works as a state machine, but the compiler skips any FSM related optimization features.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
I fear maybe only shaiko had a chance of getting the hint. ;)

See this thread to spot the similarities. ;)

But you are entirely correct that it's not the best FSM for instructive purposes. For instructive purposes these papers might be a bit better:

http://www.sunburst-design.com/papers/CummingsSNUG2000Boston_FSM.pdf
http://www.sunburst-design.com/papers/CummingsSNUG2003SJ_SystemVerilogFSM.pdf

Personally I like the 3 always block approach. Gives clean readable code.

As for "Is it possible to control the encoding style (one-hot,gray,binary, etc...) of your FSM using your HDL code ?" ... yes. That's generally in the user guide for your synthesis tool of choice, and usually includes some example code.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Is it possible to write an FSM in Verilog using only one "always" block ?
(the same way you would write a single process FSM in VHDL)
 

Yeah, you can do it all in one always block. I started out doing it that way, but these days I mostly use 3-always, and sometimes 2-always. Bit depending on the design. The all-in-one-always block tends to become unreadable for larger FSMs. And unreadable becomes hard to maintain. And hard to maintain becomes more prone to errors. And more prone to errors becomes spending time debugging FSMs instead of coding new modules.
 

mrflibble,

won't the above code yield a gated clock?

in this section:

Code:
    always  @(posedge   state2[12])
        begin
            REC_DATA[7]  <=  DT0PRI;
        end
    
    always  @(posedge   state2[11])
        begin
            REC_DATA[6]  <=  DT0PRI;
        end
    
    always  @(posedge   state2[10])
        begin
            REC_DATA[5]  <=  DT0PRI;
        end
    
    always  @(posedge   state2[9])
        begin
            REC_DATA[4]  <=  DT0PRI;
        end
    
    always  @(posedge   state2[8])
        begin
            REC_DATA[3]  <=  DT0PRI;
        end
    
    always  @(posedge   state2[7])
        begin
            REC_DATA[2]  <=  DT0PRI;
        end
    
    always  @(posedge   state2[6])
        begin
            REC_DATA[1]  <=  DT0PRI;
        end
    
    always  @(posedge   state2[5])
        begin
            REC_DATA[0]  <=  DT0PRI;
        end

- - - Updated - - -
 

For reply see other thread. :p

Short version: I don't think it does, not sure. Either way, I think the code is not the best of ideas.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
won't the above code yield a gated clock?
It's involving a ripple clock (register output used as clock signal), often bringing up timing problems. The code looks like being writting without much understanding of synchronous design methods.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top