1

我正在建模一个由三个 D 触发器组成的移位寄存器。有三个输入(clk、reset、shiftIn)和一个输出(shiftOut)。复位为同步高电平有效并复位所有触发器。

设计


    module shiftReg(shiftIn,clk,reset,shiftOut);
    input shiftIn, clk, reset;
    output shiftOut;
    reg Q1,Q2,shiftOut;
    always @(posedge clk or posedge reset) 
    begin
        if(reset == 1'b1) begin
            Q1 <= 1'b0;
            Q2 <= 1'b0;
            shiftOut <= 1'b0;
        end
        else begin
            Q1 <= shiftIn;
            Q2 <= Q1;
            shiftOut <= Q2;
        end
    end
    endmodule

试验台


    module tb_shiftReg();
    reg shiftin;
    reg clk;
    reg reset;
    wire shiftOut;
    shiftReg SR(shiftIn,clk,reset,shiftOut);
    initial begin
        clk=0;
        forever #10 clk = ~clk; 
    end
    initial begin
        $monitor("time=",$time, "shiftin=%b  reset =%d shiftout =%b",shiftIn,reset,shiftOut);
        $dumpfile("test.vcd");
        $dumpvars;           
        reset=0;
        shiftin <= 0;
        #100;
        reset=0;
        shiftin <= 1;
        #100;
        reset =1;
        shiftin <= 0;
        #100;
        reset =1;
        shiftin <= 0;
        #100 $finish;
    end
    endmodule

当我使用以下模拟它时,我得到以下输出iverilog


    vu2swz@PPDP01:~$ iverilog Shiftregister.v 
    vu2swz@PPDP01:~$ ./a.out 
    VCD info: dumpfile test.vcd opened for output.
    time=                   0shiftin=z  reset =0 shiftout =x
    time=                  50shiftin=z  reset =0 shiftout =z
    time=                 200shiftin=z  reset =1 shiftout =0

为什么我得到 z 和 x 而不是 1 和零?

4

1 回答 1

2

Verilog 区分大小写。 shiftin是与shiftIn(大写“I”)不同的信号。在您声明的测试台中shiftin,但您没有声明shiftIn。默认情况下,Verilog 将未声明的信号视为 type ,并且 a的wire默认值为。这意味着您的设计模块的输入是非驱动的。我使用的模拟器给了我一个警告信息。您还可以在 edaplayground 上的不同模拟器上尝试您的代码,以获得更多有用的信息。wirez

将所有更改shiftInshiftin您的测试平台模块,这会清除您的大部分zx

time=                   0shiftin=0  reset =0 shiftout =x
time=                  50shiftin=0  reset =0 shiftout =0
time=                 100shiftin=1  reset =0 shiftout =0
time=                 150shiftin=1  reset =0 shiftout =1
time=                 200shiftin=0  reset =1 shiftout =0

您仍然x在时间 0 得到,因为在时间 0 未断言重置;reset 在时间 200 置位。通常,您将在时间 0 ( ) 置位复位,然后在几个时钟周期后将其reset=1;置为无效 ( ),例如在时间 100。reset=0;

module tb_shiftReg();
    reg shiftin;
    reg clk;
    reg reset;
    wire shiftOut;
    shiftReg SR(shiftin,clk,reset,shiftOut);
    initial begin
        clk=0;
        forever #10 clk = ~clk; 
    end
    initial begin
        $monitor("time=",$time, "shiftin=%b  reset =%d shiftout =%b",shiftin,reset,shiftOut);
        $dumpfile("test.vcd");
        $dumpvars;           
        reset=1;
        shiftin <= 0;
        #100;
        reset=0;
        shiftin <= 1;
        #100;
        shiftin <= 0;
        #100;
        shiftin <= 0;
        #100 $finish;
    end
endmodule

通过上述更改,所有信号都显示为 0/1:

time=                   0shiftin=0  reset =1 shiftout =0
time=                 100shiftin=1  reset =0 shiftout =0
time=                 150shiftin=1  reset =0 shiftout =1
time=                 200shiftin=0  reset =0 shiftout =1
time=                 250shiftin=0  reset =0 shiftout =0

注意:您的重置信号是异步的,而不是同步的,因为您包含reset在敏感度列表中:

always @(posedge clk or posedge reset)
于 2021-01-07T11:27:15.753 回答