Single Cycle로 구현한 small MIPS Processor 입니다.
총 3 개의 소스를 첨부하였으며, 기존의 32bit-RCA 와 ALU, Registerfiles를 프로젝트 내에 추가 하여 합성하면 됩니다.
inst_rom.v의 내용은 1~9까지의 합을 도출하는것으로 결과값으로 45 혹은 h2D가 나오게 됩니다.
이전 Verilog HDL 소스와 마찬가지로 상업적 이용은 안됩니다.
닫기 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
// 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
// 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
닫기