Files
iceFun_Projects/tdc/rtl/tdc.v

82 lines
1.9 KiB
Verilog

`default_nettype none
module tdc #(parameter COUNTER_WIDTH=16)(
input wire i_clk,
input wire i_start,
input wire i_stop,
input wire i_reset,
output wire o_ready,
output wire [COUNTER_WIDTH-1:0] o_data
);
reg [COUNTER_WIDTH-1:0] counter;
assign o_data = counter;
// states
localparam state_idle = 2'b00;
localparam state_started = 2'b01;
localparam state_running = 2'b10;
localparam state_stopped = 2'b11;
reg [1:0] current_state, next_state;
// ensure that state changes each clock
always @(posedge i_clk, posedge i_reset) begin
if (i_reset) begin
current_state <= state_idle;
end else begin
current_state <= next_state;
end
end
// state logic
/* verilator lint_off COMBDLY */
always @(*) begin
case (current_state)
state_idle: begin
if (i_start && (~i_stop))
next_state <= state_started;
else
next_state <= state_idle;
end
state_started: begin
if (~i_start && (~i_stop))
next_state <= state_running;
else
next_state <= state_started;
end
state_running: begin
if (~i_start && (i_stop))
next_state <= state_stopped;
else
next_state <= state_running;
end
state_stopped: begin
if (i_reset)
next_state <= state_idle;
else
next_state <= state_stopped;
end
default : next_state <= current_state;
endcase
end
/* verilator lint_on COMBDLY */
// counter runs during running state only
always @(posedge i_clk) begin
case (current_state)
state_idle: counter <= 0;
state_started: counter <= 0;
state_running: counter <= counter + 1;
state_stopped: counter <= counter;
default : counter <= 0;
endcase
end
assign o_ready = (current_state == state_stopped);
endmodule
// Local Variables:
// verilog-library-directories:(".." "./rtl" ".")
// End: