根据2位选择输入(M),移位寄存器为:00-无更改,01-并行负载,10-左旋转,11-右移位(带SI)。我不确定并行加载的含义,并且我确定为多路复用器实例化代码的方式是不正确的(就使其执行移位,旋转等而言)。模拟测试平台时,我的Q值得到Xs。我撞墙了,不确定自己在做什么。
// Shift reg
module shift_reg4(
input clk,
input reset,
input [3:0] din,
input [1:0] M,
input SI,
output [3:0] Q);
// wires to interconnect the 4-mux's to the 4 D-FF's
wire w3,w2,w1,w0;
mux4_to_1 m0 (.I({Q[3], Q[2], Q[1], Q[0]}),.S(M),.Y(w0));
mux4_to_1 m1 (.I(({din[3], din[2], din[1], din[0]}),.S(M),.Y(w1));
mux4_to_1 m2 (.I({Q[3], Q[1], din[2], Q[2]}),.S(M),.Y(w2));
mux4_to_1 m3 (.I({SI, din[3], din[2], din[1]}),.S(M),.Y(w3));
d_ff u0 (.clk(clk),.reset(reset),.D(w0),.Q(Q[0]));
d_ff u1 (.clk(clk),.reset(reset),.D(w1),.Q(Q[1]));
d_ff u2 (.clk(clk),.reset(reset),.D(w2),.Q(Q[2]));
d_ff u3 (.clk(clk),.reset(reset),.D(w3),.Q(Q[3]));
endmodule
//D-FlipFlop (Provided)
module d_ff(
input clk,
input reset,
input D,
output reg Q
);
always @(posedge clk, posedge reset) begin
if(reset == 1'b1)
Q <= 1'b0;
else
Q <= D;
end
endmodule
// 4-to-1 mux (Provided)
module mux4_to_1(
input [3:0] I,
input [1:0] S,
output reg Y);
always @(I,S)
case(S)
2'b00: Y = I[0];
2'b01: Y = I[1];
2'b10: Y = I[2];
2'b11: Y = I[3];
default: Y = I[0];
endcase
endmodule
// Hint that was also provided for 16-bit
case(M)
2'b00: Q <= Q;
2'b01: Q <= din;
2'b10: Q <= {SI,Q[15:1];
2'b11: Q <= {Q[14:0], Q[15]};
default: Q <= Q;
endcase
// My guess based on that hint is that the mux should be instantiated as:
mux4_to_1 m0 (.I(Q[3:0]),.S(M),.Y(w0));
mux4_to_1 m1 (.I(din[3:0]),.S(M),.Y(w1));
mux4_to_1 m2 (.I({Q[2:0], Q[3]}),.S(M),.Y(w2));
mux4_to_1 m3 (.I({SI, Q[3:1]}),.S(M),.Y(w3));
//This is my test bench for the shift reg (provided) but I'm not getting
//a value for Q
module shift_reg4_tb;
// Inputs
reg clk, reset, SI;
reg [3:0] D;
reg [1:0] M;
// Outputs
wire [3:0] Q;
// Instantiate the Unit Under Test (UUT)
shift_reg4 uut (
.clk(clk),
.reset(reset),
.din(D),
.M(M),
.SI(SI),
.Q(Q)
);
// Generate Clock with a 10 ns period
always
#5 clk = ~clk;
// Initialize Inputs
initial begin
$timeformat(-9, 1, " ns", 6);
clk = 0; reset = 0; M = 0; D = 0; SI = 0;
//These two clocks take care of reset
@(negedge clk)
{reset,M,D,SI} = 8'b1_xx_xxxx_x;
@(negedge clk)
{reset,M,D,SI} = 8'b0_xx_xxxx_x;
//Exercise the "load" function with D = 0xC(1100). Note SIis don't care
@(negedge clk)
{reset,M,D,SI} = 8'b0_01_1100_x;
//Exercise the "no change" function. Note both D and SI are don't care
@(negedge clk)
{reset,M,D,SI} = 8'b0_00_xxxx_x;
//Exercise the "shift right" function with SI = 0. Note D is don't care
@(negedge clk)
{reset,M,D,SI} = 8'b0_11_xxxx_0;
//Exercise the "shift right" function with SI = 1. Note D is don't care
@(negedge clk)
{reset,M,D,SI} = 8'b0_11_xxxx_1;
//Exercise the "no change" function. Note both D and SI are don't care
@(negedge clk)
{reset,M,D,SI} = 8'b0_00_xxxx_x;
//Exercise the "rotate left" function. Note both D and SI are don't care
@(negedge clk)
{reset,M,D,SI} = 8'b0_10_xxxx_x;
//Exercise the "rotate left" function. Note both D and SI are don't care
@(negedge clk)
{reset,M,D,SI} = 8'b0_10_xxxx_x;
//Exercise the "no change" function. Note both D and SI are don'tcare
@(negedge clk)
{reset,M,D,SI} = 8'b0_00_xxxx_x;
$finish;