fancytimer -- HDLBits Solution
Talk is cheap, show me the code :
module top_module (
input clk,
input reset, // Synchronous reset
input data,
output [3:0] count,
output counting,
output done,
input ack );
wire shift_ena,done_counting,count_ena;
wire [9:0] q;
fsm f1(clk,reset,data,shift_ena,counting,done_counting,done,ack);
sc sc1(clk,shift_ena,count_ena,data,count);
c1000 c1(clk,reset||!counting,q,count_ena);
assign done_counting= count_ena&&count==0;
endmodule
module c1000 (
input clk,
input reset,
output [9:0] q,
output co);
always@(posedge clk)
q<=reset|co?0:q+1;
assign co= q==999;
endmodule
module sc (
input clk,
input shift_ena,
input count_ena,
input data,
output [3:0] q);
always@(posedge clk)begin
if(shift_ena)
q<={q[2:0],data};
if(count_ena)
q<=q-1;
end
endmodule
module fsm (
input clk,
input reset, // Synchronous reset
input data,
output shift_ena,
output counting,
input done_counting,
output done,
input ack );
wire start_counting;
r1101 i(clk,reset||s!=0,data,shift_ena,start_counting);
reg [1:0] s;
parameter Count=1,Wait=2;
always@(posedge clk)begin
if(reset)
s<=0;
else begin
case(s)
0:
s<=start_counting?Count:0;
Count:
s<=done_counting?Wait:Count;
Wait:
s<=ack?0:Wait;
default:
s<=s;
endcase
end
end
assign counting= s==Count;
assign done= s==Wait;
endmodule
module r1101 (
input clk,
input reset, // Synchronous reset
input data,
output shift_ena,
output start_counting);
reg [2:0] s;
parameter S=0,S1=1,S11=2,S110=3,S1101=4;
always@(posedge clk)begin
if(reset)
s<=0;
else begin
case(s)
S:
s<=data?S1:S;
S1:
s<=data?S11:S;
S11:
s<=data?S11:S110;
S110:
s<=data?S1101:S;
// S1101:
// s<=s;
default:
s<=s+1;
endcase
end
end
assign shift_ena= s[2];
assign start_counting= s==7;
endmodule