CPU0-Mini 的控制單元

# 訊息

## English

``````module cpu0m(input clock, reset, output reg [31:0] pc,
output reg [2:0] tick, output reg [31:0] ir,
output reg [31:0] mar, output reg [31:0] mdr,
inout [31:0] dbus, output reg m_en, m_rw,
output reg [7:0] op, output reg signed [31:0] A,
output reg signed [31:0] B, output reg signed [31:0] C,
output reg [3:0] ra, output reg [3:0] rb, output reg [3:0] rc,
output reg signed [31:0] aluOut);
reg signed [11:0] cx12;
reg signed [15:0] cx16;
reg signed [23:0] cx24;
reg signed [31:0] R [0:15];

`define PC R[15]

always @(posedge clock) begin
if (reset) begin
`PC = 0;
tick = 0;
end
else begin
tick = tick+1;
m_en = 0;
case (tick)
// 指令擷取階段 Tick 1..3 ： memory.read(m[PC])
1:    begin  // Tick 1：將 PC 丟到位址匯流排上
mar = `PC; // MAR = PC
m_en = 1;
`PC = `PC+4; // PC = PC + 4
end
2:    begin  // Tick 2：ir = m[PC]
mdr = dbus;
ir = mdr; // IR = dbus = m[PC]
{op,ra,rb,rc,cx12} = ir;
cx24 = ir[23:0];
cx16 = ir[15:0];
end
3:    begin  // Tick 3：將 PC 丟到位址匯流排上
m_en = 0;
A = R[ra];
B = R[rb];
C = R[rc];
end
// 指令執行階段 Tick 4..6 ： execute(IR)
4:    begin  // Tick 4：將 PC 丟到位址匯流排上
case (op) // 解讀 OP: Tick 4
8'h00: begin // 指令：LD ra, rb, cx ; 語意：R[ra] = m[rb+cx]
mar = B + cx16; // mar = 讀取位址 = R[rb]+cx
m_en = 1;
end
8'h01: begin // 指令：ST ra, rb, cx ; 語意：m[rb+cx]=R[ra]
mar = B + cx16;  // 寫入位址 = R[rb]+cx
mdr = A; // 寫入資料：R[ra]
m_rw = 0; // 寫入模式：write
m_en = 1;
end
8'h13: begin // 指令：ADD ra, rb, rc ; 語意：R[ra]=R[rb]+R[rc]
aluOut = B+C; // 執行加法
end
8'h26: begin // 指令：JMP cx ; 語意：PC = PC+cx
addr32 = cx24; // 取出 cx 並轉為 32 位元有號數
end
default:    begin
end
endcase
end
5:    begin // 解讀 OP: Tick 5
case (op) // LD ra, rb, cx ; R[ra] = R[rb+cx] ; mdr = R[rb+cx]
8'h00: begin // 指令：LD ra, rb, cx ; 語意：R[ra] = m[rb+cx]
mdr = dbus; // 取得記憶體傳回的 dbus = m[rb+cx]
R[ra] = mdr; // 存入到目標暫存器 R[ra] 中
A = mdr;
m_en = 0; // 讀取完畢
end
8'h01: begin // 指令：ST ra, rb, cx ; 語意：m[rb+cx]=R[ra]
m_en = 0; // 寫入完畢
end
8'h13: begin // 指令：ADD ra, rb, rc ; 語意：R[ra]=R[rb]+R[rc]
R[ra] = aluOut;
end
8'h26: begin // 指令：JMP cx ; 語意：PC = PC+cx
end
default:    begin
end
endcase
end
6:    begin
tick = 0;
end
default:    begin
end
endcase
end
pc = `PC;
end
endmodule```
```