一、题目

这一篇的题目中要求我们做一个类似不重叠的1xx序列检测器。
二、我的解法(2个状态)
我还是一贯的跟随前一题Lemmings 4的思路,其中加入参数进行计数器的效果。而这题与之类似,分为两个状态:发送和不发送,通过计数器的值来使每次发送的状态持续3个时钟周期,且在第三个时钟周期时对in[3]进行判断,来决定进入下一个发送状态还是进入不发送状态。这题比较简单,只是我的思路与作者给的提示思路不同,所以记录一下。下面是我的完整代码。
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output done); //
reg [0:0] state, next_state ;
parameter not_send=0, send=1 ;
reg [1:0] cnt ;
// State transition logic (combinational)
always@(*)begin
case(state)
not_send : next_state = in[3] ? send : not_send ;
send : next_state = ((cnt==3)&~in[3]) ? not_send : send ;
endcase
end
// State flip-flops (sequential)
always@(posedge clk)begin
if(reset)begin
state <= not_send ;
cnt <= 1 ;
end
else begin
state <= next_state ;
if(cnt == 3)
cnt <= 1 ;
else if(state)
cnt++ ;
end
end
// Output logic
assign done = (cnt == 3) & state ;
endmodule
三、作者思路
3.1 4个状态
作者提供的hint还是从每一个字节发送单独考虑的角度出发,将发送每一个字节的状态单独分开,同时加入一个状态用以判断done。hint及代码如下。
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output done); //
reg [1:0] state, next_state ;
parameter byte1=0, byte2=1, byte3=2, bdone=3 ;
// State transition logic (combinational)
always@(*)begin
case(state)
byte1 : next_state = in[3] ? byte2 : byte1 ;
byte2 : next_state = byte3 ;
byte3 : next_state = bdone ;
bdone : next_state = in[3] ? byte2 : byte1 ;
endcase
end
// State flip-flops (sequential)
always@(posedge clk)begin
if(reset)
state <= byte1 ;
else
state <= next_state ;
end
// Output logic
assign done = (state == bdone) ;
endmodule
3.2 3个状态
上述思路中,作者给的hint中说三个状态的话可能无法将done置1,所以添加了一个状态来给done置1。但是从我自己的解法出发,可以通过计数器的值对done是否置1进行判断,那么我认为在将发送每一个比特的状态拆分开的思路中,同样可以添加这样的一个参数来进行判断。
从原理出发,只要从byte1开始的三个时钟周期完整发送后,done便置1。那么,即在状态为byte3的下一周期将done置1即可。但这时我们只有三个状态,就无法直接通过现有状态判断,所以我加入last_state参数,在reset不置1时,记录当前周期的状态以便于下一个周期进行判断。代码如下。
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output done); //
reg [1:0] state, next_state, last_state ;
parameter byte1=0, byte2=1, byte3=2, bdone=3 ;
// State transition logic (combinational)
always@(*)begin
case(state)
byte1 : next_state = in[3] ? byte2 : byte1 ;
byte2 : next_state = byte3 ;
byte3 : next_state = byte1 ;
//bdone : next_state = in[3] ? byte2 : byte1 ;
endcase
end
// State flip-flops (sequential)
always@(posedge clk)begin
if(reset)
state <= byte1 ;
else begin
state <= next_state ;
last_state <= state ;
end
end
// Output logic
assign done = (last_state == byte3) ;
endmodule
四、总结反思
我在第一遍思考时,觉得自己的思路减少了状态,比作者的思路更巧妙一些。但是在做完回过头来看时,还是觉得分成四个状态更直接,更符合有限状态机的思路。不同于我两次添加标志位来对done是否置1进行判断,作者的思路直接给出一个状态来对done进行置1操作,思路更清晰,也更便于修改。

被折叠的 条评论
为什么被折叠?



