Single Cycle로 구현한 small MIPS Processor 입니다.
총 3 개의 소스를 첨부하였으며, 기존의 32bit-RCA 와 ALU, Registerfiles를 프로젝트 내에 추가 하여 합성하면 됩니다.
inst_rom.v의 내용은 1~9까지의 합을 도출하는것으로 결과값으로 45 혹은 h2D가 나오게 됩니다.
이전 Verilog HDL 소스와 마찬가지로 상업적 이용은 안됩니다.
 닫기  Code Type : VerilogHDL
 닫기  Code Type : VerilogHDL
/*
-----------------------------------------------------------------------
    Title : small MIPS Processor
      File  : mips.v
-----------------------------------------------------------------------
      Author     : Oh,Hyung-Tak
      Organization : Kwangwoon university
      Created    : 2007.4.30
      Last update  : 2007.5.21
      Platform    : WINDOWS XP
      Simulators  : Quartus II 6.0
      Synthesizers : Quartus II 6.0
      Target     : Cyclone II:AUTO
-----------------------------------------------------------------------
      Descriptions       : sMIPS를 설계합니다.
      Revisions Number    : 1
      Version          : 1.0
      Date of change      : 2007.5.21
      Modifier          : Oh,Hyung-Tak ( ohyung@ohyung.com )
      Description of change :
-------------------------------------------------------------------------
*/
//mips top moudle
module mips ( clk, rst_n, oRegDst, oBranch, oMemRead, oMemtoReg, oALUOp,
              oMemWrite, oALUSrc, oRegWrite, oJump, oAluResult, oInst, oWePC, oCurPC, oNxtPC,
              oRead1Reg, oRead2Reg, oWriteReg, oReadData1, oReadData2, oWriteDataReg, oAddress, oWriteData, oReadData);
    input           clk, rst_n;
    output          oRegDst, oBranch, oMemRead, oMemtoReg, oMemWrite, oALUSrc, oRegWrite, oJump, oWePC;
    output [01:0] oALUOp;
    output [04:0] oRead1Reg, oRead2Reg, oWriteReg;
    output [07:0] oAddress;
    output [31:0] oAluResult, oInst, oCurPC, oNxtPC,
                  oWriteDataReg, oReadData1, oReadData2, oWriteData, oReadData;
    wire        RegDst, Branch, MemRead, ALUSrc;
    wire        we_pc;
    wire [31:0] cur_pc, next_pc;
    wire [31:0]    inc_adder_pc, adr_adder_pc;
    assign         inc_adder_pc = 32'h00000004;
    wire [31:0]    extended_inst;
    wire [31:0] sft_2_v;
    wire        carryout_adder_pc, carryout_adder_pc2;
    wire [31:0] newadr_adder_pc2;
    wire         PCSrc;
    wire [27:0] sfted_adr;
    wire [31:0] jump_address;
    wire        Jump;
    wire [31:0] next_mux_out;
    wire        we_inst_mem;
    wire [31:0] adr_inst_mem, inst_inst_mem;
    wire        RegWrite; 
    wire [04:0] writeregister_reg_file;    
    wire [31:0] writedata_reg_file, readdata1_reg_file, readdata2_reg_file; 
    wire        carryout_alu, overflow_alu, Zero; 
    wire [1:0]  ALUOp;
    wire [2:0]    control_alu;    
    wire [31:0] in2_alu, result_alu;    
    wire [31:0] writedata_data_mem, readdata_data_mem;    
    wire         MemWrite;    
    wire         MemtoReg;    
    assign oWePC = we_pc;
    assign oRegDst = RegDst;
    assign oBranch = Branch;
    assign oMemRead = MemRead;
    assign oMemtoReg = MemtoReg;
    assign oALUOp = ALUOp;
    assign oMemWrite = MemWrite;
    assign oALUSrc = ALUSrc;
    assign oRegWrite = RegWrite;
    assign oJump = Jump;
    assign oInst = inst_inst_mem;
    assign oAluResult = result_alu;
    assign oCurPC = cur_pc;
    assign oNxtPC = next_pc;
    assign oRead1Reg = inst_inst_mem[25:21];
    assign oRead2Reg = inst_inst_mem[20:16];
    assign oWriteReg = writeregister_reg_file;
    assign oWriteDataReg = writedata_reg_file;
    assign oReadData1 = readdata1_reg_file;
    assign oReadData2 = readdata2_reg_file;
    assign oAddress = result_alu[7:0];
    assign oWriteData = readdata2_reg_file;
    assign oReadData = readdata_data_mem;
    reg_32bit PC ( clk, rst_n, we_pc, next_pc, cur_pc);
    rca_32bit PC_NEXT_1 ( carryout_adder_pc, adr_adder_pc,
                            cur_pc, inc_adder_pc, 1'b0 );
    shift_26bit_to_28bit SFT_LEFT_0 (inst_inst_mem[25:0], sfted_adr);
    assign jump_address = {adr_adder_pc[31:28],sfted_adr};
    assign PCSrc = Branch & Zero;
    shift32bit_left_2bit SHIFT_LEFT_1 (extended_inst, sft_2_v);
    rca_32bit Adder_PC2 (carryout_adder_pc2, newadr_adder_pc2,
                        adr_adder_pc, sft_2_v, 1'b0);
    mux32bit_2to1 Mux_Next_PC (adr_adder_pc, newadr_adder_pc2,
                             PCSrc, next_mux_out);
    mux32bit_2to1 Mux_Jump (next_mux_out, jump_address, Jump, next_pc);
    inst_rom Inst_Mem (cur_pc[7:0],inst_inst_mem);
    mux5bit_2to1 Mux_Write_Reg (inst_inst_mem[20:16], inst_inst_mem[15:11],
                     RegDst, writeregister_reg_file);
    reg_files Register_Files (clk, rst_n, RegWrite,
                            inst_inst_mem[25:21], inst_inst_mem[20:16],
                            writeregister_reg_file, writedata_reg_file,
                            readdata1_reg_file, readdata2_reg_file);
    sign_extend SIGN_EXTEND_0 (inst_inst_mem[15:0], extended_inst);
    mux32bit_2to1 ALU_input2_0 (readdata2_reg_file, extended_inst, ALUSrc, in2_alu);
    alu_control ALU_CONTROL ( inst_inst_mem[5:0], ALUOp, control_alu);
    alu_32bit ALU ( readdata1_reg_file, in2_alu,
                    control_alu, result_alu, carryout_alu, overflow_alu, Zero);
    data_ram Data_Mem ( result_alu[7:0], clk, rst_n, readdata2_reg_file,
                        MemWrite, readdata_data_mem);
    mux32bit_2to1 DATA_MEMORY_OUTPUT( result_alu, readdata_data_mem, MemtoReg, writedata_reg_file);
    mips_control MIPS_CONTROL (clk, rst_n, inst_inst_mem[31:26], we_pc,
                                 RegDst, Branch, MemRead, MemtoReg, ALUOp,
                                MemWrite, ALUSrc, RegWrite, Jump );
endmodule
module mux5bit_2to1(in0, in1, sel, out_mux);
    input            sel;
    input  [4:0] in0, in1;
    output [4:0] out_mux;
    reg   [31:0] out_mux;
    always @ (sel or in0 or in1)
    begin
        case (sel)
            0 : out_mux = in0;
            1 : out_mux = in1;
            default : out_mux = 32'b0;
        endcase
    end
endmodule
module mux32bit_2to1(in0, in1, sel, out_mux);
    input            sel;
    input  [31:0] in0, in1;
    output [31:0] out_mux;
    reg   [31:0] out_mux;
    always @ (sel or in0 or in1)
    begin
        case (sel)
            0 : out_mux = in0;
            1 : out_mux = in1;
            default : out_mux = 32'b0;
        endcase
    end
endmodule
module sign_extend (in_d, out_d);
    input  [15:0] in_d;
    output [31:0] out_d;
    assign out_d = { {16{in_d[15]}} , in_d };
endmodule
module shift_26bit_to_28bit (in_d, out_d);
    input  [25:0] in_d;
    output [27:0] out_d;
    assign out_d = in_d<<2;
endmodule
module shift32bit_left_2bit (in_d, out_d);
    input  [31:0] in_d;
    output [31:0] out_d;
    assign out_d = in_d<<2;
endmodule
module alu_control ( inst, control, out_sig );
    input  [1:0] control;
    input  [5:0] inst;
    output [2:0] out_sig;
    assign out_sig[0] = control[1]&(inst[0]|inst[3]);
    assign out_sig[1] = ~inst[2]|~control[1];
    assign out_sig[2] = control[0]|(control[1]&inst[1]);
endmodule
module mips_control ( clk, rst_n, inst, we_pc, regdst, branch, memread, memtoreg, aluop, memwrite, alusrc, regwrite, jump);
    input              clk, rst_n;
    input        [5:0] inst;
    output reg          memwrite,regwrite;
    output reg         we_pc, regdst, branch, memread, memtoreg,alusrc,jump;
    output reg [1:0] aluop;
    always @ (negedge clk or negedge rst_n)
    begin
        if(rst_n == 1'b0) begin
            memwrite = 1'b0;
            regwrite = 1'b0;
        end
        else begin
            case(inst)
                35 : begin
                    memwrite = 1'b0;
                    regwrite = 1'b1;
                end
                0 : begin
                    memwrite = 1'b0;
                    regwrite = 1'b1;
                end
                43 : begin
                    memwrite = 1'b1;
                    regwrite = 1'b0;
                end
                default : begin
                    memwrite = 1'b0;
                    regwrite = 1'b0;
                end
            endcase
        end
    end
    always @ (inst)
    begin
        we_pc = 1'b1;
            case (inst)
            0  :
            begin
                regdst = 1'b1;
                alusrc = 1'b0;
                memtoreg = 1'b0;
                memread = 1'b0;
                branch = 1'b0;
                aluop = 2'b10;
                jump = 1'b0;
            end
            2  :
            begin
                regdst = 1'b0;
                alusrc = 1'b0;
                memtoreg = 1'b0;
                memread = 1'b0;
                branch = 1'b0;
                aluop = 2'b00;
                jump = 1'b1;
            end
            4  :
            begin
                regdst = 1'bx;
                alusrc = 1'b0;
                memtoreg = 1'bx;
                memread = 1'b0;
                branch = 1'b1;
                aluop = 2'b01;
                jump = 1'b0;
            end
            35 :
            begin
                regdst = 1'b0;
                alusrc = 1'b1;
                memtoreg = 1'b1;
                memread = 1'b1;
                branch = 1'b0;
                aluop = 2'b00;
                jump = 1'b0;
            end
            43 :
            begin
                regdst = 1'bx;
                alusrc = 1'b1;
                memtoreg = 1'b1;
                memread = 1'b0;
                branch = 1'b0;
                aluop = 2'b00;
                jump = 1'b0;
            end
            default :
            begin
                regdst = 1'b0;
                branch = 1'b0;
                memread = 1'b0;
                memtoreg = 1'b0;
                alusrc = 1'b0;
                jump = 1'b0;
                aluop = 2'b00;
            end
        endcase
    end
endmodule 닫기
 닫기  닫기  Code Type : VerilogHDL
 닫기  Code Type : VerilogHDL
// megafunction wizard: %RAM: 1-PORT%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: altsyncram
// ============================================================
// File Name: data_ram.v
// Megafunction Name(s):
//             altsyncram
//
// Simulation Library Files(s):
//             altera_mf
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 7.0 Build 33 02/05/2007 SJ Web Edition
// ************************************************************
//Copyright (C) 1991-2007 Altera Corporation
//Your use of Altera Corporation's design tools, logic functions
//and other software and tools, and its AMPP partner logic
//functions, and any output files from any of the foregoing
//(including device programming or simulation files), and any
//associated documentation or information are expressly subject
//to the terms and conditions of the Altera Program License
//Subscription Agreement, Altera MegaCore Function License
//Agreement, or other applicable license agreement, including,
//without limitation, that your use is for the sole purpose of
//programming logic devices manufactured by Altera and sold by
//Altera or its authorized distributors.  Please refer to the
//applicable agreement for further details.
/**
 addi 와 subi 등의 명령어가 없기 때문에 레지스터의 값을 초기화 해줄 수 없다.
 따라서 data memory에 임의의 상수값을 넣고 lw 를 사용해아야 레지스터를 초기화 할 수 있다.
 아래 module 은 data memory 를 나타내고 임의로 그 값일 넣어 놓을 수 있도록 설계되어 있다.
**/
module data_ram (
                address,
                clk,
                rst_n,
                data,
                wren,
                q);
    input      clk, rst_n, wren;
    input  [07:0] address;
    input  [31:0] data;
    output [31:0] q;
    wire [15:0] we;
   wire [31:0] r00,r01,r02,r03,r04,r05,r06,r07,r08,r09,
           r10,r11,r12,r13,r14,r15;
  decoder8bit ADR_DECODER0 (address, we);
    reg_32bit2 u00  (clk, rst_n, 32'h00008000, we[00] & wren, data, r00);
    reg_32bit2 u04  (clk, rst_n, 32'h00000400, we[01] & wren, data, r01);
    reg_32bit2 u08  (clk, rst_n, 32'h00000400, we[02] & wren, data, r02);
    reg_32bit2 u0c  (clk, rst_n, 32'h10350301, we[03] & wren, data, r03);
    reg_32bit2 u10  (clk, rst_n, 32'h0A30C0A0, we[04] & wren, data, r04);
    reg_32bit2 u14  (clk, rst_n, 32'h0000000A, we[05] & wren, data, r05);
    reg_32bit2 u18  (clk, rst_n, 32'h00000000, we[06] & wren, data, r06);
    reg_32bit2 u1c  (clk, rst_n, 32'h00000001, we[07] & wren, data, r07);
    reg_32bit2 u20  (clk, rst_n, 32'h00000000, we[08] & wren, data, r08);
    reg_32bit2 u24  (clk, rst_n, 32'h00000000, we[09] & wren, data, r09);
    reg_32bit2 u28  (clk, rst_n, 32'h00000000, we[10] & wren, data, r10);
    reg_32bit2 u2c  (clk, rst_n, 32'h00000000, we[11] & wren, data, r11);
    reg_32bit2 u30  (clk, rst_n, 32'h00000000, we[12] & wren, data, r12);
    reg_32bit2 u34  (clk, rst_n, 32'h00000000, we[13] & wren, data, r13);
    reg_32bit2 u38  (clk, rst_n, 32'h00000000, we[14] & wren, data, r14);
    reg_32bit2 u3c  (clk, rst_n, 32'h00000000, we[15] & wren, data, r15);
  mux32bit_16to1 mux0 (r00, r01, r02, r03, r04, r05, r06, r07,
                    r08, r09, r10, r11, r12, r13, r14, r15,
              address, q);
endmodule
// register file sub module //
/* n-to-1 decoder */
module decoder8bit (reg_number, out_we);
    input    [7:0]  reg_number;
    output reg [15:0] out_we;
    always @(reg_number)
    begin
        case (reg_number)
            8'h00 : out_we = 16'h0001;
            8'h04 : out_we = 16'h0002;
            8'h08 : out_we = 16'h0004;
            8'h0c : out_we = 16'h0008;
            8'h10 : out_we = 16'h0010;
            8'h14 : out_we = 16'h0020;
            8'h18 : out_we = 16'h0040;
            8'h1c : out_we = 16'h0080;
            8'h20 : out_we = 16'h0100;
            8'h24 : out_we = 16'h0200;
            8'h28 : out_we = 16'h0400;
            8'h2c : out_we = 16'h0800;
            8'h30 : out_we = 16'h1000;
            8'h34 : out_we = 16'h2000;
            8'h38 : out_we = 16'h4000;
            8'h3c : out_we = 16'h8000;
            default : out_we = 16'h0000;
        endcase
    end
endmodule
// register file sub module //
/* 32 bit register */
module reg_32bit2 (clk, rst_n, s_data, we, data_in, data_out);
    input      clk, rst_n, we;
    input  [31:0] data_in, s_data;
    output [31:0] data_out;
    reg   [31:0] data_out;
    always @ (posedge clk or negedge rst_n)
    begin
        if (rst_n == 1'b0) begin
            data_out = s_data;
        end
        else if(we == 1'b1) begin
           data_out = data_in;
        end
    end
endmodule
/* n-to-1 decoder */
module mux32bit_16to1 (r00, r01, r02, r03, r04, r05, r06, r07,
                    r08, r09, r10, r11, r12, r13, r14, r15, select, out_we);
    input    [7:0]  select;
    input    [31:0] r00, r01, r02, r03, r04, r05, r06, r07,
                      r08, r09, r10, r11, r12, r13, r14, r15;
      output reg [31:0] out_we;
    always @(select or r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, r10, r11, r12, r13, r14, r15)
    begin
        case (select)
            8'h00 : out_we = r00;
            8'h04 : out_we = r01;
            8'h08 : out_we = r02;
            8'h0c : out_we = r03;
            8'h10 : out_we = r04;
            8'h14 : out_we = r05;
            8'h18 : out_we = r06;
            8'h1c : out_we = r07;
            8'h20 : out_we = r08;
            8'h24 : out_we = r09;
            8'h28 : out_we = r10;
            8'h2c : out_we = r11;
            8'h30 : out_we = r12;
            8'h34 : out_we = r13;
            8'h38 : out_we = r14;
            8'h3c : out_we = r15;
            default : out_we = r15;
        endcase
    end
endmodule
 닫기
 닫기  닫기  Code Type : Verilog HDL
 닫기  Code Type : Verilog HDL
// megafunction wizard: %ROM: 1-PORT%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: altsyncram
// ============================================================
// File Name: inst_rom.v
// Megafunction Name(s):
//             altsyncram
//
// Simulation Library Files(s):
//             altera_mf
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 7.0 Build 33 02/05/2007 SJ Web Edition
// ************************************************************
// 아래 모듈은 여러분들의 assembly language 코드를 넣는 부분이 되겠다.
// 각 address 들어있는 32-bit data 는 assembly 코드를 의미한다.
module inst_rom (
    address,
    q );
    input     [7:0] address;
    output reg [31:0] q;
    always @ (address)
    begin
        case (address)
            8'h00 : q = 32'h8c110000;
            8'h04 : q = 32'h8c120004;
            8'h08 : q = 32'h02329820;
            8'h0c : q = 32'h0232a024;
            8'h10 : q = 32'h0232a825;
            8'h14 : q = 32'h0232b022;
            8'h18 : q = 32'h0251b82a;
            8'h1c : q = 32'h8c130008;
            8'h20 : q = 32'h12530002;
            8'h24 : q = 32'hac120004;
            8'h28 : q = 32'h0800000d;
            8'h2c : q = 32'hac170004;
            8'h30 : q = 32'h0800000a;
            8'h34 : q = 32'h8c110014;
            8'h38 : q = 32'h8c120018;
            8'h3c : q = 32'h8c13001c;
            8'h40 : q = 32'h8c140018;
            8'h44 : q = 32'h12510003;
            8'h48 : q = 32'h0292a020;
            8'h4c : q = 32'h02539020;
            8'h50 : q = 32'h08000011;
            8'h54 : q = 32'hac140018;
            default : q = 32'h00000000;
        endcase
    end
endmodule
 닫기
 닫기