NEXYS 4: Signal Disappearing Across Wire in Port Instantiation

82 views Asked by At

I'm trying to make a stopwatch that is able to count from 0:00.0 to 9:99.9 with (1/10) second precision.

My stopwatch works by giving each digit its own binary counter (provided by Vivado's IP catalog) that works on a clock and enable signal. When a particular digit resets back to zero (so transitions from a 9 to a 0 for instance) it sends a pulse to the next digit telling it to count up by one.

I gave each digit its own module and connected the ports to each other via the top module.

The problem is the deci-seconds spot counts up perfectly, but the following digit stays zero. After simulating the design I found out that the signal being sent by the first digit isn't being received by the next digit.

I've checked my module instantiations sytax and port connections and didn't see an error. I've even mapped the output pulse of the first digit onto some LEDs and they lit up perfectly fine. So I'm assuming the error is on the recieving end of the second digit. I'm not sure why this is going on however.

DIGIT 1 MODULE:

// module that contains both digit 1 counter and decimal converter
module digit_1(
    input clk_10_Hz, clk_100_Hz, reset,
    output [7:0] digit_1_out,
    output [3:0] Q_1
    );

    c_counter_binary_9_count COUNTER_9 (.CLK(clk_100_Hz),.CE(clk_10_Hz),.SCLR(reset),.Q(Q_1));
    digit_1_bcd_to_decimal CONVERTER_DIGIT_1 (.Q_1,.clk_100_Hz,.digit_1_out);

endmodule

DIGIT 2 MODULE:

// module that contains both digit 2 counter and decimal converter
module digit_2(
    input clk_100_Hz, reset,
    input [3:0] Q_1,
    output [7:0] digit_2_out,
    output [3:0] Q_2
    );

reg THRESH1;
reg test_CE_2;

c_counter_binary_9_count COUNTER_9 (.CLK(clk_100_Hz),.CE(test_CE_2),.SCLR(reset),.Q(Q_2));
digit_2_bcd_to_decimal CONVERTER_DIGIT_2 (.Q_2,.clk_100_Hz,.digit_2_out);

// ensures that clock pulse will only be length of 100 Hz clock pulse 
always @ (negedge clk_100_Hz)
    if (Q_1 == 4'h9)
        THRESH1 = 1;
    else
        THRESH1 = 0;

always @ (posedge clk_100_Hz)
    if (THRESH1)
        begin
        if (Q_1 == 4'h0)
            test_CE_2 = 1;
        else
            test_CE_2 = 0;
        end
    else
        test_CE_2 = 0;

endmodule

TOP MODULE:

// TOP module - combines all the other modules with each other
module stop_watch(
    input clk_100_MHz, reset, enable,
    output [7:0] an, display
    );

    wire clk_10_Hz, clk_100_Hz, clk_250_Hz;
    wire [7:0] digit_1_out ,digit_2_out,digit_3_out,digit_4_out; // connects digit outputs with display selector

    wire [3:0] Q_1, Q_2, Q_3; // connects outpus of binary counter with inputs of others

    clock CLOCK (.clk_100_MHz,.enable,.clk_10_Hz,.clk_100_Hz,.clk_250_Hz);

    digit_1 DIGIT_1 (.clk_10_Hz,.clk_100_Hz,.reset,.Q_1,.digit_1_out);
    digit_2 DIGIT_2 (.clk_100_Hz,.reset,.Q_1,.Q_2,.digit_2_out);
    digit_3 DIGIT_3 (.clk_100_Hz,.reset,.Q_2,.Q_3,.digit_3_out);
    digit_4 DIGIT_4 (.clk_100_Hz,.reset,.Q_3,.digit_4_out);

    anode_frequency ANODE_FREQUENCY (.clk_250_Hz,.an);
    display_selector DISPLAY_SELECTOR (.an,.digit_1_out,.digit_2_out,.digit_3_out,.digit_4_out,.display);

endmodule

The whole code is around 400 lines so I only put the parts of interest but I could put the whole code if requested.

I'm using Vivado 2014.1 and the FPGA board is the NEXYS 4.

1

There are 1 answers

4
wilcroft On BEST ANSWER

Firstly, since the counter is posedge triggered, you'll want your enable signal to be active from negedge-to-negedge around the intended rising edge, to avoid potential timing violations. (See comments below)

Secondly, to ensure your counters "tick-up" in-sync, you'll want the enables to be aligned - something along the lines of :

if (Q_1 == 9 && Q_1_Enable)
  Q_2_Enable = 1;
else
  Q_2_Enable = 0;

This way, Counter 2 increments on the same cycle counter one transitions from 9->0.

Lastly, unless your 10Hz clock is on a 10% duty cycle, your "deci-second" counter will actually be ticking up 5 times/second, instead of 1 time/demisecond. Regardless, in may be better - if you have to option - to use only the 10Hz clock for all counters, at which point your enable signals become simple.

/*  always @ (negedge clk_10_Hz) *No need for edge-triggered* */
always @ (*)
begin
   // Q_1_Enable is always 1(true) if using a 10 Hz clock
   if (Q_1 == 9)
     Q_2_Enable = 1;
   else 
     Q_2_Enable = 0;
   if (Q_2 == 9 && Q_2_Enable)
     Q_3_Enable = 1;
   else
     Q_3_Enable = 0;
   if (Q_3 == 9 && Q_3_Enable)
    ...