简体   繁体   English

尝试设计一个8位可重载递减计数器

[英]Trying to design an 8-bit reloadable down counter

Task: Designing a 8-bit downcounter which takes an initial input value and start the downcount, and when count becomes 8'b0000_0000, it should automatically set to input value.任务:设计一个 8 位递减计数器,它接受一个初始输入值并开始递减计数,当计数变为 8'b0000_0000 时,它应该自动设置为输入值。

Ex: If given input is 8'b10010100, counter should start counting down, when value reaches 8'00000000, it should automatically reset to 8'b10010100, and again start downcount repeatedly.例:给定输入8'b10010100,计数器开始递减计数,当数值达到8'00000000时,自动复位为8'b10010100,再次开始递减计数。 For this had written a modified D flip flop using behavioral method, which works as follows: When ld=0, output of d-flip flop q=d1 and q_bar=~d1 and when ld=1, q=d2 and q_bar=~d2 Here d2 stores the initial input values, and ld is being used as switch, ie when q=8'b00000000, ld=1 and sets counter output q=d2 and next cycle, ld=0 and takes d1 value.为此用行为法写了一个修改过的D触发器,其工作原理如下: 当ld=0时,d触发器的output q=d1 and q_bar=~d1 and when ld=1, q=d2 and q_bar=~ d2 这里d2存储初始输入值,ld用作开关,即当q=8'b00000000时,ld=1并设置计数器output q=d2和下一个循环,ld=0并取d1值。

Modified D-flip flop改进的 D 型触发器

module modified_d_flip_flop(q,q_bar,d1,d2,clk,ld
    );
    input d1,d2,clk,ld;
    output q,q_bar;
    reg q,q_bar;
    always @(posedge clk)
        begin
                if(ld==0)
                begin
                q<=d1;
                q_bar<=~d1;
                end
            else if(ld==1)
                begin
                q<=d2;
                q_bar<=~d2;
                end
            else
                begin
                q<=q;
                q_bar<=q_bar;
                end
            end
    endmodule

Down Counter:递减计数器:

module down_counter(
    input [7:0] d,
    input clk,
    input ld,
    output [7:0] q,
    output [7:0] q_bar
    );      
    modified_d_flip_flop m_dff1 (.q(q[0]), .q_bar(q_bar[0]), .d1(q_bar[0]), .d2(d[0]), .clk(clk), .ld(ld));
    modified_d_flip_flop m_dff2 (.q(q[1]), .q_bar(q_bar[1]), .d1(q_bar[1]), .d2(d[1]), .clk(q[0]), .ld(ld));
    modified_d_flip_flop m_dff3 (.q(q[2]), .q_bar(q_bar[2]), .d1(q_bar[2]), .d2(d[2]), .clk(q[1]), .ld(ld));
    modified_d_flip_flop m_dff4 (.q(q[3]), .q_bar(q_bar[3]), .d1(q_bar[3]), .d2(d[3]), .clk(q[2]), .ld(ld));
    modified_d_flip_flop m_dff5 (.q(q[4]), .q_bar(q_bar[4]), .d1(q_bar[4]), .d2(d[4]), .clk(q[3]), .ld(ld));
    modified_d_flip_flop m_dff6 (.q(q[5]), .q_bar(q_bar[5]), .d1(q_bar[5]), .d2(d[5]), .clk(q[4]), .ld(ld));
    modified_d_flip_flop m_dff7 (.q(q[6]), .q_bar(q_bar[6]), .d1(q_bar[6]), .d2(d[6]), .clk(q[5]), .ld(ld));
     modified_d_flip_flop m_dff8 (.q(q[7]), .q_bar(q_bar[7]), .d1(q_bar[7]), .d2(d[7]), .clk(q[6]), .ld(ld));
    endmodule

Down counter Test Bench倒柜试验台

 module down_counter_tb;

    reg [7:0] d;
    reg clk;
    reg ld;

    wire [7:0] q;
    wire [7:0] q_bar;

    down_counter uut (
        .d(d), 
        .clk(clk),
        .ld(ld),
        .q(q), 
        .q_bar(q_bar)
    );
        always #5 clk = ~clk;
    initial begin
        clk = 1;
        ld = 1;
        d = 8'b00000111;
        end
    initial begin
        #20 ld = 0;
        #20 ld = 1;
        #30 ld = 0;
     end
     endmodule

Issue: If initial input ie d2=8'b11111111, then i am getting the downcounter it works properly for the above code, But if i give some thing like d2=8'10010011, then counter starts from 011, 010, 001 and 111, 110, 101, ........ it counts only the number of high bits from lsb + 1, if 0 is encountered next values till msb becomes x.问题:如果初始输入即 d2=8'b11111111,那么我得到的向下计数器对于上面的代码可以正常工作,但是如果我给出类似 d2=8'10010011 的东西,那么计数器从 011、010、001 和 111 开始, 110, 101, ....... 它只计算从 lsb + 1 开始的高位数,如果遇到 0 下一个值,直到 msb 变为 x。

enter image description here在此处输入图像描述

enter image description here在此处输入图像描述

enter image description here在此处输入图像描述

ld function too is not working as expected, when ld =0 instead of reset counter to initial input, it stops counter and starts it once ld =0. ld function 也没有按预期工作,当ld =0 而不是将计数器重置为初始输入时,它会停止计数器并在ld =0 后启动它。

Your code is too hard to debug because you are not designing at the proper level of abstraction.您的代码很难调试,因为您没有在适当的抽象级别进行设计。 You should always use the highest level of abstraction to make the design easier to understand.您应该始终使用最高级别的抽象以使设计更易于理解。 Instead of designing an individual flip-flop then trying to connect them together, just design a simple counter.与其设计一个单独的触发器然后尝试将它们连接在一起,不如设计一个简单的计数器。

With all those module instance connections, you may have a simple connection bug.对于所有这些模块实例连接,您可能会遇到一个简单的连接错误。

Another potential issue is a simulation race condition.另一个潜在的问题是模拟竞争条件。 Every flip-flop uses a different clock signal.每个触发器使用不同的时钟信号。

Here is a common way to design a synchronous counter.下面介绍一种设计同步计数器的常用方法。 It uses the same clock for all flops of the counter:它对计数器的所有触发器使用相同的时钟:

module down_counter (
    input [7:0] d,
    input clk,
    input ld,
    output reg [7:0] q
);      

always @(posedge clk) begin
    if (ld || (q == 0)) begin
        q <= d;
    end else begin
        q <= q - 1;
    end
end
endmodule

module down_counter_tb;
    reg [7:0] d;
    reg clk;
    reg ld;
    wire [7:0] q;

    down_counter uut (
        .d(d), 
        .clk(clk),
        .ld(ld),
        .q(q)
    );

    always #5 clk = ~clk;

    initial begin
        clk = 1;
        ld  = 1;
        d   = 7;

        repeat (2) @(posedge clk);
        ld <= 0;

        repeat (15) @(posedge clk);
        ld <= 0;
        d  <= 8'b1001_0011;
        repeat (1) @(posedge clk);
        ld <= 0;

        repeat (500) @(posedge clk);
        $finish;
    end
endmodule

By using nonblocking assignments ( <= ) and driving the inputs on @(posedge clk) in the testbench (as is done in the design), we also avoid race conditions in the testbench.通过使用非阻塞分配 ( <= ) 并在测试台中驱动@(posedge clk)上的输入(正如在设计中所做的那样),我们还避免了测试台中的竞争条件。

You didn't provide a thorough description of the ld signal.您没有提供ld信号的详尽描述。 The code I showed loads the counter with the 8-bit input data ( d ) when ld =1.ld = 1 时,我展示的代码使用 8 位输入数据 ( d ) 加载计数器。 When ld =0, the counter counts down.ld =0 时,计数器递减计数。 When it reaches 0, the counter is automatically reloaded with d .当它达到 0 时,计数器会自动重新加载d

Thanks @toolic谢谢@toolic

You code surely gave me an idea.你的代码肯定给了我一个想法。 Modified it a little to solve my issue稍微修改一下以解决我的问题

I am trying to design a frequency divider for my project for that i needed this downcounter.我正在尝试为我的项目设计一个分频器,因为我需要这个下计数器。

ld - Use was to make the counter reset to my expected value when ld=0 and again make ld=1 next cycle to start the downcount and again when downcounter value became 0, make ld=0 to reset the counter to expected value. ld - 用于在 ld=0 时使计数器重置为我的预期值,并在下一个周期再次使 ld=1 以开始向下计数,当向下计数器值变为 0 时再次使 ld=0 将计数器重置为预期值。 This had to go on forever.这必须永远保持 go。

In your testbench we have to set it many times.在您的测试台中,我们必须多次设置它。 I just wanted to give one initial value and i wanted it to run forever.我只是想给一个初始值,我希望它永远运行。

I modified your code, to get my desired result.我修改了您的代码,以获得我想要的结果。 I removed ld and added, initial q = 0我删除了 ld 并添加了初始 q = 0

Down Counter递减柜台

module down_counter( 
 input [7:0] d,
 input clk,
 output reg [7:0] q
);
 
 initial q = 0;
 
 always @(posedge clk)
    begin
    if (q == 0)
        begin
        q <= d;
        end
    else 
        begin
        q <= q-1;
        end
    end
endmodule

Testbench:试验台:

module down_counter_tb;

// Inputs
reg [7:0] d;
reg clk;

// Outputs
wire [7:0] q;

// Instantiate the Unit Under Test (UUT)
down_counter uut (
    .d(d), 
    .clk(clk), 
    .q(q)
);

always #5 clk=~clk;

initial begin
    // Initialize Inputs
    d = 8'b00000100;
    clk = 1;

end
  
endmodule

Waveform:波形: 当它变为 0 时,它会一次又一次地自动设置为 4

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM