无法获得移位寄存器分析和观察的输出

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

我正在开发具有左移和右移功能的 Verilog 移位寄存器。代码可以编译,但是当我运行测试时,

shift_left
shift_right
的输出根本没有变化。 它输出 0 值。下面是代码的最小示例以及测试结果。我检查了类似的问题和 Verilog 文档,但无法确定问题。任何指导将不胜感激!

module Shift_reg(
    output [3:0] dout,      
    input [3:0] din,        
    input shift_left,       
    input shift_right,      
    input clk,              
    input rst               
);
    wire d0, d1, d2, d3;    
    wire q0, q1, q2, q3;    

    
    wire s1 = shift_right & ~shift_left;
    wire s0 = shift_left & ~shift_right;

    
    Mux_4_1 mux0 (.f(d0), .i0(q0), .i1(q1), .i2(din[0]), .i3(1'b0), .s1(s1), .s0(s0));
    Mux_4_1 mux1 (.f(d1), .i0(q1), .i1(q2), .i2(din[1]), .i3(q0), .s1(s1), .s0(s0));
    Mux_4_1 mux2 (.f(d2), .i0(q2), .i1(q3), .i2(din[2]), .i3(q1), .s1(s1), .s0(s0));
    Mux_4_1 mux3 (.f(d3), .i0(q3), .i1(1'b0), .i2(din[3]), .i3(q2), .s1(s1), .s0(s0));

    
    D_flp dff0 (.dout(q0), .din(d0), .clk(clk), .rst(rst));
    D_flp dff1 (.dout(q1), .din(d1), .clk(clk), .rst(rst));
    D_flp dff2 (.dout(q2), .din(d2), .clk(clk), .rst(rst));
    D_flp dff3 (.dout(q3), .din(d3), .clk(clk), .rst(rst));

    
    assign dout = {q3, q2, q1, q0};
endmodule


module Mux_4_1(f, i0, i1, i2, i3, s1, s0); 
    input i0, i1, i2, i3, s1, s0;
    output f;
    wire s1_bar, s0_bar;
    wire w1, w2, w3, w4;

    not n1(s0_bar, s0);
    not n2(s1_bar, s1);

    and a1(w1, s1_bar, s0_bar, i0);
    and a2(w2, s1_bar, s0, i1);
    and a3(w3, s1, s0_bar, i2);
    and a4(w4, s1, s0, i3);

    or o1(f, w1, w2, w3, w4);
endmodule 


module D_flp(dout, din, clk, rst); 
    input din, clk, rst;
    output reg dout;

    always @(posedge clk or posedge rst) begin
        if (rst)
            dout <= 1'b0;
        else
            dout <= din;
    end
endmodule

这是测试台代码

module Shift_reg_mux_Sim;

    // Parameters
    reg [3:0] din;          
    reg shift_left;        
    reg shift_right;       
    reg clk;               
    reg rst;               
    wire [3:0] dout;       

    // Instantiate the Shift Register
    Shift_reg uut (
        .dout(dout),
        .din(din),
        .shift_left(shift_left),
        .shift_right(shift_right),
        .clk(clk),
        .rst(rst)
    );

    // Clock generation
    initial begin
        clk = 0;
        forever #5 clk = ~clk; 
    end

    // Test sequence
    initial begin
        // Initialize inputs
        rst = 1;
        din = 4'b0000;
        shift_left = 0;
        shift_right = 0;

        // Wait for reset to settle
        #10;
        rst = 0;

        // Load initial data into the shift register
        #10 din = 4'b1010;  // Load 1010
        #10 shift_left = 1; // Shift left
        #10 shift_left = 0; // Stop shifting left

        // Check output
        #10 din = 4'b0000;  // Load data is irrelevant now
        #10 shift_right = 1; // Shift right
        #10 shift_right = 0; // Stop shifting right

        // Check output again
        #10 shift_left = 1; // Shift left again
        #10 shift_left = 0; // Stop shifting left

        // Reset the shift register
        #10 rst = 1;        // Activate reset
        #10 rst = 0;        // Deactivate reset

        // Finish simulation
        #10 $finish;
    end

    // Monitor outputs
    initial begin
        $monitor("Time: %0t | din: %b | dout: %b | shift_left: %b | shift_right: %b | rst: %b", 
                  $time, din, dout, shift_left, shift_right, rst);
    end

endmodule
verilog system-verilog shift-register
1个回答
0
投票

如有任何指导,我们将不胜感激!

您将收到的指导。

您使用的方法很容易出错。 您应该使用更高级别的抽象来建模您的逻辑。 无需在 Verilog 中使用触发器和多路复用器实例进行设计。 这种做法太低级了。

最好使用行为代码对移位寄存器本身进行建模,就像对触发器所做的那样。 您应该使用

always
块。 Stack Overflow 上有很多 shift 寄存器 Verilog 代码的示例比如这个

采用这种新方法比费力调试现有代码更能充分利用时间。

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