CPU0-Mini 的控制單元

CPU0 處理器

基礎知識

Verilog

程式計數模組

記憶體

指令提取單元

跳躍指令

控制單元

CPU0-Mini

CPU0

DE2-70 板實作

LED 與開關

七段顯示器

Clock 時脈

程式計數器

跳躍指令

CPU0-Mini

CPU0

Icarus 實作

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 [31:0] addr32;
    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_rw = 1; // m_rw=1 is read mode, read(m[MAR]) => read(m[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_rw = 1; // 讀取模式:read 
                            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 位元有號數
                            `PC = `PC+addr32; // 跳躍目標位址=PC+cx
                        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

Facebook

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License