暫存器
–ㄧ群正反器
邏輯閘決定這個資料如何轉移至暫存器
例子: 四位元暫存器:

範例:具有一載入控制輸入的四位元資料儲存暫存器

移位佔存器:
一個可將儲存在每一胞元的二元資料以所指定之方向移位至其相鄰胞元的暫存器稱為移位暫存器 (shift register)。 最簡單的移位暫存器
僅僅使用正反器
範例:四位元移位佔存器

串列轉移
*一個數位系統一次轉移或處理一個位元的資料時,則此系統被稱為操作於串列模式。
*從原來的暫存器移位至預定的暫存器


範例:利用D型正反器的串列加法

範例:利用JK正反器的串列加法


並行轉移
*並行轉移則是在相同時間轉移暫存器內的全部位元資料。
通用移位暫存器 (universal shift register)
1. 一個清除 (clear) 控制將暫存器清除為0。
2. 一個時脈 (clock) 輸入使所有操作同步化。
3. 一個右移 (shift-right) 控制用以啟動向右移位操作,以及串列輸入及輸出 (serial input and output) 線配合成
可向右移位。
4. 一個左移 (shift-left) 控制用以啟動向左移位操作,以及串列輸入及輸出 (serial input and output) 線配合成可
向左移位。
5. 一個並列載入 (parallel-load) 控制以啟動並列轉移,及有 n 條輸入線配合提供並列轉移。
6. n條的並列輸出線。
7. 在時脈不斷供應之下,有一個控制狀態可使暫存器內的資訊維持不變。其他的移位暫存器可能
只有前述的部分功能,但至少具備一種移位操作功能。
*單向移位暫存器 (unidirectional shift register)
*雙向移位暫存器 (bidirectional shift register)
* 通用移位暫存器 (universal shift register)
範例: 4-位元 通用移位暫存器

| 控制模式S1 | 控制模式S0 | 佔存計操作 |
| 0 | 0 | 不便 |
| 0 | 1 | 左移 |
| 1 | 0 | 右移 |
| 1 | 1 | 並列載入 |


四位元移位佔存器--design bench
module Shift_Register_4_beh (
output reg [3: 0] A_par, // 輸出
input [3: 0] I_par, // 並列載入
input s1, s0, // 選擇輸入
MSB_in, LSB_in, // Serial inputs
CLK, Clear_b // Clock and Clear_b
);
always @ (posedge CLK, negedge Clear_b)
if (~Clear_b) A_par <= 4'b0000;
else
case ({s1, s0})
2'b00: A_par <= A_par; // 不改變
2'b01: A_par <= {MSB_in, A_par[3: 1]}; // 右移
2'b10: A_par <= {A_par[2: 0], LSB_in}; // 左移
2'b11: A_par <= I_par; // 並列載入
endcase
endmodule
四位元移位佔存器--test bench
module t_Shift_Register_4_beh ();
reg s1, s0, // Select inputs
MSB_in, LSB_in, // Serial inputs
clk, reset_b; // Clock and Clear_b
reg [3: 0] I_par; // Parallel input
wire [3: 0] A_par; // Register output
Shift_Register_4_beh M0 (A_par, I_par,s1, s0, MSB_in, LSB_in, clk, reset_b);
initial #200 $finish;
initial begin clk = 0; forever #5 clk = ~clk; end
initial fork
// test reset action load
#3 reset_b = 1;
#4 reset_b = 0;
#9 reset_b = 1;
// test parallel load
#10 I_par = 4'hA;
#10 {s1, s0} = 2'b11;
那我們用比較結構化的方式去實現
四位元移位佔存器--design bench
// 4x1 multiplexer // 模塊一l
module Mux_4_x_1 (mux_out, i0, i1, i2, i3, select);
output mux_out;
input i0, i1, i2, i3;
input [1: 0] select;
reg mux_out;
always @ (select, i0, i1, i2, i3)
case (select)
2'b00: mux_out = i0;
2'b01: mux_out = i1;
2'b10: mux_out = i2;
2'b11: mux_out = i3;
endcase
endmodule
// Behavioral model of D flip-flop // 模塊二
module D_flip_flop (Q, D, CLK, Clr_b);
output Q;
input D, CLK, Clr_b;
reg Q;
always @ (posedge CLK or negedge Clr_b)
if (!Clr_b) Q <= 1'b0; else Q <= D;
endmodule
// One stage of shift register //模塊stage 用到模組1跟模組2
module stage (i0, i1, i2, i3, Q, select, CLK, Clr_b);
input i0, // circulation bit selection
i1, // data from left neighbor or serial input for shift-right
i2, // data from right neighbor or serial input for shift-left
i3; // data from parallel input
output Q;
input [1: 0] select; // stage mode control bus
input CLK, Clr_b; // Clock, Clear for flip-flops
wire mux_out;
// instantiate mux and flip-flop
Mux_4_x_1 M0 (mux_out, i0, i1, i2, i3, select);
D_flip_flop M1 (Q, mux_out, CLK, Clr_b);
endmodule
//用到模組stage
module Shift_Register_4_str ( // V2001, 2005
output [3: 0] A_par, // Parallel output
input [3: 0] I_par, // Parallel input
input s1, s0, // Mode select
input MSB_in, LSB_in, CLK, Clear_b // Serial inputs, clock, clear
);
// bus for mode control
wire [1:0] select = {s1, s0};
// Instantiate the four stages
stage ST0 (A_par[0], A_par[1], LSB_in, I_par[0], A_par[0], select, CLK, Clear_b);
stage ST1 (A_par[1], A_par[2], A_par[0], I_par[1],A_par[1], select, CLK, Clear_b);
stage ST2 (A_par[2], A_par[3], A_par[1], I_par[2], A_par[2], select, CLK, Clear_b);
stage ST3 (A_par[3], MSB_in, A_par[2], I_par[3], A_par[3], select, CLK, Clear_b);
endmodule
四位元移位佔存器--test bench
module t_Shift_Register_4_str ();
reg s1, s0, // Select inputs
MSB_in, LSB_in, // Serial inputs
clk, Clear_b; // Clock and Clear_b
reg [3: 0] I_par; // Parallel input
wire [3: 0] A_par; // Register output
Shift_Register_4_str M0 (A_par, I_par, s1, s0, MSB_in, LSB_in, clk, Clear_b);
initial #200 $finish;
initial begin clk = 0; forever #5 clk = ~clk; end
initial fork
// test reset action load
#3 Clear_b = 1;
#4 Clear_b = 0;
#9 Clear_b = 1;
// test parallel load
#10 I_par = 4'hA;
#10 {s1, s0} = 2'b11;
// test shift right
#30 MSB_in = 1'b0;
#30 {s1, s0} = 2'b01;
// test shift left
#80 LSB_in = 1'b1;
#80 {s1, s0} = 2'b10;
// test circulation of data
#130 {s1, s0} = 2'b11;
#140 {s1, s0} = 2'b00;
// test reset on the fly
#150 Clear_b = 1'b0;
#160 Clear_b = 1'b1;
#160 {s1, s0} = 2'b11;
join
endmodule
