hdlbits网站:HDLBits (01xz.net)
其他hdlbits博客:
【hdlbits】个人学习交流分享(带答案)——verilog language部分-优快云博客
【hdlbits】个人学习交流分享(带答案)——combinational logic部分-优快云博客
【hdlbits】个人学习交流分享(带答案)——sequential logic部分-优快云博客
【hdlbits】个人学习交流分享(带答案)——Reading Simulations和Writing Testbenches部分-优快云博客
有限状态机部分难度比较大,在这一部分我花了比其他另外四个部分都多的时间,几乎占了我刷整个hdlbits一半的时间,死了很多脑细胞,写的我头昏脑胀。一个是很多有些题目作者的表达并不好,项目要求描述的并不清楚,最准确的还是时序图,时序图是不会说谎的。另外一个就是这一部分对初学者难度确实更大,先要弄懂作者题目的需求,然后根据需求要做出正确的状态机设计和输出逻辑的设计,这部分代码长一些,状态机部分也是整个hdlbits的精华内容,所以这部分除了代码,我写的分析的内容也会多一些。
正文:
finite state machines
simple FSM1(asynchronous reset)
Moore状态机,一个输入in,一个输出out,两个状态A和B,异步复位areset
module top_module(
input clk,
input areset, // Asynchronous reset to state B
input in,
output out);//三段式状态机
parameter A=0, B=1;
reg state, next_state;
always @(*) begin //组合逻辑块:状态转换的逻辑判断
case(state)
A:next_state=in?A:B;
B:next_state=in?B:A;
default:next_state=B;//防止进入未设定状态产生latch锁死,设定default后可以自启动
endcase
end
always @(posedge clk, posedge areset) begin // 时序逻辑块:执行状态变换
if(areset)
state<=B;
else
state<=next_state;
end
// Output logic
assign out = (state ==B);
endmodule
simple FSM1(synchronous reset)
Moore状态机,一个输入in,一个输出out,两个状态A和B,同步复位reset
题目给了一段式状态机模板,我就顺着写了,非常不建议写一段式状态机。
// Note the Verilog-1995 module declaration syntax here:
module top_module(clk, reset, in, out);
input clk;
input reset; // Synchronous reset to state B
input in;
output out;//
reg out;
//一段式状态机(不提倡这么写)
reg present_state, next_state;
parameter A=1'b0,B=1'b1;
always @(posedge clk) begin
if (reset) begin
present_state<=B;
out<=1'b1;
end else begin
case (present_state)// state transition logic
A:next_state=in?A:B;
B:next_state=in?B:A;
default:next_state=B;
endcase
// State flip-flops
present_state = next_state;
case (present_state)// output logic
B:out<=1'b1;
A:out<=1'b0;
default:out<=1'b1;
endcase
end
end
endmodule
simple FSM2(asynchronous reset)
Moore状态机,两个输入j和k,一个输出out,两个状态OFF和ON,异步复位areset
module top_module(
input clk,
input areset, // Asynchronous reset to OFF
input j,
input k,
output out); // 三段式
parameter OFF=0, ON=1;
reg state, next_state;
always @(*) begin
case(state)
ON:next_state=k?OFF:ON;
OFF:next_state=j?ON:OFF;
default:next_state=OFF;
endcase
end
always @(posedge clk, posedge areset) begin
if(areset)
state<=OFF;
else
state<=next_state;
end
// Output logic
assign out = (state == ON);
endmodule
simple FSM2(synchronous reset)
Moore状态机,两个输入j和k,一个输出out,两个状态OFF和ON,同步复位reset
module top_module(
input clk,
input reset, // Synchronous reset to OFF
input j,
input k,
output out); //
parameter OFF=0, ON=1;
reg state, next_state;
always @(*) begin
case(state)
OFF:next_state=j?ON:OFF;
ON:next_state=k?OFF:ON;
default:next_state=OFF;
endcase
end
always @(posedge clk) begin
if(reset)
state<=OFF;
else
state<=next_state;
end
// Output logic
assign out = (state == ON);
endmodule
simple state transitions3
要求实现此状态机的状态转换逻辑和输出逻辑(组合逻辑部分)
状态转移图:
Moore状态机,一个输入in,一个输出out,四个状态A,B,C,D。
module top_module(
input in,
input [1:0] state,
output [1:0] next_state,
output out); //
parameter A=2'b00,B=2'b01,C=2'b10,D=2'b11;
// State transition logic: next_state = f(state, in)
always @(*)begin
case(state)
A:next_state=in?B:A;
B:next_state=in?B:C;
C:next_state=in?D:A;
D:next_state=in?B:C;
default:next_state=A;
endcase
end
// Output logic: out = f(state) for a Moore state machine
assign out=(state==D);
endmodule
simple one-hot state transitions3
本题可以设独热码是A=4'b0001,B=4'b0010,C=4'b0100,D=4'b1000,独热码保证每个状态只有一个 state bit 为1,其他都为0。这意味着可以通过检查特定位的值来判别是否处于特定状态。本题中[0]/[1]/[2]/[3]分别是A/B/C/D的状态位(state bit)
要求通过独热编码来检查推导出状态转换逻辑和输出逻辑(组合逻辑部分)。
状态转移图:
本题与上题放在前后可以做对比,正常写状态机的状态转移逻辑,都是根据现态(current_state)和触发条件转移到哪个次态(next_state),这是current_state→next_state的思路,也就是看现态(current_state)指出去的箭头。
这里题目要求通过独热编码来检查状态转换逻辑,这里从次态(next-state)出发,分析什么样的现态(current_state)加什么样的条件会得到该次态,这是next_state→current_state的思路(一种逆向的思路),也就是看指向次态(next_state)的箭头。
更详细的信息可以参考作者的解释:
module top_module(
input in,
input [3:0] state,
output [3:0] next_state,
output out); //
parameter A=0, B=1, C=2, D=3;//A=0,B=1,C=2,D=3是一个[3:0]state位索引
// State transition logic: Derive an equation for each state flip-flop.
assign next_state[A] = (state[A]&~in)|(state[C]&~in);
assign next_state[B] = (state[A]&in)|(state[B]&in)|(state[D]&in);
assign next_state[C] = (state[B]&~in)|(state[D]&~in);
assign next_state[D] = (state[C]&in);
// Output logic:
assign out = (state[D]);
endmodule
因为这里独热码设为了A=4‘b0001,B=4'b0010,C=4'b0100,D=4'b1000,所以上面这段代码A=0,B=1,C=2,D=3其实是一个[3:0]state bit的索引,如果不写parameter,还可以这样写:
module top_module(
input in,
input [3:0] state,
output [3:0] next_state,
output out); //
// State transition logic: Derive an equation for each state flip-flop.
assign next_state[0] = (state[0]&~in)|(state[2]&~in);
assign next_state[1] = (state[0]&in)|(state[1]&in)|(state[3]&in);
assign next_state[2] = (state[1]&~in)|(state[3]&~in);
assign next_state[3] = (state[2]&in);
// Output logic:
assign out = (state[3]);
endmodule
simple FSM3(asynchronous reset)
Moore状态机,一个输入in,一个输出out,四个状态A,B,C,D,异步复位。
module top_module(
input clk,
input in,
input areset,
output out); //
parameter A=2'b00,B=2'b01,C=2'b10,D=2'b11;
reg [1:0]current_state,next_state;
// 主控状态转移逻辑
always @(*)begin
case(current_state)
A:next_state=in?B:A;
B:next_state=in?B:C;
C:next_state=in?D:A;
D:next_state=in?B:C;
default:next_state=A;
endcase
end
// 主控执行逻辑
always @(posedge clk,posedge areset)begin
if(areset)
current_state<=A;
else
current_state<=next_state;
end
// 输出逻辑
assign out=(current_state==D);
endmodule
simple FSM3(synchronous reset)
Moore状态机,一个输入in,一个输出out,四个状态A,B,C,D,同步复位。
module top_module(
input clk,
input in,
input reset,
output out); //三段式
parameter A=2'b00,B=2'b01,C=2'b10,D=2'b11;
reg [1:0]current_state,next_state;
// 主控状态转移逻辑
always @(*)begin
case(current_state)
A:next_state=in?B:A;
B:next_state=in?B:C;
C:next_state=in?D:A;
D:next_state=in?B:C;
default:next_state=A;
endcase
end
// 主控执行逻辑
always @(posedge clk)begin
if(reset)
current_state<=A;
else
current_state<=next_state;
end
// 输出逻辑
assign out=(current_state==D);
endmodule
design a Moore FSM
module top_module (
input clk,
input reset,
input [3:1] s,
output reg fr3,
output reg fr2,
output reg fr1,
output reg dfr
);
parameter H3=4'b1000,B32=4'b0100,B21=4'b0010,L1=4'b0001;//4个状态:high s3,between s3s2,between s2s1, low s1,
reg [3:0]current_state,next_state;
always @(posedge clk)begin//主控执行逻辑
if (reset) begin
current_state<=L1;
end
else begin
current_state<=next_state;
end
end
always @(*)begin//主控状态转移逻辑
case(s)
3'b000:next_state=L1;
3'b001:next_state=B21;
3'b011:next_state=B32;
3'b111:next_state=H3;
default:next_state=L1;
endcase
end
always @(posedge clk)begin//{fr3,fr2,fr1}的输出逻辑
if(reset) begin
{fr3,fr2,fr1}<=3'b111;
end
else begin
case(next_state)
L1:{fr3,fr2,fr1}<=3'b111;
B21:{fr3,fr2,fr1}<=3'b011;
B32:{fr3,fr2,fr1}<=3'b001;
H3:{fr3,fr2,fr1}<=3'b000;
default:{fr3,fr2,fr1}<=3'b111;
endcase
end
end
always @(posedge clk)begin//dfr的输出逻辑
if(reset) begin
dfr<=1'b1;
end
else begin
if(next_state<current_state) begin
dfr<=1'b1;
end
else if(next_state>current_state) begin
dfr<=1'b0;
end
else
dfr<=dfr;
end
end
endmodule
lemmings 1
用摩尔状态机实现,两种状态LEFT和RIGHT,两个输入bump_left和bump_right,两个输出walk_left和walk_right;
状态转移图:
代码:
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
output walk_left,
output walk_right); //
parameter LEFT=0, RIGHT=1;
reg current_state, next_state;
always @(*) begin// State transition logic
case(current_state)
LEFT:next_state=bump_left?RIGHT:LEFT;
RIGHT:next_state=bump_right?LEFT:RIGHT;
default:next_state=LEFT;
endcase
end
always @(posedge clk, posedge areset) begin// State flip-flops with asynchronous reset
if(areset) begin
current_state<=LEFT;
end
else begin
current_state<=next_state;
end
end
// Output logic
assign walk_left = (current_state == LEFT);
assign walk_right = (current_state == RIGHT);
endmodule
lemmings 2
优先级:下落>碰撞,所以下落时候无视碰撞信号
用摩尔状态机实现,四种状态LEFT、RIGHT、FALL_LEFT和FALL_RIGHT,三个输入bump_left、 bump_right和ground,三个输出walk_left、walk_right和aaah
状态转移图(粗黑色箭头代表areset复位到的状态):
代码:
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
output walk_left,
output walk_right,
output aaah );
parameter LEFT=4'b0001,RIGHT=4'b0010,FALL_LEFT=4'b0100,FALL_RIGHT=4'b1000;
reg [3:0]current_state,next_state;
always@(*)begin主控状态转移逻辑
case(current_state)
LEFT:begin
if(!ground) begin//地面消失,向左下落
next_state=FALL_LEFT;
end
else begin//在地面上向左走
if(bump_left) begin//碰撞改向右走
next_state=RIGHT;
end
else begin
next_state=LEFT;//没碰撞继续向左走
end
end
end
RIGHT:begin
if(!ground) begin//地面消失,向右下落
next_state=FALL_RIGHT;
end
else begin//在地面上向右走
if(bump_right) begin//碰撞改向左走
next_state=LEFT;
end
else begin
next_state=RIGHT;//没碰撞继续向右走
end
end
end
FALL_LEFT:begin
if(ground) begin
next_state=LEFT;
end
else begin