[RTLLM-p021] Memory/LIFO (Last-In, First-Out)/LIFObuffer
4 位元 LIFO 堆疊緩衝器
題目說明
請設計一個名為 LIFObuffer 的同步式後進先出緩衝器。
此緩衝器的資料寬度為 4 位元,最多可儲存 4 筆資料,並支援:
- Push:將資料壓入堆疊
- Pop:從堆疊頂端取出資料
- Reset:清除堆疊
- Enable:控制是否執行操作
- Full 與 Empty 狀態判斷
LIFO 的完整名稱為:
Last-In-First-Out
表示最後寫入的資料會最先被讀出。
例如,依序寫入:
2, 4, 6
之後依序讀出時,結果應為:
6, 4, 2
模組介面
| 埠 | 方向 | 位元寬度 | 說明 |
|---|---|---|---|
dataIn |
input | 4 | 要壓入堆疊的資料 |
RW |
input | 1 | 操作選擇,0 為寫入,1 為讀取 |
EN |
input | 1 | 操作致能訊號 |
Rst |
input | 1 | 高電位有效同步重置 |
Clk |
input | 1 | 時脈訊號 |
EMPTY |
output | 1 | 堆疊為空旗標 |
FULL |
output | 1 | 堆疊已滿旗標 |
dataOut |
output | 4 | 讀出的資料 |
內部結構
模組使用下列儲存結構:
reg [3:0] stack_mem [0:3];
此陣列包含 4 個元素,每個元素可儲存 4 位元資料。
使用堆疊指標 SP 表示目前堆疊頂端的位置。
本題採用以下指標定義:
SP |
狀態 |
|---|---|
| 4 | 堆疊為空 |
| 3 | 儲存 1 筆資料 |
| 2 | 儲存 2 筆資料 |
| 1 | 儲存 3 筆資料 |
| 0 | 儲存 4 筆資料,堆疊已滿 |
因此:
EMPTY = 1 when SP == 4
FULL = 1 when SP == 0
重置操作
在 Clk 上升沿,當:
EN = 1
Rst = 1
時,必須清除整個堆疊:
SP = 4
dataOut = 0
stack_mem[0] = 0
stack_mem[1] = 0
stack_mem[2] = 0
stack_mem[3] = 0
重置是同步操作,只有在 Clk 上升沿執行。
依照本題規格,只有 EN = 1 時才會執行重置或其他堆疊操作。
寫入操作
當:
EN = 1
Rst = 0
RW = 0
FULL = 0
時,執行 Push 操作。
由於空堆疊的 SP 初始值為 4,因此寫入時必須先將 SP 減一,再將資料寫入新位置。
概念上等價於:
SP = SP - 1
stack_mem[SP] = dataIn
例如,重置後:
SP = 4
第一次寫入資料 A:
SP = 3
stack_mem[3] = A
第二次寫入資料 B:
SP = 2
stack_mem[2] = B
此時堆疊頂端為 B。
當 FULL = 1 時,寫入要求必須被忽略。
讀取操作
當:
EN = 1
Rst = 0
RW = 1
EMPTY = 0
時,執行 Pop 操作。
讀取目前 SP 指向的堆疊頂端資料:
dataOut = stack_mem[SP]
接著清除該記憶體位置,並將 SP 加一:
stack_mem[SP] = 0
SP = SP + 1
當 EMPTY = 1 時,讀取要求必須被忽略,dataOut 保持原值。
EN 行為
當:
EN = 0
時:
- 不執行重置
- 不執行 Push
- 不執行 Pop
SP保持不變stack_mem保持不變dataOut保持不變
FULL 與 EMPTY
狀態旗標由堆疊指標組合產生:
EMPTY = (SP == 4)
FULL = (SP == 0)
重置後:
EMPTY = 1
FULL = 0
寫入四筆資料後:
EMPTY = 0
FULL = 1
讀出所有資料後:
EMPTY = 1
FULL = 0
設計要求
- 模組名稱必須為
LIFObuffer。 - 資料寬度固定為 4 位元。
- 堆疊深度固定為 4。
- 必須使用同步時序邏輯。
Rst為高電位有效同步重置。- 只有
EN = 1時才執行重置、讀取或寫入。 RW = 0表示 Push。RW = 1表示 Pop。- 堆疊已滿時不可繼續寫入。
- 堆疊為空時不可繼續讀取。
- Pop 後必須清除原本的記憶體位置。
- 資料必須符合後進先出的順序。
程式設計模板
module LIFObuffer (
input [3:0] dataIn,
input RW,
input EN,
input Rst,
input Clk,
output EMPTY,
output FULL,
output reg [3:0] dataOut
);
// Write your code here
endmodule
評論