【Verilog学习日常】—牛客网刷题—Verilog企业真题—VL65

状态机与时钟分频

描述

题目描述:

使用状态机实现时钟分频,要求对时钟进行四分频,占空比为0.25

信号示意图:

clk为时钟

rst为低电平复位

clk_out 信号输出

Ps 本题题解是按照1000的状态转移进行的,不按照此状态进行,编译器可能报错但没有影

波形示意图:

输入描述:

clk为时钟

rst为低电平复位

输出描述:

clk_out 信号输出

解题思路

根据波形图的描述可得

本题中采用的时钟分频的状态机本质上可以视为生成"1000"序列的序列发生器;

因此我们使用传统的有限状态机的三段式写法:

①进程一:同步时序always模块,格式化描述次态寄存器迁移到现态寄存器;

cpp 复制代码
always @(posedge clk or negedge rst) begin
	if (!rst)	current_state <= IDLE;
	else		current_state <= next_state;
end

②进程二:组合逻辑always模块,描述次态转移条件判断

cpp 复制代码
always @(*) begin
	case(current_state)
	IDLE:	next_state = S1;
	S1:		next_state = S2;
	S2:     next_state = S3;
	S3:     next_state = IDLE;
	default:next_state = IDLE;
	endcase
end

③进程三:同步时序always模块,格式化描述次态寄存器输出

cpp 复制代码
always @(posedge clk or negedge rst) begin
	if (!rst) clk_out <= 1'b0;
	else begin
	case (next_state)
	IDLE: clk_out <= 1'b0;
	S1:	  clk_out <= 1'b1;
	S2:	  clk_out <= 1'b0;
	S3:   clk_out <= 1'b0;
	default:clk_out <= 1'b0;
	endcase
	end
end

问题:

对于进程三,当使用如下代码时,会出现结果错误:

cpp 复制代码
always @(posedge clk or negedge rst) begin
	if (!rst) clk_out <= 1'b0;
	else begin
	case (next_state)
	IDLE: clk_out <= 1'b1;
	S1:	  clk_out <= 1'b0;
	S2:	  clk_out <= 1'b0;
	S3:   clk_out <= 1'b0;
	default:clk_out <= 1'b0;
	endcase
	end
end

而将case中的next_state换成current_state时,不会报错:

cpp 复制代码
always @(posedge clk or negedge rst) begin
	if (!rst) clk_out <= 1'b0;
	else begin
	case (current_state)
	IDLE: clk_out <= 1'b1;
	S1:	  clk_out <= 1'b0;
	S2:	  clk_out <= 1'b0;
	S3:   clk_out <= 1'b0;
	default:clk_out <= 1'b0;
	endcase
	end
end

完整代码如下:

cpp 复制代码
`timescale 1ns/1ns

module huawei7(
	input wire clk  ,
	input wire rst  ,
	output reg clk_out
);

//*************code***********//

reg [1:0] current_state, next_state;
//设置状态名称
parameter [1:0] IDLE = 2'b00;
parameter [1:0] S1 = 2'b01;
parameter [1:0] S2 = 2'b11;
parameter [1:0] S3 = 2'b10;

always @(posedge clk or negedge rst) begin
	if (!rst)	current_state <= IDLE;
	else		current_state <= next_state;
end

always @(*) begin
	case(current_state)
	IDLE:	next_state = S1;
	S1:		next_state = S2;
	S2:     next_state = S3;
	S3:     next_state = IDLE;
	default:next_state = IDLE;
	endcase
end

always @(posedge clk or negedge rst) begin
	if (!rst) clk_out <= 1'b0;
	else begin
	case (next_state)
	IDLE: clk_out <= 1'b0;
	S1:	  clk_out <= 1'b1;
	S2:	  clk_out <= 1'b0;
	S3:   clk_out <= 1'b0;
	default:clk_out <= 1'b0;
	endcase
	end
end

//*************code***********//
endmodule
相关推荐
全栈道3 小时前
AI 时代,软件开发应该如何学习
人工智能·学习
存在morning3 小时前
【OLAP 学习笔记】Doris:数据湖之上的分析查询引擎
笔记·学习
代码山河3 小时前
Java语言特点:跨平台、面向对象、安全性详解
java·学习·架构·教程·面向对象·项目
每天题库3 小时前
登高架设作业考试题库大全 核心考点真题刷题备考通关秘籍
学习·安全·考试·题库·考证
andrsted4 小时前
练题簿在线免费刷题:听读练题支持暂停续播、循环播放,让自己的题库听得更方便
学习·微信小程序·小程序·刷题·在线刷题
李日华大战鸡红15 小时前
FOC状态空间方程模型推导(学习记录)
python·学习·线性代数
kkkkkkkkkk_Z17 小时前
新手自学嵌入式 | 学习日记:异常与中断基础、i.MX6ULL裸机开发环境搭建、GPIO模块与点灯原理
学习
m4Rk_17 小时前
【论文阅读】Agent 记忆机制(94):MemGen——在推理过程中动态生成并织入潜在记忆
论文阅读·人工智能·学习·开源·github
晓德17 小时前
0、LLM大模型安全学习系列(启)
学习·安全
Titan202418 小时前
MySQL索引学习笔记
笔记·学习·mysql