|
发表于 2016-6-29 23:29:53
|
显示全部楼层
修改了下楼主的部分代码,两种情况下仿真结果一致。因此个人认为,两种情况是一致的,书中的F和A,G和adle是等价状态。因此7状态会产生冗余逻辑。如果有兴趣的,下次发一下DC综合的面积报告,一定是会有区别的。----------------------------------------------------------------------------------------------------
5状态
----------------------------------------------------------------------------------------------------
module seqdet (
rst_n, clk,
seq, det
);
input clk, rst_n;
input seq;
output det;
reg det;
reg [2:0] cstate, nstate;
parameter IDLE = 3'd0,
A_1 = 3'd1,
B_10 = 3'd2,
C_100 = 3'd3,
D_1001 = 3'd4,
E_10010 = 3'd5;
always @ (posedge clk or negedge rst_n)
if (!rst_n)
cstate <= IDLE;
else
cstate <= nstate;
always @ (seq or cstate) //修改:always用于组合逻辑,内部赋值用阻塞赋值
case (cstate)
IDLE : if (seq == 1) nstate = A_1;
else nstate = IDLE;
A_1: if (seq == 0) nstate = B_10;
else nstate = A_1;
B_10: if (seq == 0) nstate = C_100;
else nstate = A_1;
C_100: if (seq == 1) nstate = D_1001;
else nstate = IDLE;
D_1001: if (seq == 0) nstate = E_10010;
else nstate = A_1;
E_10010: if (seq == 0) nstate = C_100;
else nstate = A_1;
default: nstate = IDLE;
endcase
always @ (nstate) //修改:楼主是现态,采用次态,可以在最后一个0一出现就输出det=1,用现态,得多等一个周期
if (nstate == E_10010) det = 1;
else det = 0;
endmodule
-------------------------------------------------------------------------------------------------------------------------------------
7状态
--------------------------------------------------------------------------------------------------------------------------------------
module seqdetor(clock,reset,signalin,signalout);
input clock,signalin,reset;
output signalout;
reg [2:0] state;
parameter
idle = 3'd0,
a = 3'd1,
b = 3'd2,
c = 3'd3,
d = 3'd4,
e = 3'd5,
f = 3'd6,
g = 3'd7;
assign signalout = (state == d && signalin == 0)?1:0;//改为D状态
always@(posedge clock)
if(!reset)
begin
state <= idle;
end
else
begin
casex(state)
idle:
begin
if(signalin == 1) //1st 1 comes
state <= a;
else
state <= idle;
end
a:
begin
if(signalin == 0) //1st 0 comes
state <= b;
else
state <= a;
end
b:
begin
if(signalin == 0)//2sec 0 comes
state <= c;
else
state <= f;
end
c:
begin
if(signalin == 1) //2sec 1 comes
state <= d;
else
state <= g;
end
d:
begin
if(signalin == 0)//last 0 comes
state <= e;
else
state <= a;
end
e:
begin
if(signalin == 0)
state <= c;
else
state <= a;
end
f:
begin
if(signalin == 1)
state <= a;
else
state <= b;
end
g:
begin
if(signalin == 1)
state <= a;
else
state <= g; //修改,楼主是F,应该转为g或者IDLE,两者等价
end
default:
state <= idle;
endcase
end
endmodule
-------------------------------------------------------------------------------------------
仿真图
---------------
`timescale 1ns/1ns
module seqdet_tb;
reg clk ;
reg rst_n;
reg seq;
wire det;
wire [23: 0] dat = 20'b1111_0101_1010_0110_0100_1111 ; //修改直接注释,后面没用到,是书中方法。
initial
begin
clk = 1'b0 ;
rst_n = 1'b0 ;
seq = 1'b0 ;
#200 rst_n = 1'b1 ;
end
always #25 clk = ~clk ;
integer i ;
initial i = 0 ;
always@( posedge clk )
begin
seq <= $random ;//dat;
if( i == 23 )
i = 0 ;
else
i = i + 1 ;
end
seqdet dut( //楼主的代码
.rst_n(rst_n ),
.clk( clk ),
.seq( seq ),
.det( det ) //det 是楼主的输出。
);
wire det2 ;
seqdetor dut2( //书上的例子
.clock( clk ),
.reset( rst_n ),
.signalin( seq ),
.signalout( det2 )); //det2 是书上例子的输出
initial begin
$fsdbDumpfile("wave.fsdb");
$fsdbDumpvars( 0 , seqdet_tb );
end
endmodule
--------------------------------------------------------------------------------------------
状态机建议两段式和三段式,清晰易修改。若想要快速反馈输出,第三个always用电平敏感做做组合逻辑用,若考虑剔除毛刺;三段式的第三个always用做时序逻辑,用寄存器打一拍。 |
|