tdc state machine

This commit is contained in:
2020-10-26 16:06:00 -05:00
parent 74dd3fb1d8
commit 4886fad4b2
3 changed files with 163 additions and 42 deletions

81
tdc/rtl/tdc.v Normal file
View File

@@ -0,0 +1,81 @@
`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:

View File

@@ -1,25 +1,42 @@
`default_nettype none
module top(i_clk, o_led, o_led_row_0);
parameter WIDTH = 24;
input wire i_clk;
output wire o_led;
output wire o_led_row_0;
module top #(parameter WIDTH=24)(
input wire i_clk,
output wire o_led,
input wire i_start,
input wire i_stop,
input wire i_resetN,
output wire o_ready,
output wire [15:0] o_data,
output wire o_led_row_0
);
wire clk_12MHz;
reg buf_led = 0;
clk_gen clk_gen_0 (/*autoinst*/
// Outputs
.o_clk (clk_12MHz),
// Inputs
.i_clk (i_clk));
// Outputs
.o_clk (clk_12MHz),
// Inputs
.i_clk (i_clk));
tdc tdc0(/*autoinst*/
// Outputs
.o_ready (o_ready),
.o_data (o_data[15:0]),
// Inputs
.i_clk (clk_12MHz),
.i_start (i_start),
.i_stop (i_stop),
.i_reset (~i_resetN));
reg [WIDTH-1:0] counter;
always @(posedge clk_12MHz)
always @(posedge clk_12MHz) begin
counter <= counter + 1'b1;
buf_led <= counter[WIDTH-1];
end
assign o_led = counter[WIDTH-1];
assign o_led = ~buf_led;
assign o_led_row_0 = 1'b0;
endmodule

View File

@@ -5,43 +5,66 @@
#include "Vtop.h"
void tick(int tickcount, Vtop *tb, VerilatedVcdC* tfp) {
tb->eval();
if (tfp)
tfp->dump(tickcount * 10 - 2);
tb->i_clk = 1;
tb->eval();
if (tfp)
tfp->dump(tickcount * 10);
tb->i_clk = 0;
tb->eval();
if (tfp) {
tfp->dump(tickcount * 10 + 5);
tfp->flush();
}
tb->eval();
if (tfp)
tfp->dump(tickcount * 10 - 2);
tb->i_clk = 1;
tb->eval();
if (tfp)
tfp->dump(tickcount * 10);
tb->i_clk = 0;
tb->eval();
if (tfp) {
tfp->dump(tickcount * 10 + 5);
tfp->flush();
}
}
int main(int argc, char **argv) {
// Call commandArgs first!
Verilated::commandArgs(argc, argv);
// Call commandArgs first!
Verilated::commandArgs(argc, argv);
// Instantiate our design
Vtop *tb = new Vtop;
Verilated::traceEverOn(true);
VerilatedVcdC* tfp = new VerilatedVcdC;
// Instantiate our design
Vtop *tb = new Vtop;
Verilated::traceEverOn(true);
VerilatedVcdC* tfp = new VerilatedVcdC;
tb->trace(tfp, 00);
tfp->open("build/waveform.vcd");
tb->trace(tfp, 00);
tfp->open("build/waveform.vcd");
unsigned tickcount = 0;
int last_led = tb->o_led;
tb->i_resetN = 1;
tb->i_start = 0;
tb->i_stop = 0;
unsigned tickcount = 0;
int last_led = tb->o_led;
for (int k = 0; k < 2; k++)
tick(++tickcount, tb, tfp);
for(int k=0; k<(1 << 12); k++) {
tick(++tickcount, tb, tfp);
tb->i_resetN = 0;
tick(++tickcount, tb, tfp);
tb->i_resetN = 1;
if (last_led != tb->o_led) {
printf("k = %7d, led = %d\n", k, tb->o_led);
}
for (int k = 0; k < 3; k++)
tick(++tickcount, tb, tfp);
last_led = tb->o_led;
}
tb->i_start = 1;
tick(++tickcount, tb, tfp);
tb->i_start = 0;
for (int k = 0; k < 15; k++)
tick(++tickcount, tb, tfp);
tb->i_stop = 1;
tick(++tickcount, tb, tfp);
tb->i_stop = 0;
for (int k = 0; k < 3; k++)
tick(++tickcount, tb, tfp);
tb->i_resetN = 0;
tick(++tickcount, tb, tfp);
tb->i_resetN = 1;
for (int k = 0; k < 3; k++)
tick(++tickcount, tb, tfp);
}