82 lines
1.9 KiB
Verilog
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) 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:
|