module top_module (
input clk,
input reset, // Synchronous reset
input data,
output [3:0] count,
output counting,
output done,
input ack );
parameter [2:0] IDLE=3'b000,//IDLE
A=3'b001,//Receive1
B=3'b011,//Receive1
C=3'b010,//Receive0
D=3'b110,//Receive1
E=3'b100,//Data_shift fot 4cycles
F=3'b101,//count for 1000*(count+1)
G=3'b111;//done and wait for ack
reg [2:0] state,next_state;
reg [1:0] count_shift;
reg [9:0] count_1000cycles;
reg [3:0] count_out_reg;
always @(*) begin
case(state)
IDLE:next_state = data?A:IDLE;
A: next_state = data?B:IDLE;
B: next_state = data?B:C;
C: next_state = data?D:IDLE;
D: next_state = E;
E: next_state = (count_shift==2'b10)?F:E;
F: next_state = ((count_1000cycles==10'd999) & (!count_out_reg))?G:F ;
G: next_state = ack?IDLE:G;
default: next_state = IDLE;
endcase
end
always @(posedge clk) begin
if(reset) begin
state<=IDLE;
count_shift<=2'b00;
count_1000cycles<=10'b0000000000;
count_out_reg<=4'b0000;
end
else begin
state<=next_state;
case(state)
D: begin
count_out_reg<={count_out_reg[2:0],data};
count_shift<=2'b00;
count_1000cycles<=10'b0000000000;
end
E:begin
count_shift<=count_shift+1'b1;
count_out_reg<={count_out_reg[2:0],data};
count_1000cycles<=10'b0000000000;
end
F:begin
count_shift<=2'b00;
if(count_1000cycles==10'd999) begin
count_1000cycles<=10'd0;
count_out_reg<=count_out_reg-1'b1;
end
else
count_1000cycles<=count_1000cycles+1'b1;
end
default:begin
count_out_reg<=4'b0000;
count_shift<=2'b00;
count_1000cycles<=10'b0000000000;
end
endcase
end
end
assign count=count_out_reg;
assign counting = (state==F);
assign done = (state==G);
endmodule
各状态含义可在代码中查看含义。
其中1000*(count+1)有个很巧妙的点,在借鉴其他大佬,用一个1000的独立计数,count-1作为输出值,满足题意也避免了占用多比特和乘法电路。