输入in,输出out,对输入in维持的周期进行计数N;如果N<4,则out为0,如果N>4,则将out拉高,并保持N/4个周期数。
使用状态机:
c_state == 0 : IDLE
c_state 1 : 计数
c_state2:计算out高电平持续时间
c_state==3:拉高out
对于这个题目我有点疑惑的就是in的维持时间会不会累加(就是持续一段时间高,又一会低,再继续高),还有个疑惑是N/4这应该是取整吧。如果不是取整,我觉得就有点难了,涉及到分数了。
module c_j (
input clk,
input rst_n,
input in,
output reg out
);
reg [1:0] c_state;
reg [1:0] n_state;
parameter IDLE = 2'b00;
parameter CACULATE = 2'b01;
parameter HOLD = 2'b10;
parameter UP = 2'b11;
reg [7:0] cnt;
reg [7:0] cnt_sub;
reg in_1;
reg in_2;
wire pose_in;
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
in_1 <= 1'b0;
in_2 <= 1'b0;
end
else begin
in_1 <= in;
in_2 <= in_1;
end
end
assign pose_in = in_1 & (~in_2);
assign neg_in = ~(in_1) & in_2;
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
c_state <= IDLE;
end
else begin
c_state <= n_state;
end
end
always @ (*) begin
case(c_state)
IDLE : if(pose_in)
n_state <= CACULATE;
else
n_state <= IDLE;
CACULATE : if(neg_in)
n_state <= HOLD;
else
n_state <= CACULATE;
HOLD : if(cnt > 4) n_state <= UP;
else n_state <= IDLE;
UP : if(cnt_sub=='d0) n_state <= IDLE;
else n_state <= UP;
endcase
end
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
cnt <= 'd0;
end
else if(n_state==CACULATE) begin
cnt <= cnt + 1'b1;
end
else if(n_state==IDLE) begin
cnt <= 'd0;
end
end
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
cnt_sub <= 'd0;
end
else if(n_state==HOLD) begin
cnt_sub <= cnt >> 2;
end if(n_state==UP) begin
cnt_sub <= cnt_sub - 1'b1;
end
// else begin
// cnt_sub <='d0;
// end
end
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
out <= 1'b0;
end
else if(n_state==UP) begin
out <= 1'b1;
end
else begin
out <= 1'b0;
end
end
endmodule
测试代码:
`timescale 1ps/1ps
module tb();
reg in;
reg clk;
reg rst_n;
wire out;
c_j u1(
.clk(clk),
.in(in),
.rst_n(rst_n),
.out(out)
);
initial begin
rst_n = 0;
#15;
rst_n = 1;
end
initial begin
clk = 0;
in= 0;
#20;
in = 1;
#100;
in = 0;
end
always #5 clk = ~clk;
endmodule
这个代码就写的比较蠢了,但是功能实现了,还要啥自行车。