状态机与时钟分频
描述
题目描述:
使用状态机实现时钟分频,要求对时钟进行四分频,占空比为0.25
信号示意图:
clk为时钟
rst为低电平复位
clk_out 信号输出
Ps 本题题解是按照1000的状态转移进行的,不按照此状态进行,编译器可能报错但没有影
波形示意图:
输入描述:
clk为时钟
rst为低电平复位
输出描述:
clk_out 信号输出
解题思路
根据波形图的描述可得
本题中采用的时钟分频的状态机本质上可以视为生成"1000"序列的序列发生器;
因此我们使用传统的有限状态机的三段式写法:
①进程一:同步时序always模块,格式化描述次态寄存器迁移到现态寄存器;
always @(posedge clk or negedge rst) begin
if (!rst) current_state <= IDLE;
else current_state <= next_state;
end
②进程二:组合逻辑always模块,描述次态转移条件判断
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模块,格式化描述次态寄存器输出
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
问题:
对于进程三,当使用如下代码时,会出现结果错误:
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时,不会报错:
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
完整代码如下:
`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
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » 【Verilog学习日常】—牛客网刷题—Verilog企业真题—VL65
发表评论 取消回复