[RTLLM-p024] Memory/shifter/barrel_shifter
8 位元桶形右移器
題目說明
請設計一個名為 barrel_shifter 的 8 位元桶形右移器。
模組接收一個 8 位元輸入 in,並根據 3 位元控制訊號 ctrl,將輸入資料向右移動指定的位元數。
移位量由 ctrl 表示:
shift_amount = ctrl
因此:
ctrl |
右移位數 |
|---|---|
3'b000 |
0 |
3'b001 |
1 |
3'b010 |
2 |
3'b011 |
3 |
3'b100 |
4 |
3'b101 |
5 |
3'b110 |
6 |
3'b111 |
7 |
本題執行的是邏輯右移,左側空出的位元必須補零。
例如:
in = 10000000
ctrl = 001
out = 01000000
以及:
in = 10000000
ctrl = 100
out = 00001000
模組介面
| 埠 | 方向 | 位元寬度 | 說明 |
|---|---|---|---|
in |
input | 8 | 要進行右移的輸入資料 |
ctrl |
input | 3 | 右移位數控制訊號 |
out |
output | 8 | 右移後的輸出結果 |
分層桶形移位器
桶形移位器分成三個階段:
- 右移 4 位元階段
- 右移 2 位元階段
- 右移 1 位元階段
每一個階段由控制訊號的一個位元決定是否執行移位:
ctrl[2]:控制是否右移 4 位元
ctrl[1]:控制是否右移 2 位元
ctrl[0]:控制是否右移 1 位元
總移位量為:
4 × ctrl[2] + 2 × ctrl[1] + ctrl[0]
例如:
ctrl = 3'b101
表示:
右移 4 位元 + 右移 1 位元 = 右移 5 位元
mux2X1 子模組
每個移位階段必須使用多個二對一多工器完成。
請建立一個名為 mux2X1 的子模組:
module mux2X1 (
input a,
input b,
input sel,
output y
);
其功能為:
sel = 0:y = a
sel = 1:y = b
可使用條件運算子實作:
assign y = sel ? b : a;
第一階段:右移 4 位元
當:
ctrl[2] = 0
第一階段輸出保持原輸入:
stage4 = in
當:
ctrl[2] = 1
輸入向右移 4 位元:
stage4 = {4'b0000, in[7:4]}
各輸出位元對應如下:
stage4[7] = 0
stage4[6] = 0
stage4[5] = 0
stage4[4] = 0
stage4[3] = in[7]
stage4[2] = in[6]
stage4[1] = in[5]
stage4[0] = in[4]
第二階段:右移 2 位元
當:
ctrl[1] = 0
第二階段輸出保持第一階段結果:
stage2 = stage4
當:
ctrl[1] = 1
第一階段結果向右移 2 位元:
stage2 = {2'b00, stage4[7:2]}
第三階段:右移 1 位元
當:
ctrl[0] = 0
輸出保持第二階段結果:
out = stage2
當:
ctrl[0] = 1
第二階段結果向右移 1 位元:
out = {1'b0, stage2[7:1]}
設計要求
- 頂層模組名稱必須為
barrel_shifter。 - 必須建立名為
mux2X1的子模組。 - 資料寬度固定為 8 位元。
- 控制訊號寬度固定為 3 位元。
- 必須執行邏輯右移。
- 左側空出的位元必須補零。
- 必須使用三級結構:
- 4 位元移位級
- 2 位元移位級
- 1 位元移位級
- 每個階段必須使用
mux2X1選擇是否移位。 - 此模組為組合邏輯,不需要時脈或重置訊號。
- 不可使用暫存器保存先前輸出。
out必須隨in或ctrl立即更新。
程式設計模板
module mux2X1 (
input a,
input b,
input sel,
output y
);
// Write your code here
endmodule
module barrel_shifter (
input [7:0] in,
input [2:0] ctrl,
output [7:0] out
);
// Write your code here
endmodule
評論