我正在开发具有左移和右移功能的 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 中使用触发器和多路复用器实例进行设计。 这种做法太低级了。
最好使用行为代码对移位寄存器本身进行建模,就像对触发器所做的那样。 您应该使用
always
块。 Stack Overflow 上有很多 shift 寄存器 Verilog 代码的示例,比如这个。
采用这种新方法比费力调试现有代码更能充分利用时间。