【问题标题】:Verilog counter does not trigger for different clock signalsVerilog 计数器不会针对不同的时钟信号触发
【发布时间】:2020-01-10 17:04:57
【问题描述】:

我正在尝试编写一个计数器,它只跟踪时钟的上升沿,并在它发生时增加一个变量。需要注意的是,该电路必须在不同的时钟源之间切换。计数器和时钟多路复用器的功能与模拟中的默认时钟一样,但计数器似乎没有看到第二个时钟信号的上升沿。我自己测试了多路复用器,它正确地传递了时钟信号。有什么想法吗?

顶层模块:

module hw1_top(reset, updown, inp, clkSwitch, Clk100MHz, testClock2, out);
input reset, updown, Clk100MHz, testClock2;
input [15:0] inp;
input [3:0] clkSwitch;

output [15:0] out;

wire muxtoclk;

ClockMux mux(
    .c1(Clk100MHz),
    .c2(testClock2),
    .switch(clkSwitch),
    .cOut(muxtoclk)
);

UDCounter counter(
    .RST(reset),
    .UD(updown),
    .INP(inp),
    .CLK(muxtoclk),
    .OUT(out)
);  
endmodule

计数器:

module UDCounter(RST, UD, INP, CLK, OUT);
input RST, UD, CLK; //1 bit inputs
input [15:0] INP; //16 bit input

output reg [15:0] OUT; //16 bit output, must be reg for sequential

initial
    OUT <= INP; //when we start, counter initializes to whatever the input is

always@(posedge CLK or posedge RST) //on every positive edge of the clock cycle, or if reset is triggered...
    if(RST == 1'b1) //if reset is high, set counter back to the initial input
        OUT <= INP;
    else //if reset isn't triggered...
        if(UD == 1'b0) //if up/down is in up position, count up
            begin
                OUT <= OUT + 1;
            end
        else //if in down, count down
            begin
                OUT <= OUT -1;
            end
endmodule

多路复用器:

module ClockMux(c1,c2,switch,cOut);switch,cOut);
input c1,c2;
input [3:0] switch;

output reg cOut;

always@(switch,c1,c2) //updates whenever the switch or clock changes
    case(switch)
        4'b0000: cOut <= c1;
        4'b0001: cOut <= c2;
    endcase
 endmodule

顶级测试平台和波形:

module hw1_top_tb();
reg reset, updown, Clk100MHz, testClock2;
reg [15:0] inp;

wire [15:0] out;
reg [3:0] switchValue;

hw1_top topmod(
    .reset(reset),
    .updown(updown),
    .inp(inp),
    .clkSwitch(switchValue),
    .Clk100MHz(Clk100MHz),
    .out(out)
);

initial Clk100MHz = 0;
always #5 Clk100MHz = ~Clk100MHz;

initial testClock2 = 0;
always #3 testClock2 = ~testClock2;

initial begin
    reset = 0; updown = 0; inp = 16'b0; switchValue = 4'b0000; 
    #10;
    reset = 1; updown = 0; inp = 16'b0; switchValue = 4'b0000; 
    #10; //toggles the reset briefly to clear dc's

    reset = 0; updown = 0; inp = 16'b0; switchValue = 4'b0000;
    #40;
    reset = 1; updown = 0; inp = 16'b0; switchValue = 4'b0001; //counter is not listening here
    #10;
    reset = 0; updown = 0; inp = 16'b0; switchValue = 4'b0001; //counter is not listening here
    #23;
    reset = 1; updown = 0; inp = 16'b0; switchValue = 4'b0000; //when we switch back, it's doing great
    #13;
    reset = 0; updown = 0; inp = 16'b0; switchValue = 4'b0000;
    #23;
    $finish;
end
 endmodule

【问题讨论】:

  • 仔细检查所有端口连接
  • 时钟之间的切换是一个非常难以正确处理的电路。你这样做的方式会给你时钟故障或“矮”时钟。它可以在模拟中工作,但在实际逻辑中,您应该准备好发现您的计数器有“问题”。例如你会错过时钟脉冲或更糟:你的计数器在值之间跳跃。

标签: verilog counter clock


【解决方案1】:

您从未在您的实例化topmod 中连接testClock2 hw1_top

hw1_top topmod(
    .reset(reset),
    .updown(updown),
    .inp(inp),
    .clkSwitch(switchValue),
    .Clk100MHz(Clk100MHz),
    .testClock2(testClock2), // this is missing
    .out(out)
);

【讨论】:

  • 当然可以,但是对于他特别要求的东西,它缺少什么。 Oldfart 总结了更高层次的问题,他的代码还有其他问题。然而,由于这显然是一个家庭作业问题,我只是想指出缺失的部分,并希望他的教育机构能够纠正其他不太容易在简短的答案中解决的概念错误。
  • 解决了具体问题!感谢第二双眼睛,我一定会和教授更密切地讨论整体设计。谢谢大家的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-10
  • 2018-08-09
相关资源
最近更新 更多