首页 > 其他分享 >有限状态机

有限状态机

时间:2023-01-17 15:11:48浏览次数:46  
标签:curr 有限 logic next 状态机 state always output

Abstract

FSM在数字电路中非常重要,借由FSM,数字电路也能循序地执行起算法。本文将详细讨论各种FSM coding style的优缺点,并归纳出推荐的coding style。

1.Moore FSM的架构

2.Moore FSM各种coding style比较

3.Mealy FSM架构

4.Mealy FSM各种coding style比较

5.实践上推荐的coding style

6.Conclusion

若要让数字电路也能循序地执行算法,最简单的方式可以使用DFF产生counter,根据counter的值去定要执行不同的程式,如此也能达到使数字电路循序执行算法的目的,不过这种方式仅应用很简单的演算法,在一般規模的演算法若使用counter方式,程式代码不容易维护,所以实际上会使用FSM方式来实现演算法。

其实FSM方式也是利用counter來实现,所谓的counter,并不是只有counter = counter + 1才算是counter,FSM的state register就是广义的counter,只是这种counter不是一直加1而已,而是有自己的递增规则。FSM只是提供了一种较为高容易维护的方式来实现演算法。

一般在写FSM时,会以Moore FSM为主,所以先讨论Moore。由上图可知,Moore FSM内部由3个block所构成:Next state logic,State register与Output logic。

Next state logic:纯粹的组合逻辑,以整个module的input与目前的state为输入,目的在产生下一个state值存入state register。

State register:由D-FF所构成,将Next state logic所产生的state存入register。

Output logic:纯粹的组合逻辑,根据目前的state产生整个module的output。

所以可以发现,整个Moore FSM事实上是由2块的组合逻辑与1块D-FF所构成,我们常听到所谓的一段式、二段式与三段式FSM,事实上就是由这3个block排列组合而成。

Moore FSM各种coding style比较

为了要比较各种coding style,在此举一个简单的例子,若input w_i是连续2个clk为high,则output会在下1个clk产生周期为1 T的high pulse,timing diagram如上图所示。

因此设计了Moore FSM,state diagram如上图所示,接下來要做的就是用各种coding style来实现这个Moore FSM。

1.使用3个always (三段式)

//simple_fsm_moore_3_always_best.v

module simple_fsm (clk, rst_n, w_i, z_o );

input clk;

input rst_n;

input w_i;

output z_o;

parameter IDLE = 2'b00;

parameter S0 = 2'b01;

parameter S1 = 2'b10;

reg [1:0] curr_state;

reg [1:0] next_state;

reg z_o;
// state reg
always@(posedge clk or negedge rst_n)
if (~rst_n) curr_state <= IDLE;
else curr_state <= next_state;

// next state logic
always@(*)
case (curr_state)
IDLE : if (w_i) next_state = S0;
else next_state = IDLE;
S0 : if (w_i) next_state = S1;
else next_state = IDLE;
S1 : if (w_i) next_state = S1;
else next_state = IDLE;
default : next_state = IDLE;
endcase

// output logic
always@(*)
case (curr_state)
IDLE : z_o = 1'b0;
S0 : z_o = 1'b0;
S1 : z_o = 1'b1;
default : z_o = 1'b0;
endcase

endmodule

使用1个always描述next state logic,因为是纯粹组合逻辑,所以使用阻塞赋值。

根据Moore FSM架构图所示,next state logic的结果与input与目前state有关,所以先用case对目前state做一次大分类,然后每个state再根据input做if判断。

// next state logic

always@(*)

case (curr_state)

IDLE : if (w_i) next_state = S0;

else next_state = IDLE;

S0 : if (w_i) next_state = S1;

else next_state = IDLE;

S1 : if (w_i) next_state = S1;

else next_state = IDLE;

default : next_state = IDLE;

endcase

使用1个always描述state register,因为是DFF且含clk,所以使用非阻塞赋值。

由于state register块并不包含任何逻辑,所以不会因为不同FSM而有不同写法,不同FSM只会改变next state logic与output logic的写法。

// state reg

always@(posedge clk or negedge rst_n)

if (~rst_n) curr_state <= IDLE;

else curr_state <= next_state;

使用1个always描述output logic,因为是纯粹组合逻辑,所以使用阻塞赋值。

根据Moore FSM架构图所示,output logic的结果只与目前state有关,所以只需用case对state做一次分类即可。

// output logic

always@(*)

case (curr_state)

IDLE : z_o = 1'b0;

S0 : z_o = 1'b0;

S1 : z_o = 1'b1;

default : z_o = 1'b0;

endcase

next_state logic是组合逻辑赋值,所以在输入变化时,跟着变化,不会有有一个时钟周期的延迟。同时在下一个时钟沿到来时,把次态逻辑赋值给当前状态,次态逻辑相当于一个对现态逻辑的保存作用。

//next_state的产生是组合逻辑,当第二个w_i的高电平到来时,next_state马上改变状态,但需要等到下一个时钟沿才能赋值给当前状态,由于输出为组合逻辑,直接用当前状态判断,刚好满足在下一个时钟周期输出为高电平

使用3个always写法有这些优点:

1.可忠实地反映出原本的Moore FSM硬件架构
2.可轻易地将state diagram改用Verilog表示
3.将Next state logic与output logic分开,可降低code的复杂度,便于日后维护。

module simple_fsm_tb;

reg clk = 1'b1;

reg rst_n = 1'b1;

reg w_i = 1'b0;

wire z_o;

// clk

always #10 clk = ~clk;

event after_rst;

// rst_n

initial begin

#6; // 6ns

rst_n = 1'b0;

#30; // 36ns

rst_n = 1'b1;

->after_rst;

end

// w_i

initial begin

@(after_rst);

repeat(2)

@(posedge clk); // 60ns

w_i <= 1'b1;

@(posedge clk); // 80 ns

w_i <= 1'b0;

@(posedge clk); // 100 ns

w_i <= 1'b1;

repeat(2)@(posedge clk); // 140 ns

w_i <= 1'b0;

@(posedge clk); // 160 ns

w_i <= 1'b1;

repeat(3)@(posedge clk); // 220 ns

w_i <= 1'b0;

end

initial begin

$fsdbDumpfile("simple_fsm.fsdb");

$fsdbDumpvars(0, simple_fsm_tb);

end

simple_fsm u_simple_fsm (

.clk (clk),

.rst_n (rst_n),

.w_i (w_i),

.z_o (z_o)

);

endmodule

3个always 是一个推荐的写法

2.使用2个always (两段式)

由于要使用2个always去描述3个block,根据排列组合原理,C3取2,共有3种可能,我个一个一个讨论。

2.1 state register与next state logic合一

//Description : 2 always block for moore fsm (GOOD)

module simple_fsm (

clk,

rst_n,

w_i,

z_o

);

input clk;

input rst_n;

input w_i;

output z_o;

parameter IDLE = 2'b00;

parameter S0 = 2'b01;

parameter S1 = 2'b10;

reg [1:0] curr_state;

reg z_o;

// state reg + next state logic

always@(posedge clk or negedge rst_n)

if (~rst_n) curr_state <= IDLE;

else

case (curr_state)

IDLE : if (w_i) curr_state <= S0;

else curr_state <= IDLE;

S0 : if (w_i) curr_state <= S1;

else curr_state <= IDLE;

S1 : if (w_i) curr_state <= S1;

else curr_state <= IDLE;

default : curr_state <= IDLE;

endcase

 

// output logic

always@(*)

case (curr_state)

IDLE : z_o = 1'b0;

S0 : z_o = 1'b0;

S1 : z_o = 1'b1;

default : z_o = 1'b0;

endcase

endmodule

//将state register与next state logic合起來用1个always去描述,虽然next state logic是纯粹的组合逻辑,为了迁就于带clk的state register,且要用一个always描述,就必须改用非阻塞赋值。

//由于state register与next state logic合一,所以可以少宣告next_state reg,不过这并不会影响合成结果,只是可以少打个字而已。

//因为next state logic由input与state所构成,所以先用case对state做一次大分类,然后每个state再根据input做if判断。

// state reg + next state logic

always@(posedge clk or negedge rst_n)

if (~rst_n) curr_state <= IDLE;

else

case (curr_state)

IDLE : if (w_i) curr_state <= S0;

else curr_state <= IDLE;

S0 : if (w_i) curr_state <= S1;

else curr_state <= IDLE;

S1 : if (w_i) curr_state <= S1;

else curr_state <= IDLE;

default : curr_state <= IDLE;

endcase

使用1个always描述output logic,因为是纯粹组合逻辑,所以使用阻塞赋值。

根据Moore FSM架构图所示,output logic的结果只与目前state有关,所以只需用case对state做一次分类即可。

// output logic

always@(*)

case (curr_state)

IDLE : z_o = 1'b0;

S0 : z_o = 1'b0;

S1 : z_o = 1'b1;

default : z_o = 1'b0;

endcase

使用2个always (state register与next state logic合一)写法有以下优点:

1.代码较3个always写法精简

2.可轻易地将state diagram改用Verilog表示

3.因为state register原本代码就不多,将next state logic与state register合一后,next state logic仍与output logic分开,因此不会增加code的复杂度,便于日后维护。

2个always (state register与next state logic合一)也是一个推荐的写法。

接下来要讨论的都是不推荐的写法,主要目的是了解为什么不推荐的原因。

2.2 state register与output logic合一

// state reg + output logic

always@(posedge clk or negedge rst_n)

if (~rst_n) {curr_state, z_o} <= {IDLE, 1'b0};

else begin

curr_state <= next_state;

 

case (next_state)

IDLE : z_o <= 1'b0;

S0 : z_o <= 1'b0;

S1 : z_o <= 1'b1;

default : z_o <= 1'b0;

endcase

将state register与output logic合起来用1个always去描述,虽然output logic是纯粹的组合逻辑,为了迁就于带clk的state register,且要用一个always描述,就必須改用非阻塞赋值。

因为output logic只与state有关,所以只用case对state做一次分类即可。

这种写法最大的问题是:output logic必须用next_state去判断!!

依照Moore FSM的架构图得知,output logic只与目前state有关,之前的这种FSM写法,output logic也是由目前state去判断,为什么这种写法法要靠next_state去判断呢?

主要原因是根据Moore FSM的定义,output logic只与目前state有关,且是个纯粹的組组合逻辑,但目前强迫将state register与output logic放在同一个always,迫使output logic必须使用非阻塞赋值的方式呈现,也就是若output logic仍然使用目前state去做判断,则output logic会多delay 1个clk,为了让output logic结果正常,只好提前1个clk做判断,也就是提前到next_state去做判断。

所以当我们从state diagram换成Verilog表示时,若使用2个always,且是state register与output logic合一时,必須很小心要使用next_state去做output logic判断,因为这个地方很不直观,很容易出错,所以不推荐这种写法。

// next state logic

always@(*)

case (curr_state)

IDLE : if (w_i) next_state = S0;

else next_state = IDLE;

S0 : if (w_i) next_state = S1;

else next_state = IDLE;

S1 : if (w_i) next_state = S1;

else next_state = IDLE;

default : next_state = IDLE;

endcase

使用1个always描述next state logic,因为是纯粹组合逻辑,所以使用阻塞赋值。

根据Moore FSM架构图所示,next state logic的结果与input与目前state有关,所以先用case对目前state做一次大分类,然后每个state再根据input做if判断。

使用2个always (state register与output logic合一)写法的缺点:

当使用1个always去描述state register与output logic时,output logic必须使用next_state做判断,而非用目前state判断,由于写法不直观,一不小心很容易弄错。

不推荐2个always (state register与output logic合一)写法。

或许,在实践上却常看到state register与output logic合一的写法,为什么不会出问题?那是因为尽管是用Moore FSM,我们为了timing更好,常会在output时多敲一个DFF,让Output Logic的组合逻辑不要与其他module的input的组合逻辑合并,避免造成critical path,假如是这种需求,state register与output logic合一后,可以直接判断curr_state,不用提早一個clk判断next_state。

2.3 next state logic与output logic合一

// state reg

always@(posedge clk or negedge rst_n)

if (~rst_n) curr_state <= IDLE;

else curr_state <= next_state;

使用1个always描述state register,因为是DFF且含clk,所以使用非阻塞赋值。

由于state register并不包含任何逻辑,所以不会因为不同FSM而有不同写法,不同FSM只会改变next state logic与output logic的写法。

// next state logic + output logic

always@(*)

case (curr_state)

IDLE : if (w_i) {next_state, z_o} = {S0 , 1'b0};

else {next_state, z_o} = {IDLE, 1'b0};

S0 : if (w_i) {next_state, z_o} = {S1 , 1'b0};

else {next_state, z_o} = {IDLE, 1'b0};

S1 : if (w_i) {next_state, z_o} = {S1 , 1'b1}; // always output 1'b1

else {next_state, z_o} = {IDLE, 1'b1}; // always output 1'b1

default : {next_state, z_o} = {IDLE, 1'b0};

endcase

将next state logic与output logic使用同一个always去描述,由于next state logic与output logic都是纯粹的组合逻辑,所以使用阻塞赋值描述沒有问题。

由于next state logic与input与目前state有关,但output logic却只与目前state有关,因为都是先用目前state做case判断,然后再对input做if判断,所以会出現output两次都出现1的情形,起因于output logic只与目前state有关,与input无关,固任何input都会出现1。

使用2个always (next state logic与output logic合一)写法的缺点:

1.将next state logic与output logic合一只会增加code的复杂度,日后维护会更加困难

2.很类似Mealy FSM写法,容易让人误以为是Mealy FSM。

不推荐2个always (next state logic与output logic合一)写法。

3.使用1个always (一段式)

always@(posedge clk or negedge rst_n)

if (~rst_n) {curr_state, z_o} <= {IDLE, 1'b0};

else

case (curr_state)

IDLE : if (w_i) {curr_state, z_o} <= {S0, 1'b0};

else {curr_state, z_o} <= {IDLE, 1'b0};

S0 : if (w_i) {curr_state, z_o} <= {S1, 1'b1}; //?

else {curr_state, z_o} <= {IDLE, 1'b0};

S1 : if (w_i) {curr_state, z_o} <= {S1, 1'b1};

else {curr_state, z_o} <= {IDLE, 1'b0}; //?

default : {curr_state, z_o} <= {IDLE, 1'b0};

endcase

使用1个always同时描述next state logic、state register与output logic,虽然next state logic与output logic是纯粹的组合逻辑,但为了迁就于带clk的state register,所以必须使用非阻塞赋值。

根据之前的经验,由于Moore FSM的output logic只与目前state有关,且是纯粹的组合逻辑,若硬要与state register用同一个always去描述,判断上会出现一些问题,需提早1个clk用next state判断(在state register与output logic合一时曾经用过)。

在1个always内,next_state也省了,所以在35行

S0 : if (w_i) {curr_state, z_o} <= {S1, 1'b1};

当目前state为S0且输入为1'b1时,output必須提前为1,因为这是在非阻塞赋值内!!

使用1个always写法的缺点:

1.因为使用nonblocking去描述output logic,所以要提早1個clk判断,要特別小心处理,一不小心很容易弄错

2.1个always内同时包含next state logic与output logic,会增加code的复杂度,日后维护更加困难。

Mealy FSM架构

谈完了Moore FSM,接下來谈Mealy FSM,与Moore FSM的差別只在于Moore FSM的output logic只由目前state決定,但是Mealy FSM可由目前state与input共同决定。

Mealy FSM各种coding style比较

将之前的例子用Mealy FSM重新改写,原本在Moore FSM下,若input w_i为连续2个clk为high,则output会在下1个clk产生生周期为1 T的high pulse,若改用Mealy FSM,则output会提早1个clk出现,如上图所示。

原本Moore FSM需要3个state,若改用Mealy FSM后,会只剩下2个state,接下來要用各种coding style来实现Mealy FSM。

3.使用3个always (三段式)

// state reg

always@(posedge clk or negedge rst_n)

if (~rst_n) curr_state <= IDLE;

else curr_state <= next_state;

使用1个always描述state register。

// next state logic

always@(*)

case (curr_state)

IDLE : if (w_i) next_state = S0;

else next_state = IDLE;

S0 : if (w_i) next_state = S0;

else next_state = IDLE;

default : next_state = IDLE;

endcase

使用1个always描述next state logic。

// output logic

always@(*)

case (curr_state)

IDLE : if (w_i) z = 1'b0;

else z = 1'b0;

S0 : if (w_i) z = 1'b1;

else z = 1'b0;

default : z = 1'b0;

endcase

使用1个always描述output logic。

以上3个always写法与Moore FSM的3个always并无差别,基本上只要state diagram画的出来,就能等效地用Verilog描述出來。

// mealy output to delay 1 clk for moore

always@(posedge clk or negedge rst_n)

if (~rst_n) z_o <= 1'b0;

else z_o <= z;

之前提到使用Mealy FSM会少Moore FSM 1个state,且output会早Moore FSM 1个clk,所以最后特別将output在敲一级delay 1个clk,这样Mealy FSM就会完全与Moore FSM一样。

使用3个always写法有这些优点:

1.可忠实地反映出原本的Mealy FSM硬件架构

2.可轻易地将state diagram改用Verilog表示

3.将Next state logic与output logic分开,可降低code的复杂度,便于日后维护

3个always是一个推荐的写法。

4.使用2个always (两段式)

由于要使用2个always去描述3个block,根据排列组合原理,C3取2,共有3种可能,我们一个一个讨论。

4.1 state register与next state logic合一

// state reg + next state logic

always@(posedge clk or negedge rst_n)

if (~rst_n) curr_state <= IDLE;

else

case (curr_state)

IDLE : if (w_i) curr_state <= S0;

else curr_state <= IDLE;

S0 : if (w_i) curr_state <= S0;

else curr_state <= IDLE;

default : curr_state <= IDLE;

endcase

使用1个always同时描述state register与next state logic。

// output logic

always@(*)

case (curr_state)

IDLE : if (w_i) z = 1'b0;

else z = 1'b0;

S0 : if (w_i) z = 1'b1;

else z = 1'b0;

default : z = 1'b0;

endcase

使用1个always描述output logic。

以上2个always写法(state register与next state logic合一)与Moore FSM的2個always写法(state register与next state logic合一)并无差别,基本上只要state diagram画的出來,就能等效地用Verilog描述出来。

// mealy output to delay 1 clk for moore

always@(posedge clk or negedge rst_n)

if (~rst_n) z_o <= 1'b0;

else z_o <= z;

之前提到使用Mealy FSM会少Moore FSM 1个state,且output会早Moore FSM 1个clk,所以最后特別将output在敲一级delay 1个clk,这样Mealy FSM就会完全与Moore FSM一样。

使用2个always (state register与next state logic合一)写法有以下优点:

1.代码较3个always写法精简

2.可轻易地将state diagram改用Verilog表示

3.因为state register原本代码就不多,将next state logic与state register合一后,next state logic仍与output logic分开,因此不会增加code的复杂度,便于日后维护

2个always (state register與next state logic合一)也是一个推荐的写法。

接下来要讨论的都是不推荐的写法,主要目的是了解为什么不推荐的原因。

4.2 state register与output logic合一

虽然理论上可以用1个always同时描述state register与output logic,但实际上做不到,因为Mealy FSM的output logic是目前state与input的纯粹组合逻辑,与state register合一后,就必须使用非阻塞赋值描述,之前Moore FSM还可以提前一个state去做判断,但Mealy FSM还有input,该如何提前1个clk去判断input呢?

2个always (state register与output logic合一)无法描述Mealy FSM。

4.3 next state logic与output logic合一

// state reg

always@(posedge clk or negedge rst_n)

if (~rst_n) curr_state <= IDLE;

else curr_state <= next_state;

使用1个always描述state register。

// next state logic + output logic

always@(*)

case (curr_state)

IDLE : if (w_i) {next_state, z} = {S0 , 1'b0};

else {next_state, z} = {IDLE, 1'b0};

S0 : if (w_i) {next_state, z} = {S0 , 1'b1};

else {next_state, z} = {IDLE, 1'b0};

default : {next_state, z} = {IDLE, 1'b0};

endcase

使用1个always同时描述next state logic与output logic,因为两者都是纯粹的組组合逻辑,所以使用blocking。

// mealy output to delay 1 clk for moore

always@(posedge clk or negedge rst_n)

if (~rst_n) z_o <= 1'b0;

else z_o <= z;

之前提到使用Mealy FSM会少Moore FSM 1个state,且output会早Moore FSM 1个clk,所以最后特別将output在敲一级delay 1个clk,这样Mealy FSM就会完全与Moore FSM一样

使用2个always (next state logic與output logic合一)写法的缺点:

将next state logic与output logic合一只会增加code的复杂度,日后维护会更加困难

不推荐2个always (next state logic与output logic合一)写法。

5.使用1个always (一段式)

fsm16

理论上存在使用1个always同时描述next state logic、state register与output logic,但实际上做不到,理由与2个always (state register与output logic合一)的理由一样,1个always必须使用nonblocking描述,而Mealy FSM的output logic是目前state与input的组合逻辑,我们无法提前1个clk去判断input,所以无法使用1个always去描述。

1个always 无法描述Mealy FSM。

只要output logic使用nonblocking去描述,就无法实现Mealy FSM output。

6实际上推荐的coding style

如之前所述,实际上为了timing更好,常在Moore FSM的output logic再多敲一级,以下为推荐的coding style:

fsm_n_00

6.1 使用2个always (两段式)

fsm_n_01

// state reg + next state logic

always@(posedge clk or negedge rst_n)

if (~rst_n) curr_state <= IDLE;

else

case (curr_state)

IDLE : if (w_i) curr_state <= S0;

else curr_state <= IDLE;

S0 : if (w_i) curr_state <= S1;

else curr_state <= IDLE;

S1 : if (w_i) curr_state <= S1;

else curr_state <= IDLE;

default : curr_state <= IDLE;

endcase

使用2个always,且state register与next state logic合一,只要判断curr_state即可,不用担心是否要提早1个clk判断。

// output logic

always@(posedge clk or negedge rst_n)

if (~rst_n)

z_o <= 1'b0;

else

case (curr_state)

IDLE : z_o <= 1'b0;

S0 : z_o <= 1'b0;

S1 : z_o <= 1'b1;

default : z_o <= 1'b0;

endcase

output logic也敲clk,只要判断curr_state即可,不用担心是否要提早1个clk判断。

6.2 使用3个always (三段式)

// state reg
always@(posedge clk or negedge rst_n)
if (~rst_n) curr_state <= IDLE;
else curr_state <= next_state;

使用1个always描述state register。

// next state logic

always@(*)

case (curr_state)

IDLE : if (w_i) next_state = S0;

else next_state = IDLE;

S0 : if (w_i) next_state = S1;

else next_state = IDLE;

S1 : if (w_i) next_state = S1;

else next_state = IDLE;

default : next_state = IDLE;

endcase

使用1个always描述next state logic,为纯粹组合逻辑,所以使用阻塞赋值。

// output logic

always@(posedge clk or negedge rst_n)

if (~rst_n) z_o <= 1'b0;

else

case (curr_state)

IDLE : z_o <= 1'b0;

S0 : z_o <= 1'b0;

S1 : z_o <= 1'b1;

default : z_o <= 1'b0;

endcase

使用1个always描述output logic,因为output logic也敲clk,只要判断curr_state即可,不用担心是否要提早1个clk判断。

看到这里,或许奇怪:『为了timing好,多敲一级会多delay一个clk,若我output logic提前1个clk用next_state判断,不就既可有较好的timing,也不会多delay一个clk?』

fsm_n_03

6.3 使用3个always (三段式)

fsm_n_05

// output logic

always@(posedge clk or negedge rst_n)

if (~rst_n) z_o <= 1'b0;

else

case (next_state)

IDLE : z_o <= 1'b0;

S0 : z_o <= 1'b0;

S1 : z_o <= 1'b1;

default : z_o <= 1'b0;

endcase

使用1个always去描述output logic,重点是,使用next_state去判断,因此可以提早一个clk,这样无论是在Simulator或者经过Synthesizer合成后的结果都会一样,而且既可在output敲个D flip-flop,也不会多delay一个clk。

不过这种写法也不是沒有缺点,由于next_state本身是一个纯粹的的组合逻辑,拿来当output logic的判断,timing会稍微差一点,很可能critical path就出现在这里,前一个例子的output logic用的是curr_state,是一个D flip-flop,没有组合逻辑,所以timing比较好。

另外一个缺点是output logic必须判断next_state,很容易出错,观念必须非常清楚。

7. Conclusion

1. 3个always与2个always (state register与next state logic合一)是两种推荐的写法,而且这两种写法无论是要描述Moore FSM或者Mealy FSM都沒问题,其他写法都不推荐,个人是比较喜欢2个always写法(state register + next state logic),因为这种写法最精简,各种需求都可描述,也不用担心是否要提前一个clk判断,最为直观不易错。

2.实际上不会特別拘泥使用Moore或者Mealy,只要符合需求即可,一般会以Moore FSM为正宗。

3.实际上为了timing更好,会在Moore FSM的output logic多敲一級。

4.Mealy会比Moore少1个state,且output会比Moore早1个clk。

5.Moore与Mealy之间可以互換,只要在Mealy的output多敲一级即可。

标签:curr,有限,logic,next,状态机,state,always,output
From: https://www.cnblogs.com/lanlancky/p/17056890.html

相关文章

  • 16进制枚举状态机学习
    转自:https://blog.csdn.net/wodeni512517/article/details/711234691.介绍十六进制:typedefenum{ACTION_SHOWCARDS=0x01,//1ACTION_FOLLOW=0x02,//2A......
  • 宜宾城市大数据有限公司 - 面试
    1.自我介绍,基本情况+个人信息+获奖经历+比赛项目经历等2.Integer类型的比较,缓存:-128~1273.HashMap底层数据结构,简述put操作,是否线程安全,LinkedHashMap线程安全4.项目情况5.......
  • Verilog状态机
    Verilog里面的状态机,常用的是有限状态机(FiniteStateMachine,简称FSM),在有限的窗状态下按一定规律转换的时序电路,这个其实和C里面写软件状态机差不多。状态机在FPGA里面广......
  • 基于状态机的按键消抖模块
    本次案例是按着小梅哥的思路来写的,部分截图和文字来自其教学视频。1、状态机的设定  2、模块代码`timescale1ns/1ps///////////////////////////////////////......
  • 深圳市新移科技有限公司的《4G/5G 执法记录仪产品方案介绍》!
        执法记录仪最初是出现在民警执行公务时随身佩带的取证技术装备,为了实现公正执法、文明执法、保护执法人员和当事人合法权益,保障执法人员履行职责,促进提高执法水平......
  • Verilog实现基于状态机的序列检测
    一、状态机的基本概念硬件设计需要并行设计思想,而用Verilog描述的电路大多都是并行实现的,但是对于实际的项目工程,往往需要让硬件来做一些具有顺序的工作,这就要用到状态......
  • [完全免费] 在线UML State Diagram 状态机图工具 - 教程第7部分
    状态机图用于对单个类对象,用例和整个系统的动态行为进行建模。换句话说,当一个状态机创建了对象的连接对象时,该对象成为状态机的所有者,例如,状态机所附加的对象可以是一个类,用......
  • 状态机模式
    有限状态机  FSM(FiniteStateMachine)状态机四要素现态、条件、动作、次态现态:是指当前所处的状态条件:又称为“事件”,当一个条件被满足,将会触发一个动作,或者执行一次......
  • 牛客进阶题目20:根据状态转移写状态机-二段式
    把输出段与次态段合并即可`timescale1ns/1nsmodulefsm2( inputwireclk, inputwirerst, inputwiredata, outputregflag);//*************code****......
  • 深圳市友浩达科技有限公司CTO 张善友 入选 2022 中国开源先锋 33 人|积聚开源力量,持续
    2023年1月3日,2022年「中国技术先锋」年度评选推出「2022中国开源先锋33人之心尖上的开源人物榜单」,深圳市友浩达科技有限公司CTO张善友评选成为“心”尖上的开源......