編寫Verilog代碼:
輸入in,輸出為out,對輸入in維持的周期進行計數計數周期為N,如果N<4輸出out為0;如果N>4,則拉高out并保持N/4個周期數,限定out的輸出高電平數不大于6.
此題可以由狀态加上兩個計數器組成,狀态機有4個狀态分别為:
S_IDLE:初始狀态,
S_CNT:輸入信号高電平持續周期計數;
S_DE:判斷輸出高電平持續的周期數;
S_OUT:輸出out。
代碼,testbench以及仿真結果如下:
module count_in( out,in,clk,rst_n);
parameter S0=2'b00,
S1=2'b01,
S2=2'b10,
S3=2'b11;
input in,clk,rst_n;
output out;
reg out;
reg [2:0] current_state,next_state;
reg [4:0] N;
reg [2:0] width;
always@(posedge clk or negedge rst_n)
begin
if (!rst_n)
current_state<=S0;
else
current_state<=next_state;
end
always@(*)
begin
next_state=2'bxx;
case(current_state)
S0:begin
if (in==1'b1)
next_state=S1;
else
next_state=S0;
end
S1:begin
if (in==1'b1)
next_state=S1;
else
next_state=S2;
end
S2:begin
if (width==0)
next_state=S0;
else
next_state=S3;
end
S3:begin
if (width==0)
next_state=S0;
else
next_state=S3;
end
default:next_state=S0;
endcase
end
always @ (*)
begin
if (current_state==S3)
out=1'b1;
else
out=1'b0;
end
always @ (posedge clk or negedge rst_n)
begin
if (!rst_n)
N<=0;
else if (current_state==S1)
begin
if (N<=5'd24)
N<=N+1'b1;
else
N<=N;
end
else if (current_state==S0)
N<=0;
end
always @ (posedge clk or negedge rst_n)
begin
if (!rst_n)
width<=0;
else if (current_state==S1)
begin
if (N<4)
width<=0;
else if (N<8)
width<=3'b001;
else if (N<12)
width<=3'b010;
else if (N<16)
width<=3'b011;
else if (N<20)
width<=3'b100;
else if (N<24)
width<=3'b101;
else
width<=3'b110;
end
else if (current_state==S3)
width<=width-1'b1;
end
endmodule
module count_in_t;
reg clk,rst_n;
reg in;
wire out;
count_in U1(.clk(clk),.rst_n(rst_n),.in(in),.out(out));
initial
begin
clk=1'b0;
forever #10 clk=~clk;
end
initial
begin
rst_n=1'b1;
in=1'b0;
#10 rst_n=1'b0;
#10 rst_n=1'b1; in=1'b1;
#600 in=1'b0;
end
endmodule
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLxcjN2UzN0MTMxIzNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)