概述
目录
写在前面
Finite State Manchines
Fsm serialdata
Fsm serialdp
Fsm hdlc
Design a Mealy FSM
ece241 2014 q5a
ece241 2014 q5b
2014 q3fsm
2014 q3bfsm
写在前面
HDLBits 刷题来到了最为重要的一部分---有限状态机,都说 Verilog 设计的精髓就是状态机的设计,可见状态机设计的重要性,通过三十多道的状态机的练习,可以更加熟悉状态机设计的要点,通常都设计为三段式,这样设计的状态机层次清晰且易于设计,时序上更为易懂。以下的解题方法不一定为最佳解决方案,有更好的方法欢迎提出,共同学习,共同进步!
Finite State Manchines
Fsm serialdata
设计一个有限状态机,可以识别何时在串行比特流中正确接收字节,请添加一个数据路径,该数据路径将输出正确接收的数据字节。out_byte 在完成时需要有效,并且是1,否则就不在乎。
请注意,串行协议首先发送最低有效位。
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
);
//状态机状态申明
parameter IDLE = 12'b000000000001;
parameter START = 12'b000000000010;
parameter BIT_ONE = 12'b000000000100;
parameter BIT_TWO = 12'b000000001000;
parameter BIT_THREE = 12'b000000010000;
parameter BIT_FOUR = 12'b000000100000;
parameter BIT_FIVE = 12'b000001000000;
parameter BIT_SIX = 12'b000010000000;
parameter BIT_SEVEN = 12'b000100000000;
parameter BIT_EIGHT = 12'b001000000000;
parameter STOP = 12'b010000000000;
parameter WAIT = 12'b100000000000;
reg [11:0] state;
reg [11:0] next_state;
//状态机第一段,状态初始化,时序逻辑非阻塞赋值
always @(posedge clk) begin
if (reset) begin
state <= IDLE;
end
else begin
state <= next_state;
end
end
//状态机第二段,状态跳转,阻塞赋值
always @(*) begin
next_state = state;
case(state)
IDLE: begin
if (~in) begin
next_state = START;
end
else begin
next_state = IDLE;
end
end
START: begin
next_state = BIT_ONE;
end
BIT_ONE: begin
next_state = BIT_TWO;
end
BIT_TWO: begin
next_state = BIT_THREE;
end
BIT_THREE:begin
next_state = BIT_FOUR;
end
BIT_FOUR: begin
next_state = BIT_FIVE;
end
BIT_FIVE: begin
next_state = BIT_SIX;
end
BIT_SIX: begin
next_state = BIT_SEVEN;
end
BIT_SEVEN: begin
next_state = BIT_EIGHT;
end
BIT_EIGHT: begin
if (in) begin
next_state = STOP;
end
else begin
next_state = WAIT;
end
end
WAIT: begin
if (in) begin
next_state = IDLE;
end
else begin
next_state = WAIT;
end
end
STOP: begin
if (in) begin
next_state = IDLE;
end
else begin
next_state = START;
end
end
default: begin
next_state = IDLE;
end
endcase
end
//状态机第三段,结果输出,组合逻辑
always @(posedge clk) begin
if (reset) begin
done <= 'd0;
out_byte <= 'd0;
end
else begin
case(next_state)
IDLE: begin
done <= 'd0;
out_byte <= 'd0;
end
START: begin
done <= 'd0;
out_byte <= 'd0;
end
BIT_ONE: begin
done <= 'd0;
out_byte[0] <= in;
end
BIT_TWO: begin
done <= 'd0;
out_byte[1] <= in;
end
BIT_THREE: begin
done <= 'd0;
out_byte[2] <= in;
end
BIT_FOUR: begin
done <= 'd0;
out_byte[3] <= in;
end
BIT_FIVE: begin
done <= 'd0;
out_byte[4] <= in;
end
BIT_SIX: begin
done <= 'd0;
out_byte[5] <= in;
end
BIT_SEVEN: begin
done <= 'd0;
out_byte[6] <= in;
end
BIT_EIGHT: begin
done <= 'd0;
out_byte[7] <= in;
end
WAIT: begin
done <= in;
out_byte <= out_byte;
end
STOP: begin
done <= 'd1;
out_byte <= out_byte;
end
default: begin
done <= 'd0;
out_byte <= 'd0;
end
endcase
end
end
endmodule
Fsm serialdp
我们希望将奇偶校验添加到串行接收器。奇偶校验在每个数据字节后添加一个额外的位。我们将使用奇偶校验,其中接收的9位中的1s数必须是奇数。例如,101001011满足奇偶校验(有 5 个 1秒),但001001011则不满足奇偶校验。
更改 FSM 和数据路径以执行奇数奇偶校验。仅当正确接收到一个字节并且其奇偶校验通过时,才置位完成的信号。喜欢串行接收器 FSM,此 FSM 需要识别起始位,等待所有 9 个(数据和奇偶校验)位,然后验证停止位是否正确。如果停止位未按预期出现,则 FSM 必须等到找到停止位后再尝试接收下一个字节。
为您提供了以下模块,可用于计算输入流的奇偶校验(它是具有重置功能的TFF)。预期用途是应为它提供输入位流,并在适当的时间重置,以便计算每个字节中的1位数。
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
);
//状态机状态申明
parameter IDLE = 13'b0000000000001;
parameter START = 13'b0000000000010;
parameter BIT_ONE = 13'b0000000000100;
parameter BIT_TWO = 13'b0000000001000;
parameter BIT_THREE = 13'b0000000010000;
parameter BIT_FOUR = 13'b0000000100000;
parameter BIT_FIVE = 13'b0000001000000;
parameter BIT_SIX = 13'b0000010000000;
parameter BIT_SEVEN = 13'b0000100000000;
parameter BIT_EIGHT = 13'b0001000000000;
parameter PARITY_BIT = 13'b0010000000000;
parameter STOP = 13'b0100000000000;
parameter WAIT = 13'b1000000000000;
reg [12:0] state;
reg [12:0] next_state;
reg odd;
//状态机第一段,状态初始化,时序逻辑非阻塞赋值
always @(posedge clk) begin
if (reset) begin
state <= IDLE;
end
else begin
state <= next_state;
end
end
//状态机第二段,状态跳转,阻塞赋值
always @(*) begin
next_state = state;
case(state)
IDLE: begin
if (~in) begin
next_state = START;
end
else begin
next_state = IDLE;
end
end
START: begin
next_state = BIT_ONE;
end
BIT_ONE: begin
next_state = BIT_TWO;
end
BIT_TWO: begin
next_state = BIT_THREE;
end
BIT_THREE:begin
next_state = BIT_FOUR;
end
BIT_FOUR: begin
next_state = BIT_FIVE;
end
BIT_FIVE: begin
next_state = BIT_SIX;
end
BIT_SIX: begin
next_state = BIT_SEVEN;
end
BIT_SEVEN: begin
next_state = BIT_EIGHT;
end
BIT_EIGHT: begin
next_state = PARITY_BIT;
end
PARITY_BIT: begin
if (in) begin
next_state = STOP;
end
else begin
next_state = WAIT;
end
end
WAIT: begin
if (in) begin
next_state = IDLE;
end
else begin
next_state = WAIT;
end
end
STOP: begin
if (in) begin
next_state = IDLE;
end
else begin
next_state = START;
end
end
default: begin
next_state = IDLE;
end
endcase
end
//状态机第三段,结果输出,组合逻辑
always @(posedge clk) begin
if (reset) begin
out_byte <= 'd0;
done <= 'd0;
end
else begin
case(next_state)
IDLE: begin
out_byte <= 'd0;
done <= 'd0;
end
START: begin
out_byte <= 'd0;
done <= 'd0;
end
BIT_ONE: begin
out_byte[0] <= in;
done <= 'd0;
end
BIT_TWO: begin
out_byte[1] <= in;
done <= 'd0;
end
BIT_THREE: begin
out_byte[2] <= in;
done <= 'd0;
end
BIT_FOUR: begin
out_byte[3] <= in;
done <= 'd0;
end
BIT_FIVE: begin
out_byte[4] <= in;
done <= 'd0;
end
BIT_SIX: begin
out_byte[5] <= in;
done <= 'd0;
end
BIT_SEVEN: begin
out_byte[6] <= in;
done <= 'd0;
end
BIT_EIGHT: begin
out_byte[7] <= in;
done <= 'd0;
end
PARITY_BIT: begin
out_byte <= out_byte;
done <= 'd0;
end
WAIT: begin
out_byte <= out_byte;
done <= 'd0;
end
STOP: begin
out_byte <= out_byte;
if (odd=='d1) begin
done <= 'd1;
end
else begin
done <= 'd0;
end
end
default: begin
out_byte <= 'd0;
done <= 'd0;
end
endcase
end
end
// always @(posedge clk) begin
// if (reset) begin
// done <= 'd0;
// end
// else if (next_state==STOP && odd=='d1) begin
// done <= 'd1;
// end
// else begin
// done <= 'd0;
// end
// end
wire rst;
assign rst = (reset == 1'b1 || next_state == IDLE || next_state == START);
parity u_parity(
.clk (clk ),
.reset (rst ),
.in (in ),
.odd (odd )
);
endmodule
Fsm hdlc
同步 HDLC 成帧涉及解码连续的位数据流,以查找指示帧(数据包)开始和结束的位模式。看到 6 个连续的 1(即01111110)是一个指示帧边界的“标志”。为了避免数据流意外包含“标志”,发送方在每5个连续的1之后插入一个零,接收方必须检测并丢弃。如果连续有 7 个或更多个 1,我们还需要发出错误信号。
创建一个有限状态机来识别这三个序列:
- 0111110:需要丢弃一个位的信号(丢弃)。
- 01111110:标记帧的开头/结尾(标志)。
- 01111111...: 错误 (7 或更多 1 ) (错误)。
重置 FSM 时,它应处于行为类似于上一个输入为 0 的状态。
下面是一些示例序列,用于说明所需的操作。
module top_module(
input clk,
input reset, // Synchronous reset
input in,
output disc,
output flag,
output err
);
parameter IDLE = 10'b0000000001;
parameter BIT_ONE = 10'b0000000010;
parameter BIT_TWO = 10'b0000000100;
parameter BIT_THREE = 10'b0000001000;
parameter BIT_FOUR = 10'b0000010000;
parameter BIT_FIVE = 10'b0000100000;
parameter BIT_SIX = 10'b0001000000;
parameter STOP = 10'b0010000000;
parameter DIS = 10'b0100000000;
parameter ERROR = 10'b1000000000;
reg [9:0] state;
reg [9:0] next_state;
//状态机第一段,状态初始化,时序逻辑非阻塞赋值
always @(posedge clk) begin
if (reset) begin
state <= IDLE;
end
else begin
state <= next_state;
end
end
//状态机第二段,状态跳转,阻塞赋值
always @(*) begin
next_state = state;
case(state)
IDLE: begin
if (in) begin
next_state = BIT_ONE;
end
else begin
next_state = IDLE;
end
end
BIT_ONE: begin
if (in) begin
next_state = BIT_TWO;
end
else begin
next_state = IDLE;
end
end
BIT_TWO: begin
if (in) begin
next_state = BIT_THREE;
end
else begin
next_state = IDLE;
end
end
BIT_THREE: begin
if (in) begin
next_state = BIT_FOUR;
end
else begin
next_state = IDLE;
end
end
BIT_FOUR: begin
if (in) begin
next_state = BIT_FIVE;
end
else begin
next_state = IDLE;
end
end
BIT_FIVE: begin
if (in) begin
next_state = BIT_SIX;
end
else begin
next_state = DIS;
end
end
BIT_SIX: begin
if (~in) begin
next_state = STOP;
end
else begin
next_state = ERROR;
end
end
STOP: begin
if (in) begin
next_state = BIT_ONE;
end
else begin
next_state = IDLE;
end
end
DIS: begin
if (in) begin
next_state = BIT_ONE;
end
else begin
next_state = IDLE;
end
end
ERROR: begin
if (in) begin
next_state = ERROR;
end
else begin
next_state = IDLE;
end
end
default: begin
next_state = IDLE;
end
endcase
end
//状态机第三段,结果输出,时序逻辑非阻塞赋值
always @(posedge clk) begin
if (reset) begin
disc <= 'd0;
flag <= 'd0;
err <= 'd0;
end
else begin
case(next_state)
DIS: begin
disc <= 'd1;
flag <= 'd0;
err <= 'd0;
end
STOP: begin
disc <= 'd0;
flag <= 'd1;
err <= 'd0;
end
ERROR: begin
disc <= 'd0;
flag <= 'd0;
err <= 'd1;
end
default: begin
disc <= 'd0;
flag <= 'd0;
err <= 'd0;
end
endcase
end
end
endmodule
Design a Mealy FSM
实现一个 Mealy 型有限状态机,该状态机在名为 x 的输入信号上识别序列“101”。您的 FSM 应具有一个输出信号 z,当检测到“101”序列时,该信号被置位到逻辑-1。您的 FSM 还应具有低电平有效异步复位。您的状态机中可能只有 3 个状态。您的 FSM 应识别重叠序列。
module top_module (
input clk,
input aresetn, // Asynchronous active-low reset
input x,
output z
);
//状态定义
parameter IDLE = 4'b0001;
parameter BIT_ONE = 4'b0010;
parameter BIT_TWO = 4'b0100;
parameter BIT_THREE = 4'b1000;
//现态和次态
reg [3:0] state;
reg [3:0] next_state;
//状态机第一段,初始化状态,时序逻辑非阻塞赋值
always @(posedge clk or negedge aresetn) begin
if (!aresetn) begin
state <= IDLE;
end
else begin
state <= next_state;
end
end
//状态机第二段,状态跳转,阻塞赋值
always @(*) begin
next_state = state;
case(state)
IDLE: begin
if (x) begin
next_state = BIT_ONE;
end
else begin
next_state = IDLE;
end
end
BIT_ONE: begin
if (~x) begin
next_state = BIT_TWO;
end
else begin
next_state = BIT_ONE;
end
end
BIT_TWO: begin
if (x) begin
next_state = BIT_THREE;
end
else begin
next_state = IDLE;
end
end
BIT_THREE: begin
if (x) begin
next_state = BIT_ONE;
end
else begin
next_state = BIT_TWO;
end
end
default: begin
next_state = IDLE;
end
endcase
end
//状态机第三段,结果输出,组合逻辑
assign z = (next_state==BIT_THREE);
endmodule
ece241 2014 q5a
设计一个单输入一输出串行2的补码器摩尔状态机。输入(x)是一系列位(每个时钟周期一个),从数字的最低有效位开始,输出(Z)是输入的2的补码。机器将接受任意长度的输入数字。该电路需要异步复位。释放重置时开始转换,断言重置时停止转换。
module top_module (
input clk,
input areset,
input x,
output z
);
parameter MSB = 3'b001;
parameter OUT_1 = 3'b010;
parameter OUT_0 = 3'b100;
reg [2:0] state;
reg [2:0] next_state;
//状态机第一段,状态初始化,时序逻辑非阻塞赋值
always @(posedge clk or posedge areset) begin
if (areset) begin
state <= MSB;
end
else begin
state <= next_state;
end
end
//状态机第二段,状态跳转,阻塞赋值
always @(*) begin
next_state = state;
case(state)
MSB: begin
if (x) begin
next_state = OUT_1;
end
else begin
next_state = MSB;
end
end
OUT_1: begin
if (x) begin
next_state = OUT_0;
end
else begin
next_state = OUT_1;
end
end
OUT_0: begin
if (~x) begin
next_state = OUT_1;
end
else begin
next_state = OUT_0;
end
end
default: begin
next_state = MSB;
end
endcase
end
//状态机第三段,结果输出,组合逻辑
assign z = (state==OUT_1);
endmodule
ece241 2014 q5b
利用独热码编写一下的米利状态机。
module top_module (
input clk,
input areset,
input x,
output z
);
parameter A = 2'b01;
parameter B = 2'b10;
reg [1:0] state;
reg [1:0] next_state;
//状态机第一段,状态初始化,时序逻辑非阻塞赋值
always @(posedge clk or posedge areset) begin
if (areset) begin
state <= A;
end
else begin
state <= next_state;
end
end
//状态机第二段,状态跳转,阻塞赋值
always @(*) begin
next_state = state;
case(state)
A: begin
if (x) begin
next_state = B;
z = 'd1;
end
else begin
next_state = A;
z = 'd0;
end
end
B: begin
next_state = B;
if (x) begin
z = 'd0;
end
else begin
z = 'd1;
end
end
endcase
end
endmodule
2014 q3fsm
module top_module (
input clk,
input reset, // Synchronous reset
input s,
input w,
output z
);
parameter IDLE = 5'b00001;
parameter A = 5'b00010;
parameter B = 5'b00100;
parameter C = 5'b01000;
parameter D = 5'b10000;
reg [4:0] state;
reg [4:0] next_state;
reg [10:0] cnt;
//状态机第一段,状态初始化,时序逻辑非阻塞赋值
always @(posedge clk) begin
if (reset) begin
state <= IDLE;
end
else begin
state <= next_state;
end
end
//状态机第二段,状态跳转,阻塞赋值
always @(*) begin
case(state)
IDLE: begin
if (s) begin
next_state = A;
end
else begin
next_state = IDLE;
end
end
A: begin
next_state = B;
end
B: begin
next_state = C;
end
C: begin
next_state = D;
end
D: begin
next_state = B;
end
default: begin
next_state = IDLE;
end
endcase
end
always @(posedge clk) begin
if (reset) begin
cnt <= 'd0;
end
else begin
case(next_state)
IDLE: begin
cnt <= 'd0;
end
A: begin
cnt <= 'd0;
end
B: begin
if (w) begin
cnt <= 'd1;
end
else begin
cnt <= 'd0;
end
end
C: begin
if (w) begin
cnt <= cnt + 'd1;
end
else begin
cnt <= cnt;
end
end
D: begin
if (w) begin
cnt <= cnt + 'd1;
end
else begin
cnt <= cnt;
end
end
endcase
end
end
assign z = (state==D && cnt=='d2);
endmodule
2014 q3bfsm
给定如下所示的状态分配表,实现有限状态机。重置应将 FSM 重置为状态 000。
module top_module (
input clk,
input reset, // Synchronous reset
input x,
output z
);
parameter A = 3'b000;
parameter B = 3'b001;
parameter C = 3'b010;
parameter D = 3'b011;
parameter E = 3'b100;
reg [2:0] state;
reg [2:0] next_state;
//状态机第一段,状态初始化,时序逻辑非阻塞赋值
always @(posedge clk) begin
if (reset) begin
state <= A;
end
else begin
state <= next_state;
end
end
//状态机第二段,状态跳转,阻塞赋值
always @(*) begin
next_state = state;
case(state)
A: begin
if (x) begin
next_state = B;
end
else begin
next_state = A;
end
end
B: begin
if (x) begin
next_state = E;
end
else begin
next_state = B;
end
end
C: begin
if (x) begin
next_state = B;
end
else begin
next_state = C;
end
end
D: begin
if (x) begin
next_state = C;
end
else begin
next_state = B;
end
end
E: begin
if (x) begin
next_state = E;
end
else begin
next_state = D;
end
end
default: begin
next_state = A;
end
endcase
end
//状态机第三段,结果输出,组合逻辑
assign z = (state==D) || (state==E);
endmodule
最后
以上就是辛勤山水为你收集整理的【HDLBits 刷题 11】Circuits(7)Finite State Manchines 18-26写在前面Finite State Manchines的全部内容,希望文章能够帮你解决【HDLBits 刷题 11】Circuits(7)Finite State Manchines 18-26写在前面Finite State Manchines所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复