From 4886fad4b26884ab5ec5837965fbd3a18959a791 Mon Sep 17 00:00:00 2001 From: Nam Tran Date: Mon, 26 Oct 2020 16:06:00 -0500 Subject: [PATCH] tdc state machine --- tdc/rtl/tdc.v | 81 ++++++++++++++++++++++++++++++++++++++++++++++++ tdc/rtl/top.v | 41 +++++++++++++++++-------- tdc/sim/top.cc | 83 ++++++++++++++++++++++++++++++++------------------ 3 files changed, 163 insertions(+), 42 deletions(-) create mode 100644 tdc/rtl/tdc.v diff --git a/tdc/rtl/tdc.v b/tdc/rtl/tdc.v new file mode 100644 index 0000000..da94770 --- /dev/null +++ b/tdc/rtl/tdc.v @@ -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: diff --git a/tdc/rtl/top.v b/tdc/rtl/top.v index 3f1c2be..f18a565 100644 --- a/tdc/rtl/top.v +++ b/tdc/rtl/top.v @@ -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 diff --git a/tdc/sim/top.cc b/tdc/sim/top.cc index 449c98c..73a336f 100644 --- a/tdc/sim/top.cc +++ b/tdc/sim/top.cc @@ -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); }