SV 和 JK 触发器的 BCD 计数器实现问题

问题描述 投票:0回答:1

我正在努力使用 T 触发器(JK,J=K=1)在 SystemVerilog 中实现 BCD 计数器。目标是从 0 计数到 9,然后重置回 0。我使用 JK 触发器的 clr 输入,打算在计数达到 4'b1010 时重置触发器。然而,我面临一个问题,在到达 4'b1010 时,计数器重置为 4 而不是 0。

经调查,该问题似乎可能与第三个触发器有关,因为它将always_ff块中的两个条件评估为true。

我的顶级设计:

    module bcdCounter(
    input logic clk,
    input logic rst,
    output logic Q0,
    output logic Q1,
    output logic Q2,
    output logic Q3,
    output [3:0] out
    );
    
    
    assign out = {Q3,Q2,Q1,Q0};
    
    logic clr;
    assign clr = ~(Q3 & Q1);
    // $monitor("the value of clr is %0d and Q3 is %d and Q1 is %d", clr,Q3,Q1);
    jkFlipFlop flipFlop1(.J(1'b1), .K(1'b1), .rst(rst), .clk(clk), .clr(clr), .Q(Q0));
    jkFlipFlop flipFlop2(.J(1'b1), .K(1'b1), .rst(rst), .clk(Q0), .clr(clr), .Q(Q1));
    jkFlipFlop flipFlop3(.J(1'b1), .K(1'b1), .rst(rst), .clk(Q1), .clr(clr), .Q(Q2));
    jkFlipFlop flipFlop4(.J(1'b1), .K(1'b1), .rst(rst), .clk(Q2), .clr(clr), .Q(Q3));
    
endmodule

翻牌代码:

module jkFlipFlop(
    input logic J,
    input logic K,
    input logic rst,
    input logic clk,
    input logic clr,
    output logic Q
    );
    
    always_ff @(negedge clk, negedge clr ,posedge rst) begin
        if (rst) begin
            Q <= 1'b0;
        end
        else if(clr == 1'b0) begin
            Q <= 1'b0;
        end
        else if(clr != 1'b0 )begin   
            case ({J,K})
                2'b00: Q <= Q;
                2'b01: Q <= 1'b0;
                2'b10: Q <= 1'b1;
                2'b11: Q <= ~Q; 
             endcase
        end
    end    
endmodule

TB:

module bcdTB();
    logic clk,rst,Q0,Q1,Q2,Q3;
    logic [3:0] out;
    bcdCounter bcdCount(.clk(clk), .rst(rst), .Q0(Q0), .Q1(Q1), .Q2(Q2), .Q3(Q3),.out(out));
    always #40 clk = ~clk;
    
    initial begin
        clk = 1'b0;
        rst = 1'b0;
        #2 rst = 1'b1;
        #2 rst = 1'b0;
       
        #1000
        $finish;
    end
endmodule

模拟:

verilog system-verilog hdl
1个回答
0
投票

您有模拟竞争条件,因为您的代码没有遵循同步设计的推荐实践。您有 4 个时钟信号,但您应该只有一个。

我建议在更高的抽象级别设计计数器,用标准行为代码替换触发器实例:

module bcdCounter (
    input logic clk,
    input logic rst,
    output logic Q0,
    output logic Q1,
    output logic Q2,
    output logic Q3,
    output logic [3:0] out
    );
    
    assign {Q3,Q2,Q1,Q0} = out;

    always_ff @(negedge clk, posedge rst) begin
        if (rst) begin
            out <= 4'h0;
        end else if (out == 9) begin   
            out <= 4'h0;
        end else begin   
            out <= out + 1;
        end
    end    
endmodule

输出:

© www.soinside.com 2019 - 2024. All rights reserved.