簡易處理器 CPU0-Mini -- 在 Altera DE2-70 FPGA 板上的執行結果

電路設計

基本操作

基礎元件

加法器

注意事項

教學影片

觀察方法

DE2-70 板

LED 與開關

七段顯示器

Clock 時脈

程式計數器

跳躍指令

CPU0-Mini

UART

訊息

相關網站

參考文獻

最新修改

簡體版

English

專案下載:Cpu0mDe270.zip

測試程式

0000          LD   R2, K0
0004          LD   R1, K1
0008 LOOP:    ADD  R2, R2, R1
000C          JMP  LOOP
0010 K0:      WORD 0
0014 K1:      WORD 1

執行錄影

電路方塊圖

使用 Altera Quartus II/Tool/Netlist Viewers/RTL Viewer 可以看到下列電路圖

Cpu0mDe270.png

Verilog 程式

module Computer0m(input clock, reset, 
         output [0:7] segPc1, output [0:7] segPc0, 
         output [0:7] segTick,
         output [0:7] segAlu1, output [0:7] segAlu0);
wire [31:0] counter;
wire [31:0] pc;
wire [3:0] tick;
wire [31:0] ir;
wire [31:0] mar;
wire [31:0] mdr;
wire [31:0] dbus;
wire [31:0] aluOut;
wire m_en, m_rw;

Counter mCounter(clock, counter);

cpu0m cpu (.clock(counter[24]), .reset(reset), .pc(pc), .tick(tick), .ir(ir), 
.mar(mar), .mdr(mdr), .dbus(dbus), .m_en(m_en), .m_rw(m_rw), .aluOut(aluOut));

memory0m mem (.clock(counter[24]), .reset(reset), .en(m_en), .rw(m_rw), 
.abus(mar), .dbus_in(dbus), .dbus_out(dbus));

Seg7 mSegPc1(pc[7:4], segPc1);
Seg7 mSegPc0(pc[3:0], segPc0);
Seg7 mSegTick(tick, segTick);

Seg7 mSegAlu1(aluOut[7:4], segAlu1);
Seg7 mSegAlu0(aluOut[3:0], segAlu0);

endmodule

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 signed [31:0] aluOut);
   reg [7:0] op;
   reg signed [23:0] addr24;
   reg signed [31:0] addr32;
    reg signed [31:0] A;
    reg signed [31:0] B;
    reg signed [31:0] C;
    reg signed [11:0] cx12;
   reg signed [15:0] cx16;
   reg signed [23:0] cx24;
    reg signed [31:0] R [0:15];
    reg [3:0] ra;
    reg [3:0] rb;
    reg [3:0] rc;

    `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'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'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

module Seg7(input [3:0] num, output [0:7] seg);
   reg [7:0] nseg;
    always @(num) begin
        case (num)
            4'b0000: nseg = 8'b11111100; // 0
            4'b0001: nseg = 8'b01100000; // 1
            4'b0010: nseg = 8'b11011010; // 2
            4'b0011: nseg = 8'b11110010; // 3
            4'b0100: nseg = 8'b01100110; // 4
            4'b0101: nseg = 8'b10110110; // 5
            4'b0110: nseg = 8'b10111110; // 6
            4'b0111: nseg = 8'b11100100; // 7
            4'b1000: nseg = 8'b11111110; // 8
            4'b1001: nseg = 8'b11110110; // 9
            4'b1010: nseg = 8'b11101110; // A
            4'b1011: nseg = 8'b00111110; // b
            4'b1100: nseg = 8'b10011100; // C
            4'b1101: nseg = 8'b01111010; // d
            4'b1110: nseg = 8'b10011110; // E
            4'b1111: nseg = 8'b10001110; // F
            default: nseg = 8'b00000000; //  
        endcase
    end
   assign seg = ~nseg;
endmodule

module Counter(input clock, output reg [31:0] counter);
always @(posedge clock) begin
    counter = counter + 1;
end
endmodule

module memory0m(input clock, reset, en, rw, 
            input [31:0] abus, input [31:0] dbus_in, output [31:0] dbus_out);
reg [7:0] m [0:128];
reg [31:0] data;

    always @(clock or reset or abus or en or rw or dbus_in) 
    begin
        if (reset == 1) begin
            {m[0],m[1],m[2],m[3]}     = 32'h002F000C; // 0000           LD   R2, K0
            {m[4],m[5],m[6],m[7]}     = 32'h001F000C; // 0004           LD   R1, K1
            {m[8],m[9],m[10],m[11]}   = 32'h13221000; // 0008 LOOP:     ADD  R2, R2, R1
            {m[12],m[13],m[14],m[15]} = 32'h26FFFFF8; // 000C           JMP  LOOP
            {m[16],m[17],m[18],m[19]} = 32'h00000000; // 0010 K0:        WORD 0
            {m[20],m[21],m[22],m[23]} = 32'h00000001; // 0014 K1:        WORD 1
            data = 32'hZZZZZZZZ; 
        end else if (abus >=0 && abus < 128) begin
            if (en == 1 && rw == 0) // r_w==0:write
            begin
                data = dbus_in;
                {m[abus], m[abus+1], m[abus+2], m[abus+3]} = dbus_in;
            end
            else if (en == 1 && rw == 1) // r_w==1:read
                data = {m[abus], m[abus+1], m[abus+2], m[abus+3]};
            else
                data = 32'hZZZZZZZZ;
        end else
            data = 32'hZZZZZZZZ;
    end
    assign dbus_out = data;
endmodule

PIN 腳綁定

clock        Input    PIN_AD15    3.3-V LVTTL (default)    24mA (default)    7    B7_N3
reset        Input    PIN_AA23    3.3-V LVTTL (default)    24mA (default)    6    B6_N2
segAlu0[0]    Output    PIN_AE8        3.3-V LVTTL (default)    24mA (default)    8    B8_N3
segAlu0[1]    Output    PIN_AF9        3.3-V LVTTL (default)    24mA (default)    8    B8_N2
segAlu0[2]    Output    PIN_AH9        3.3-V LVTTL (default)    24mA (default)    8    B8_N1
segAlu0[3]    Output    PIN_AD10    3.3-V LVTTL (default)    24mA (default)    8    B8_N2
segAlu0[4]    Output    PIN_AF10    3.3-V LVTTL (default)    24mA (default)    8    B8_N2
segAlu0[5]    Output    PIN_AD11    3.3-V LVTTL (default)    24mA (default)    8    B8_N2
segAlu0[6]    Output    PIN_AD12    3.3-V LVTTL (default)    24mA (default)    8    B8_N1
segAlu0[7]    Output    PIN_AF12    3.3-V LVTTL (default)    24mA (default)    8    B8_N1
segAlu1[0]    Output    PIN_AG13    3.3-V LVTTL (default)    24mA (default)    8    B8_N0
segAlu1[1]    Output    PIN_AE16    3.3-V LVTTL (default)    24mA (default)    7    B7_N3
segAlu1[2]    Output    PIN_AF16    3.3-V LVTTL (default)    24mA (default)    7    B7_N3
segAlu1[3]    Output    PIN_AG16    3.3-V LVTTL (default)    24mA (default)    7    B7_N3
segAlu1[4]    Output    PIN_AE17    3.3-V LVTTL (default)    24mA (default)    7    B7_N3
segAlu1[5]    Output    PIN_AF17    3.3-V LVTTL (default)    24mA (default)    7    B7_N2
segAlu1[6]    Output    PIN_AD17    3.3-V LVTTL (default)    24mA (default)    7    B7_N2
segAlu1[7]    Output    PIN_AC17    3.3-V LVTTL (default)    24mA (default)    7    B7_N2
segPc0[0]    Output    PIN_H6        3.3-V LVTTL (default)    24mA (default)    2    B2_N0
segPc0[1]    Output    PIN_H4        3.3-V LVTTL (default)    24mA (default)    2    B2_N1
segPc0[2]    Output    PIN_H7        3.3-V LVTTL (default)    24mA (default)    2    B2_N0
segPc0[3]    Output    PIN_H8        3.3-V LVTTL (default)    24mA (default)    2    B2_N0
segPc0[4]    Output    PIN_G4        3.3-V LVTTL (default)    24mA (default)    2    B2_N0
segPc0[5]    Output    PIN_F4        3.3-V LVTTL (default)    24mA (default)    2    B2_N0
segPc0[6]    Output    PIN_E4        3.3-V LVTTL (default)    24mA (default)    2    B2_N0
segPc0[7]    Output    PIN_K2        3.3-V LVTTL (default)    24mA (default)    2    B2_N2
segPc1[0]    Output    PIN_K3        3.3-V LVTTL (default)    24mA (default)    2    B2_N2
segPc1[1]    Output    PIN_J1        3.3-V LVTTL (default)    24mA (default)    2    B2_N2
segPc1[2]    Output    PIN_J2        3.3-V LVTTL (default)    24mA (default)    2    B2_N2
segPc1[3]    Output    PIN_H1        3.3-V LVTTL (default)    24mA (default)    2    B2_N2
segPc1[4]    Output    PIN_H2        3.3-V LVTTL (default)    24mA (default)    2    B2_N2
segPc1[5]    Output    PIN_H3        3.3-V LVTTL (default)    24mA (default)    2    B2_N1
segPc1[6]    Output    PIN_G1        3.3-V LVTTL (default)    24mA (default)    2    B2_N2
segPc1[7]    Output    PIN_G2        3.3-V LVTTL (default)    24mA (default)    2    B2_N2
segTick[0]    Output    PIN_M3        3.3-V LVTTL (default)    24mA (default)    2    B2_N3
segTick[1]    Output    PIN_L1        3.3-V LVTTL (default)    24mA (default)    2    B2_N3
segTick[2]    Output    PIN_L2        3.3-V LVTTL (default)    24mA (default)    2    B2_N3
segTick[3]    Output    PIN_L3        3.3-V LVTTL (default)    24mA (default)    2    B2_N2
segTick[4]    Output    PIN_K1        3.3-V LVTTL (default)    24mA (default)    2    B2_N2
segTick[5]    Output    PIN_K4        3.3-V LVTTL (default)    24mA (default)    2    B2_N2
segTick[6]    Output    PIN_K5        3.3-V LVTTL (default)    24mA (default)    2    B2_N1
segTick[7]    Output    PIN_K6        3.3-V LVTTL (default)    24mA (default)    2    B2_N1

Facebook

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