[学习笔记]时钟同步状态机的设计流程

1 理论

时序电路的设计就是已知命题,设计出完成该命题的电路,时钟同步状态机的设计过程大致可以分为以下几个步骤:

  • 根据题目要求,构造原始的状态图或构造原始的状态表;
  • 构建状态转移表,进行状态化简
  • 根据状态转移表画卡诺图求解,求出电路的状态方程、激励方程和输出方程;
  • 若有未用的状态还需要判断状态是否自启动,若不能自启动需要修改状态转移表;
  • 用HDL语言描述电路。

2 举例说明

设计一个序列发生器,在时钟的作用下,要求产生一个11001这样的一个序列。

2.1 状态转移图

在这里插入图片描述
"/“左边表示当前状态是“000”,”/"右边表示输出。

2.2 状态转移表

由此可以得到其状态转移表

状态转移表

2.3 卡诺图化简

Q0的次态:
Q0的次态
Q1的次态:
Q1的次态

Q2的次态
Q2的次态

由此可得转移方程:

Q0* = Q1 Q2

Q1* = Q1 Q2’ + Q1’ Q2

Q2* = Q0’ Q2’

以及输出方程 Z= Q1‘

2.4 判断是否有自启动

由于是三位二进制数Q0、Q1、Q2的状态转换,故一共有8种状态,这里出现了五种状态,还有101、110、111这三种状态未使用。

根据转移方程可以知道,这三种未用状态分别对应:
101 ——> 010
110 ——> 010
111 ——> 100

由此可以看出未用状态不能自己构成一个闭合的回路,那么该电路可以自启动。


3 用Verilog HDL实现序列发生器

module div_clk(
	input clk,
	input rst,
	output led
);

reg [25:0] cnt;
reg q0 = 0;
reg q1 = 0;
reg q2 = 0;

//分频
always @(posedge clk) begin
	if(~rst)		
		cnt <= 26'b0;
	else if (cnt == 26'd50) //原来是50_000_000,考虑仿真方便,更改为50,同理下面的25也类似
		cnt <= 26'b0;
	else
		cnt <= cnt + 26'b1;
end 

wire clk_1hz = (cnt>26'd25) ? 1'b1 : 1'b0;

//根据转移方程和状态方程进行设计

assign led = ~q1;
always @(posedge clk_1hz) begin
	if (~rst) begin
		q0 <= 0;
		q1 <= 0;
		q2 <= 0;
	end
	else begin
		q0 <= q1 & q2;
		q1 <= ~q1 & q2 | q1 & ~q2;
		q2 <= ~q0 & ~q2;
	end
end

endmodule

另一种方式实现分频:

`timescale 1us/1us

module clk1hz(
	input clk,
	input rst,
	output led
);

reg [25:0] clk_1hz;
reg [25:0] cnt;
reg q0 = 0;
reg q1 = 0;
reg q2 = 0;

//always @(posedge clk) begin和end之间的代码,执行频率是50Mhz,每0.02us(20ns)执行一次
//分频
always @(posedge clk) begin
	if (~rst) begin
		cnt <= 0;
		clk_1hz <= 0;
	end 
	else if(cnt == 26'd250) begin //25_000_000 
		clk_1hz <= ~clk_1hz; //
		cnt <= 0;
	end
	else
		cnt <= cnt + 1'b1;
end

//根据转移方程和状态方程进行设计

assign led = ~q1;
always @(posedge clk_1hz) begin
	if (~rst) begin
		q0 <= 0;
		q1 <= 0;
		q2 <= 0;
	end
	else begin
		q0 <= q1 & q2;
		q1 <= ~q1 & q2 | q1 & ~q2;
		q2 <= ~q0 & ~q2;
	end
end

endmodule

4 仿真

`timescale 1us/1us
module test_1;

reg clk;
reg reset;
wire led;

div_clk uut(
clk,
reset,
led
);

initial begin
	clk = 0;
	reset = 1'b1;
#35 reset = 1'b0;
#60 reset = 1'b1;
end

always #10 clk = ~clk;

endmodule

仿真截图

根据仿真截图中的led的变化,可以知道已经实现了11001这一序列发生器;
根据仿真截图中q0、q1、q2的变化,可以知道一共包含五种状态的变化。

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值