移位寄存器实现Verilog代码:
`timescale 1ns / 1ps
module add(
input clk,
input reset,
input [1:0] s,
input dl,
input dr,
input [3:0] d,
output reg [3:0] q
);
always @(posedge clk or negedge reset)
if (~reset) begin
q <= 4'b0000;
end else begin
case(s)
2'b00: q <= q; //保持
2'b01: q <= {q[2:0],dr}; //右移
2'b10: q <= {dl,q[3:1]}; //左移
2'b11: q <= d; //置数
endcase
end
endmodule
仿真代码
`timescale 1ns / 1ps
module conter_t;
// Inputs
reg clk;
reg reset;
reg [1:0] s;
reg dl;
reg dr;
reg [3:0] d;
// Outputs
wire [3:0] q;
// Instantiate the Unit Under Test (UUT)
add uut (
.clk(clk),
.reset(reset),
.s(s),
.dl(dl),
.dr(dr),
.d(d),
.q(q)
);
parameter PERIOD = 20;
always begin
clk = 1'b0;
#(PERIOD/2) clk = 1'b1;
#(PERIOD/2);
end
initial begin
// Initialize Inputs
clk = 0;
reset = 0;
s = 0;
dl = 0;
dr = 0;
d = 0;
// Wait 100 ns for global reset to finish
#40;
reset = 1;
d = 4'b1011;
// Add stimulus here
s = 2'b11; //置数
#40;
s = 2'b01; //右移
#100;
s = 2'b11; //置数
#40;
s = 2'b10; //左移
#100;
s = 2'b11; //置数
#40;
s = 2'b00; //保持
#100;
end
endmodule
仿真波形:
总结:由于没有人给予指导,在调试的过程中,一直被一个问题困扰,问题及解决办法描述如下。
本来想要测试程序的移位功能时,我想的是给q(输出)一个初始值,然后设定模式为移位模式,让q在时钟脉冲的作用下移位并进行观察。于是在仿真程序中,对q进行幅值操作,但是默认生成的仿真程序模板中,q为wire类型,不允许幅值,于是手动改为reg类型(实现程序中为了对q赋值,就是需要定义q为reg类型,所以我理所当然的认为这里也要这样改写)。
但是这样操作之后的现象是:仿真程序中对q的值的改变语句均生效,但是源程序中对q值的改变语句无效,寻找很久未果。
后来发现,其他的仿真的程序中似乎都没有把输出变量设定为reg类型,即没有在仿真程序中修改输出变量的值。
因此想到,将q恢复为默认的wire类型,在仿真程序中对d赋值,然后通过移位寄存器的置数功能将d的值传递给q,上述问题得到解决。
如有问题,欢迎交流。
——cloud over sky
——2019/11/26