【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
相关推荐
unicrom_深圳市由你创科技8 小时前
项目分析和FPGA器件选型外包服务包括哪些内容?别让选错芯片毁了整个项目
fpga开发
charlie1145141919 小时前
现代Qt开发教程(新手篇)1.10——进程
开发语言·c++·qt·学习
绿豆人9 小时前
Cache缓存项目学习2
学习·缓存
山楂树の9 小时前
H.265 (HEVC) 视频解码转逐帧图像 完整实现方案
学习·音视频·h.265
星幻元宇VR9 小时前
VR观景台推动安全科普走向沉浸体验
科技·学习·安全·vr·虚拟现实
Aaron15889 小时前
27DR/47DR/67DR技术对比及应用分析
人工智能·算法·fpga开发·硬件架构·硬件工程·信息与通信·基带工程
十安_数学好题速析9 小时前
【多选】成比之道:巧解三角形中比例综合
笔记·学习·高考
嵌入式小企鹅9 小时前
RISC-V车规专委会成立、AI模型集中开源、半导体产能加速爬坡
人工智能·学习·ai·程序员·算力·risc-v·半导体
我想我不够好。9 小时前
消防监控学习 4.30 1.5hour
学习
全栈工程师修炼指南9 小时前
Moodle | ‌开源学习管理系统简体中文包安装配置
学习·开源