1.兵乓操作:
输入数据流通过“输入数据选择单元”将数据流等时分配到两个数据缓冲区,数据缓冲模块可以为任何存储模块,比较常用的存储单元为双口 RAM(DPRAM)、单口RAM(SPRAM)、FIFO等。
在第一个缓冲周期,将输入的数据流缓存到“数据缓冲模块1”;在第2个缓冲周期,通过“输入数据选择单元”的切换,将输入的数据流缓存到“数据缓冲模块2”,同时将“数据缓冲模块1”缓存的第1个周期数据通过“输出数据选择单元”的选择,送到 “数据流运算处理模块”进行运算处理;在第3个缓冲周期通过“输入数据选择单元”的再次切换,将输入的数据流缓存到“数据缓冲模块1”,同时将“数据缓冲模块2”缓存的第2个周期的数据通过“输出数据选择单元”切换,送到“数据流运算处理模块”进行运算处理。
2.Mealy和moore型状态机
Mealy和moore型状态机的主要区别
状态机一般分为三种类型:
Moore型状态机:下一状态只由当前状态决定,与输入无关,即次态=f(现状,输入),输出=f(现状);
Mealy型状态机:下一状态不但与当前状态有关,还与当前输入值有关,即次态=f(现状,输入),输出=f(现状,输入);
混合型状态机。
以下内容转载自:https://blog.csdn.net/CrazyUncle/article/details/88830654
波形上的区别:
以一个序列检测器为例,检测到输入信号11时输出z为1,其他时候为0。用摩尔型FSM实现需要用到三个状态(A,B,C)。而用米利型FSM实现则需要两个状态(A,B)。摩尔型FSM输出函数的输入只由状态变量决定,要想输出z=1,必须C状态形成,即寄存器中的两个1都打进去后才可以。输出z=1会在下一个有效沿到来的时候被赋值。而米利型FSM输出函数是由输入和状态变量共同决定的。状态在B的时候如果输入为1,则直接以组合电路输出z=1,不需要等到下个有效沿到来。从而也就不需要第三个状态C。
比较:
1.摩尔机器使用更安全:
输出在时钟边沿变化(总是在一个周期后)。
在Mealy机器中,输入更改可能会在逻辑完成后立即导致输出更改, 当两台机器互连时出现大问题 - 如果不小心,可能会发生异步反馈。
2.Mealy机器对输入的反应更快:
在相同的周期内反应 - 不需要等待时钟。
在Moore机器中,可能需要更多逻辑来将状态解码为输出 - 在时钟边沿之后更多的门延迟。
并非所有时序电路都可以使用Mealy模型实现。 一些时序电路只能作为摩尔机器实现。
以下内容转载自:Verilog基础知识(状态机与序列检测
http://www.jeepxie.net/article/441255.html
状态机
状态机分moore机和mealy机,其中:
- moore机的输出只与状态有关
- mealy机的输出与当前状态和输入都有关
- 体现在状态转移图上就是,moore机的输出在状态圆圈内,mealy机的输出在转移曲线上
- moore完全描述状态转移图会比mealy机多一个状态
- 体现在verilog代码中就是,moore机的最后输出逻辑只判断state,mealy机的输出逻辑中判断
state && input
状态机写法
一段式:一个always块,既描述状态转移,又描述状态的输入输出,当前状态用寄存器输出。一段式写法简单,但是不利于维护,状态扩展麻烦,状态复杂时易出错,不推荐;
二段式:两个always块,时序逻辑与组合逻辑分开,一个always块采用同步时序描述状态转移;另一个always块采用组合逻辑判断状态转移条件,描述状态转移规律以及输出,当前状态用组合逻辑输出,可能出现竞争冒险,产生毛刺,而且不利于约束,不利于综合器和布局布线器实现高性能的设计;
三段式:三个always块,一个always模块采用同步时序描述状态转移;一个always采用组合逻辑判断状态转移条件,描述状态转移规律;第三个always块使用同步时序描述状态输出,寄存器输出。
三段式与二段式相比,关键在于根据状态转移规律,在上一状态根据输入条件判断出当前状态的输出,从而在不插入额外时钟节拍的前提下,实现了寄存器输出。
状态机3段式代码风格
描述方式:
同步状态转换过程的边沿敏感行为(时序逻辑,用“<=”非阻塞赋值);
描述下一个状态和输出逻辑的电平敏感行为(组合逻辑,用“=”阻塞赋值)。
下面以检测10010序列为例说明。
状态转移图
测试代码
module pattern_det(
input in, clk, rst,
output reg moore_out, mealy_out
);
reg [4:0] state, state_next;
localparam S_idle = 5'b00000;
localparam S1 = 5'b00001;
localparam S10 = 5'b00010;
localparam S100 = 5'b00100;
localparam S1001 = 5'b01000;
localparam S10010 = 5'b10000;
always @(posedge clk or posedge rst) begin
if (rst) begin
state <= S_idle;
end
else begin
state <= state_next;
end
end
always @(*) begin
if (rst) begin
state_next = S_idle;
end
else begin
case(state)
S_idle: if (in == 1) state_next = S1;
else state_next = S_idle;
S1: if (in == 0) state_next = S10;
else state_next = S1;
S10: if (in == 0) state_next = S100;
else state_next = S1;
S100: if (in == 1) state_next = S1001;
else state_next = S_idle;
S1001: if (in ==0) state_next = S10010;
else state_next = S1;
S10010: if (in == 0) state_next = S100;
else state_next = S1;
default: state_next = S_idle;
endcase
end
end
//Moore Machine
always @(posedge clk or posedge rst) begin
if (rst) begin
moore_out <= 1'b0;
end
else begin
// moore_out <= (state == S10010) ? 1'b1 : 1'b0;
case(state)
S10010: moore_out <= 1'b1;
default: moore_out <= 1'b0;
endcase
end
end
//Mealy Machine
always @(posedge clk or posedge rst) begin
if (rst) begin
mealy_out <= 1'b0;
end
else begin
mealy_out <= (state == S1001 && in ==0) ? 1'b1 : 1'b0;
end
end
endmodule
`timescale 1ns/100ps
module pattern_det_tb;
reg clk, rst;
reg [23:0] data;
wire in, moore_out, mealy_out;
assign in = data[23];
initial begin
clk = 1'b0;
rst = 1'b0;
#2 rst = 1'b1;
#30 rst = 1'b0;
data = 20'b1100_1001_0000_1001_0100;
#20000 $finish;
end
always #20 clk = ~clk;
always @(posedge clk)
#2 data = {data[22:0], data[23]};
pattern_det U1(
.in(in),
.clk(clk),
.rst(rst),
.moore_out(moore_out),
.mealy_out(mealy_out)
);
endmodule
可以看出综合出的电路中mealy机最后输出是input和state在做与运算。
moore机因为是到达S10010状态才输出,mealy机则是S1001状态下输入为0就输出,所以moore机的输出比mealy机输出慢一个周期。
参考文献:Verilog经典题——FSM三段式状态机序列检测
https://zhuanlan.zhihu.com/p/159216603