难点易错点总结
- 状态机:总共10个状态,一开始写了11个状态,发现从B4跳变到CUNT的状态多余,并且时序不符合题目要求,会延迟一个时钟周期输出count信号
- count信号:该信号每计数够1000就减一,同时要求进入CUNT状态的第一个周期就要输出count数据。要满足此要求,唯有将上个状态(D4)的data_r信号直接输出。
代码
module top_module (
input clk,
input reset,
input data,
output [3:0] count,
output counting,
output done,
input ack );
parameter IDLE = 4'd0;
parameter B1 = 4'd1;
parameter B2 = 4'd2;
parameter B3 = 4'd3;
parameter B4 = 4'd4;
parameter D1 = 4'd5;
parameter D2 = 4'd6;
parameter D3 = 4'd7;
parameter D4 = 4'd8;
parameter CUNT = 4'd9;
parameter DONE = 4'd10;
reg [3:0] state, next_state;
reg [3:0] data_r;
reg [3:0] data_rr;
reg [14:0] count_d;
wire c_flag;
always @(posedge clk)begin
if(reset)
state <= IDLE;
else
state <= next_state;
end
always @*begin
case(state)
IDLE : next_state = data ? B1 : IDLE;
B1 : next_state = data ? B2 : IDLE;
B2 : next_state = data ? B2 : B3;
B3 : next_state = data ? D1 : IDLE;
D1 : next_state = D2;
D2 : next_state = D3;
D3 : next_state = D4;
D4 : next_state = CUNT;
CUNT : next_state = c_flag ? DONE : CUNT;
DONE : next_state = ack ? IDLE : DONE;
default : next_state = 'x;
endcase
end
always @(posedge clk)begin
if(reset)begin
data_r <= 0;
count_d <= 0;
end
else
case(state)
D1 : data_r[3] <= data;
D2 : data_r[2] <= data;
D3 : data_r[1] <= data;
D4 : begin
data_r[0] <= data;
data_rr <= {data_r[3:1], data};
end
CUNT: begin
count_d <= count_d +1'b1;
case(count_d)
999: data_r <=data_r -1'b1;
1999: data_r <=data_r -1'b1;
2999: data_r <=data_r -1'b1;
3999: data_r <=data_r -1'b1;
4999: data_r <=data_r -1'b1;
5999: data_r <=data_r -1'b1;
6999: data_r <=data_r -1'b1;
7999: data_r <=data_r -1'b1;
8999: data_r <=data_r -1'b1;
9999: data_r <=data_r -1'b1;
10999: data_r <=data_r -1'b1;
11999: data_r <=data_r -1'b1;
12999: data_r <=data_r -1'b1;
13999: data_r <=data_r -1'b1;
14999: data_r <=data_r -1'b1;
15999: data_r <=data_r -1'b1;
endcase
end
default: count_d <= 0;
endcase
end
assign c_flag = (count_d == (data_rr+1'b1)*1000-1);
assign counting = (state == CUNT);
assign done = (state == DONE);
assign count = data_r;
endmodule