1.有限状态机概念
概念
状态机是复杂逻辑功能(如算法机中的流程控制器)实现的最主要也是最有效的手段
状态机记录自身工作状态,通过输入与当前状态来确定下个状态,并通过当前状态和输入来确定输出
状态编码:
1.二进制编码或者格雷码(防止竞争冒险)
2.独热码:是只有一位为高的编码
3.CPLD一般使用格雷码
4.FPGA一般使用独热码(综合工具一般会把已经识别的状态机中的编码转换为独热码,所以,这时候使用良好的代码风格就非常重要,如三段式。好的代码风格可以使时钟频率加快几倍)
设计步骤
1.逻辑抽象,绘制转换图
2.状态简化与分配
3.总结状态驱动与输出
4.编写代码
设计方法(三段式代码编写)
1.状态转移段(时序逻辑)
2.状态驱动段(组合逻辑)
3.输出段(一般为组合逻辑)
实例:序列检测器
检测到输入序列110,则输出1,否则0
状态转换图: (S0:输入一个0;S1:收到一个1;S2:连续收到两个1;S3:连续收到110)
Verilog代码:
module seqdet ( input clk, input rst, input seq, output reg det );
localparam s0=4'h1; localparam s1=4'h2; localparam s2=4'h4; localparam s3=4‘h8; // 独热码
reg [3:0] state, next_state; // 状态转移 always@(posedge clk) begin if(rst) state <= s0; else state <= next_state; end //这是时序逻辑 |
// 状态驱动 always @(*) begin case(state) s0: next_state=((seq==1)?s1:s0); s1: next_state=((seq==1)?s2:s0); s2: next_state=((seq==1)?s2:s3); s3: next_state=((seq==1)?s1:s0); default: next_state=((seq==1)?s1:s0); endcase end // 输出 case(state) s0: det=1'b0; s1: det=1'b0; s2: det=1'b0; s3: det=1'b1; default: det=1'b0; endcase end
endmodule
|
Q1:这是什么用法?
Q2:仿真出现错误:Too many inherited module instance parameters.
Testbench:
module testbench; reg clk; reg rst; reg [19:0]data = 20'b0011_1001_0101_1011_0000; wire out; reg [4:0] cnt; wire seq = data[cnt]; integer i; initial begin clk = 1'b0; cnt = 5'b0; rst = 1'b1; #40 rst = 1'b0; end always begin #10 clk = ~clk; end always@(posedge clk) begin if(cnt < 5'd19) cnt <= cnt + 1'b1; else $stop(); end seqdet seqdet_inst(.clk(clk), .rst(rst), .seq(data[cnt]), .det(out)); endmodule
|
实例:秒表
1.某秒表有两个按键K1和K0
按下K0,计时开始,再次按下K0,计时暂停,再次按下K0,计时继续;
计时开始后,按下K1,显示暂停,即显示的数字冻结,内部仍在计时,再次按下K1,显示更新为新的计时时间,仍然冻结,内部仍继续计时;
计时暂停后,按下K1,计时复位(归零);
冻结显示时,按下K0,恢复正常显示;
状态归纳:
空闲状态:不计时,显示0;
计时状态:计时,并实时显示时间;
计时暂停状态:计时暂停;
显示暂停状态:计时,显示时间锁定。
2.状态转换归纳
停止(Stop)
K0à计时
计时(Run)
K0à计时暂停
K1à显示暂停
计时暂停(Pause)
K0à计时
K1à停止
显示暂停(Freeze)
K0à计时
K1à显示暂停
3.
4.整体结构
(1)假定计时显示格式为:HH:MM:SS:cc(cc是百分秒)
(2)可使用一个M100计数器、两个M60计数器和一个M24计数器级联构成计时器
需实现使能和同步复位
(3)可使用一个7位D触发器、两个6位D触发器和一个5位D触发器并列构成冻结器
需实现使能(相当于24位D触发器)
计时与否(Timing=1/0)可由计时器的使能控制(状态输出)
清零(Reset)可由计时器的同步复位实现(事件输出)
冻结显示与否(Freeze=1/0)可由冻结器的使能实现(状态输出)
冻结显示的更新(Update单脉冲的使能信号)可由冻结器的使能实现(事件输出)
状态输出:由状态机的当前状态直接决定的输出
事件输出:仅在状态机状态转换时出现的输出
详细的状态转换和输出
需要做一个段位扫描输出(用手扫过可以判断是否使用了段位扫描)