You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Verilog左右移位寄存器无移位输出问题求助

Verilog左右移位寄存器功能失效问题排查

我正在开发一款具备左右移位功能的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;

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

    Shift_reg uut (
        .dout(dout),
        .din(din),
        .shift_left(shift_left),
        .shift_right(shift_right),
        .clk(clk),
        .rst(rst)
    );

    initial begin
        clk = 0;
        forever #5 clk = ~clk; 
    end

    initial begin
        rst = 1;
        din = 4'b0000;
        shift_left = 0;
        shift_right = 0;

        #10;
        rst = 0;

        #10 din = 4'b1010;
        #10 shift_left = 1;
        #10 shift_left = 0;

        #10 din = 4'b0000;
        #10 shift_right = 1;
        #10 shift_right = 0;

        #10 shift_left = 1;
        #10 shift_left = 0;

        #10 rst = 1;
        #10 rst = 0;

        #10 $finish;
    end

    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

问题根源分析

1. 数据加载逻辑未触发

测试平台中设置din=4'b1010后,没有触发寄存器的加载操作。根据多路选择器逻辑:

  • 当shift_left和shift_right都为0时,多路器选择i0输入(保持触发器当前值,复位后为0),不会加载din的数据;
  • 加载din的条件是shift_right=1且shift_left=0,但测试流程中未设置该信号组合,导致寄存器始终保持复位后的0值。

2. 移位方向的多路器输入映射错误

移位逻辑方向完全搞反:

  • 左移操作应让q3←q2、q2←q1、q1←q0、q0←0,但当前代码中shift_left时,多路器选择的输入是右移逻辑(比如q0取q1);
  • 右移操作应让q0←q1、q1←q2、q2←q3、q3←0,当前代码的输入映射也不符合该逻辑。

3. 测试平台时序控制问题

信号切换间隔为10ns(一个时钟周期),但未保证信号在时钟上升沿稳定生效,比如设置din后立即切换移位信号,可能导致加载操作根本未执行。


修正方案

1. 调整寄存器模块逻辑

新增load控制信号明确加载操作,修正多路器输入映射匹配正确移位方向:

module Shift_reg(
    output [3:0] dout,      
    input [3:0] din,        
    input shift_left,       
    input shift_right,      
    input load,             // 新增加载控制信号
    input clk,              
    input rst               
);
    wire d0, d1, d2, d3;    
    wire q0, q1, q2, q3;    

    // 定义选择信号:00=保持, 01=左移, 10=右移, 11=加载
    wire [1:0] sel = {shift_right, shift_left};

    // 修正多路器输入映射
    Mux_4_1 mux0 (.f(d0), .i0(q0), .i1(1'b0), .i2(q1), .i3(din[0]), .s1(sel[1]), .s0(sel[0]));
    Mux_4_1 mux1 (.f(d1), .i0(q1), .i1(q0), .i2(q2), .i3(din[1]), .s1(sel[1]), .s0(sel[0]));
    Mux_4_1 mux2 (.f(d2), .i0(q2), .i1(q1), .i2(q3), .i3(din[2]), .s1(sel[1]), .s0(sel[0]));
    Mux_4_1 mux3 (.f(d3), .i0(q3), .i1(q2), .i2(1'b0), .i3(din[3]), .s1(sel[1]), .s0(sel[0]));

    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

2. 修改测试平台

加入加载操作,调整时序保证信号在时钟上升沿生效:

module Shift_reg_mux_Sim;

    reg [3:0] din;          
    reg shift_left;        
    reg shift_right;       
    reg load;               // 新增加载信号
    reg clk;               
    reg rst;               
    wire [3:0] dout;       

    Shift_reg uut (
        .dout(dout),
        .din(din),
        .shift_left(shift_left),
        .shift_right(shift_right),
        .load(load),
        .clk(clk),
        .rst(rst)
    );

    initial begin
        clk = 0;
        forever #5 clk = ~clk; 
    end

    initial begin
        rst = 1;
        din = 4'b0000;
        shift_left = 0;
        shift_right = 0;
        load = 0;

        #10;
        rst = 0;

        // 加载数据:等待时钟上升沿完成加载
        #5 din = 4'b1010;
        load = 1;
        #10 load = 0;

        // 左移一次
        shift_left = 1;
        #10 shift_left = 0;

        // 右移一次
        shift_right = 1;
        #10 shift_right = 0;

        // 左移两次
        shift_left = 1;
        #20 shift_left = 0;

        rst = 1;
        #10 rst = 0;

        #10 $finish;
    end

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

endmodule

3. 可选:简化多路选择器代码

用行为级描述代替门级描述,减少连线错误:

module Mux_4_1(f, i0, i1, i2, i3, s1, s0); 
    input i0, i1, i2, i3, s1, s0;
    output reg f;

    always @(*) begin
        case({s1, s0})
            2'b00: f = i0;
            2'b01: f = i1;
            2'b10: f = i2;
            2'b11: f = i3;
        endcase
    end
endmodule

内容的提问来源于stack exchange,提问作者Kotupalli Venkata Siva Teja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 19:04:59