0

我正在尝试制作一个能够以 (1/10) 秒精度从 0:00.0 计数到 9:99.9 的秒表。

我的秒表通过为每个数字提供自己的二进制计数器(由 Vivado 的 IP 目录提供)来工作,该计数器在时钟和启用信号上工作。当一个特定的数字重置为零(例如从 9 转换为 0)时,它会向下一个数字发送一个脉冲,告诉它加一。

我给每个数字一个自己的模块,并通过顶部模块将端口相互连接。

问题是十进制点数完美,但后面的数字保持为零。在模拟设计后,我发现第一个数字发送的信号没有被下一个数字接收。

我检查了我的模块实例化语法和端口连接,没有看到错误。我什至将第一个数字的输出脉冲映射到一些 LED 上,它们亮得非常好。所以我假设错误出现在第二个数字的接收端。但是,我不确定为什么会这样。

数字 1 模块:

// 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

数字 2 模块:

// 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 - 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

整个代码大约 400 行,所以我只放了感兴趣的部分,但如果需要,我可以放整个代码。

我使用的是 Vivado 2014.1,FPGA 板是 NEXYS 4。

4

1 回答 1

0

首先,由于计数器是摆位触发的,因此您希望您的使能信号在预期的上升沿附近从反边到反边处于活动状态,以避免潜在的时序违规。见下面的评论

其次,为确保您的计数器“同步”同步,您需要对齐使能 - 类似于:

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

这样,计数器 2 在从 9->0 转换的同一周期计数器上递增。

最后,除非您的 10Hz 时钟的占空比为 10%,否则您的“十进制”计数器实际上会以 5 次/秒的速度递增,而不是 1 次/分秒。无论如何,如果您必须选择,可能会更好 - 对所有计数器仅使用 10Hz 时钟,此时您的启用信号变得简单。

/*  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)
    ...
于 2015-06-28T03:50:16.553 回答