project single cyclemips processor_verilog

22
Designing a Single Cycle MIPS microprocessor in Verilog Harsha Yelisala Spring 2009

Upload: harsha-yelisala

Post on 20-May-2015

393 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Project single cyclemips processor_verilog

Designing a Single Cycle MIPS microprocessor inVerilog

Harsha Yelisala

Spring 2009

Page 2: Project single cyclemips processor_verilog

Technology Profile

The following technologies are used in this project,

I MIPS Processor Architecture.

I Verilog HDL.

I VHDL HDL.

I ModelSim 6.2 SE

I Timing Analysis

I SPIM

Page 3: Project single cyclemips processor_verilog

Aim

The Objectives of this project are

I 1. To design a Single Cycle MIPS Microprocessor in Verilogand simulate the design in Modelsim.

I 2. To get hands-on experience in Verilog coding.

I 3. To get working expertise in using the Modelsim PEStudent Edition 6.6a.

I 4. To understand the various stages of a processor design.

I 5. To analyze a processor from timing perspective.

Page 4: Project single cyclemips processor_verilog

Abstract

Designing a processor is one of the most challenging tasks in chipdesigning industry. Being part of processor making is the ultimategoal of many hardware engineers. Hence a thorough understandingof working of a processor is of high importance. This project dealswith designing a single cycle microprocessor in Verilog. The designis then simulated in Modelsim.

Page 5: Project single cyclemips processor_verilog

Work Flow

I 1. Studying the data path of a processor from ComputerOrganization and Design, The Hardware Software Interface3rd Edition 2004.

I 2. Creating Verilog modules for each functional unit of thedatapath.

I 3. Testing the created modules with customized test benches.

I 4. Combining the designed modules to a single top module.

I 5. Verifying and testing the final module in Modelsim.

Page 6: Project single cyclemips processor_verilog

Datapath

The datapath of a processor has the following functional units.

I 1. ProgramCounter

I 2. Register File

I 3. Arithmetic Logic Unit

I 4. Instruction Memory

I 5. Data Memory

I 6. Adders

I 7. Multiplexors

I 8. Shifters

I 9. SignExtender and

I 10. Control Unit

Page 7: Project single cyclemips processor_verilog

Datapath

Page 8: Project single cyclemips processor_verilog

Control Information

ALU Control Lines Function

0000 AND0001 OR0010 ADD0110 SUB0111 SLT1100 NOR

Page 9: Project single cyclemips processor_verilog

Alu Control Implementation-1 of 2

Opcode AluOp Operation Funct Field Desired ALU Action ALU Control output

LW 00 load word XXXXXX add 0010SW 00 store word XXXXXX add 0010

BEQ 01 branch equal XXXXXX sub 0110R-type 10 add 100000 add 0010R-type 10 sub 100010 sub 0110R-type 10 and 100100 and 0000R-type 10 or 100101 or 0001R-type 10 slt 101010 set lessthan 0111

Page 10: Project single cyclemips processor_verilog

Alu Control Implementation-2 of 2

AluOp 1 AluOp 0 F5 F4 F3 F2 F1 F0 Operation

0 0 X X X X X X 0010

X 1 X X X X X X 0110

1 X X X 0 0 0 0 0010

1 X X X 0 0 1 0 0110

1 X X X 0 1 0 0 0000

1 X X X 0 1 0 1 0001

1 X X X 1 0 1 0 0111

Page 11: Project single cyclemips processor_verilog

Control Block Implementation

Control R-Format LW SW BEQ

RegDst 1 0 X X

ALUSrc 0 1 1 0

MemtoReg 0 1 X X

RegWrite 1 1 0 0

MemRead 0 1 0 0

MemWrite 0 0 1 0

Branch 0 0 0 1

AluOp1 1 0 0 0

AluOp 0 0 0 0 1

Page 12: Project single cyclemips processor_verilog

ProgramCounter

module PC(clock,reset,pcin,pcout);

input clock;

input reset;

input [31:0] pcin;

output [31:0] pcout;

reg clk;

reg [31:0] pcout;

initial

begin

clk=clock;

end

always

#5 clk = ~clk;

always @(posegde(clk))

pcout<=pcin;

endmodule

Page 13: Project single cyclemips processor_verilog

RegisterFile

module REGISTERS(ReadRegister1,ReadRegister2, WriteRegister, WriteData_reg,RegWrite,ReadData1,ReadData2);

input [4:0] ReadRegister1, ReadRegister2, WriteRegister;

input [31:0] WriteData_reg;

input RegWrite;

output [31:0] ReadData1, ReadData2;

reg [31:0] ReadData1, ReadData2;

reg [31:0] REG[0:31];

integer i;

initial

begin

for(i=0;i<32;i=i+1)

REG[i]=0;

end

always @(ReadRegister1,ReadRegister2,RegWrite,WriteRegister,WriteData_reg)

if(RegWrite==1’b1)

REG[WriteRegister]=WriteData_reg;

else

begin

ReadData1 <= REG[ReadRegister1];

ReadData2 <= REG[ReadRegister2];

end

endmodule

Page 14: Project single cyclemips processor_verilog

ArithmeticLogicUnit

module ALU(Read_data_1, Read_data_2, ALUControl, ALUresult, isZero);

input [31:0] Read_data_1, Read_data_2;

input [3:0] ALUControl;

output [31:0]ALUresult, isZero;

reg [31:0] ALUresult, isZero;

reg [3:0] addcode, subcode, andcode, orcode, sltcode;

initial begin

addcode[3:0] <= 4’b0010;

subcode[3:0] <= 4’b0110;

andcode[3:0] <= 4’b0000;

orcode[3:0] <= 4’b0001;

sltcode[3:0] <= 4’b0111;

end

always @(Read_data_1, Read_data_2, ALUControl)

if (ALUControl == addcode) //add

ALUresult = Read_data_1 + Read_data_2;

else if(ALUControl == subcode) //sub

ALUresult = Read_data_1 - Read_data_2;

else if(ALUControl == andcode) //and

ALUresult = Read_data_1 & Read_data_2;

else if(ALUControl == orcode) //or

ALUresult = Read_data_1 | Read_data_2;

else if(ALUControl == sltcode) //slt

if(Read_data_1 < Read_data_2)

ALUresult = 32’b00000000000000000000000000000001;

else

ALUresult = 32’b00000000000000000000000000000000;

always @(Read_data_1, Read_data_2, ALUControl,ALUresult)

if(ALUresult == 32’b0)

isZero = 32’b00000000000000000000000000000001;

else

isZero = 32’b00000000000000000000000000000000;

endmodule

Page 15: Project single cyclemips processor_verilog

InstructionMemory

module INSTRUCTIONMEMORY(ReadAddress,Instruction);

input [31:0] ReadAddress;

output [31:0] Instruction;

reg [31:0] Instruction;

reg [31:0] IMEM[0:64];

integer i;

initial begin

for(i=0;i<64;i=i+1)

IMEM[i]=1’b0;

end

always @(ReadAddress)

Instruction=IMEM[ReadAddress];

endmodule

Page 16: Project single cyclemips processor_verilog

DataMemory

module DATAMEMORY(Address,MemWrite,MemRead,WriteData,ReadData);

input [31:0] Address;

input MemWrite;

input MemRead;

input [31:0] WriteData;

output [31:0] ReadData;

reg [31:0] ReadData;

reg [31:0] RAM[0:63];

integer i,j;

initial

begin

for(i=0;i<64;i=i+1)

for(j=0;j<32;j=j+1)

RAM[i][j]<=0;

end

always @(Address,MemWrite,MemRead,WriteData)

if(MemWrite==1’b1)

RAM[Address]=WriteData;

else if(MemRead==1’b1)

ReadData=RAM[Address];

endmodule

Page 17: Project single cyclemips processor_verilog

ControlUnitmodule CONTROL(opcode,RegDst,Branch,MemRead,MemtoReg,ALUOp,MemWrite,ALUSrc,RegWrite);

input [6:0] opcode;

output RegDst, Branch, MemRead, MemtoReg, MemWrite, ALUSrc, RegWrite;

output [1:0] ALUOp;

reg RegDst, Branch, MemRead, MemtoReg, MemWrite, ALUSrc, RegWrite;

reg [1:0] ALUOp;

always @(opcode)

begin

if(opcode==6’b000000) //r controls

begin

RegDst<=1’b1;

ALUSrc<=1’b0;

MemtoReg<=1’b0;

RegWrite<=1’b1;

MemRead<=1’b0;

MemWrite<=1’b0;

Branch<=1’b0;

ALUOp<=2’b10;

end

if(opcode==6’b100011) //lw controls

begin

RegDst<=1’b0;

ALUSrc<=1’b1;

MemtoReg<=1’b1;

RegWrite<=1’b1;

MemRead<=1’b1;

MemWrite<=1’b0;

Branch<=1’b0;

ALUOp<=2’b00;

end

if(opcode==6’b101011) //sw controls

begin

RegDst<=1’bx;

ALUSrc<=1’b1;

MemtoReg<=1’bx;

RegWrite<=1’b0;

MemRead<=1’b0;

MemWrite<=1’b1;

Branch<=1’b0;

ALUOp<=2’b00;

end

if(opcode==6’b101011) //beq controls

begin

RegDst<=1’bx;

ALUSrc<=1’b0;

MemtoReg<=1’bx;

RegWrite<=1’b0;

MemRead<=1’b0;

MemWrite<=1’b0;

Branch<=1’b1;

ALUOp<=2’b01;

end

end

endmodule

Page 18: Project single cyclemips processor_verilog

Adders and Multiplexors

module ADD(data1, data2, sum);

input [31:0] data1;

input [31:0] data2;

output [31:0]sum;

reg [31:0]sum;

always @(data1, data2)

sum = data1 + data2;

endmodule

module MUX(mux_in_1,mux_in_2,sel,mux_out);

input [31:0] mux_in_1;

input [31:0] mux_in_2;

input sel;

output [31:0] mux_out;

reg [31:0] mux_out;

always @(mux_in_1,mux_in_2,sel)

if(sel==1’b0)

mux_out=mux_in_1;

else

mux_out=mux_in_2;

endmodule

Page 19: Project single cyclemips processor_verilog

Shifter and Signextender

module SHIFTLEFT(shift_in,shift_out);

input [31:0] shift_in;

output [31:0] shift_out;

reg [31:0] shift_out;

reg [29:0] temp;

always @(shift_in)

shift_out= shift_in<<2;

endmodule

module SIGNEXTEND(sign_in, sign_out);

input [15:0] sign_in;

output [31:0] sign_out;

reg [31:0] sign_out;

reg [31:0] tmp;

integer i;

initial

begin

sign_out <=32’b0;

end

always @(sign_in)

if(sign_in[15] == 0)

sign_out = {32’b000000000000000000,sign_in};

else

sign_out = {32’b111111111111111111,sign_in};

endmodule

Page 20: Project single cyclemips processor_verilog

SingleCycleMIPSProcessormodule SINGLECYCLEMIPSPROCESSOR(globalclock,globalreset);

input globalclock;

input globalreset;

wire [31:0] _pcout;

wire [31:0] _Instruction;

wire [31:0] _ReadData1;

wire [31:0] _ReadData2;

wire _RegDst,_Branch,_MemRead,_MemtoReg,_MemWrite,_ALUSrc,_RegWrite;

wire [1:0] _ALUOp;

wire [31:0] _sign_out;

wire [31:0] _shift_out;

wire [31:0] _sum_pcplus4;

wire [31:0] _sum_branchadder;

wire _sel_regfiledest;

wire [31:0] _mux_out_alusrc;

wire _sel_alusrc;

wire [31:0] _mux_out_branchornot;

wire _sel_branchornot;

wire [31:0] #20 _mux_out_regfiledata;

wire [4:0] _mux_out_regfiledest_5b;

wire [3:0] _ALUControl;

wire [31:0] _ReadData;

wire [31:0] _ALUresult;

wire _isZero;

//After Portmapping

PC mypc(.clock(globalclock),.reset(globalreset),.pcin(_mux_out_branchornot),.pcout(_pcout));

INSTRUCTIONMEMORY myinstructionmemory(.ReadAddress(_pcout),.Instruction(_Instruction));

REGISTERS myregisters(.ReadRegister1(_Instruction[25:21]),.ReadRegister2(_Instruction[20:16]),.WriteRegister(_mux_out_regfiledest_5b),.WriteData_reg(_mux_out_regfiledata),.RegWrite(_RegWrite),.ReadData1(_ReadData1),.ReadData2(_ReadData2));

CONTROL mycontrol(.opcode(_Instruction[31:26]),.RegDst(_RegDst),.Branch(_Branch),.MemRead(_MemRead),.MemtoReg(_MemtoReg),.ALUOp(_ALUOp),.MemWrite(_MemWrite),.ALUSrc(_ALUSrc),.RegWrite(_RegWrite));

SIGNEXTEND mysignextend( .sign_in(_Instruction[15:0]), .sign_out(_sign_out) );

SHIFTLEFT myshiftleft( .shift_in(_sign_out), .shift_out(_shift_out) );

ADDPLUS4 myadd_pc_plus4(.data1(_pcout), .sum(_sum_pcplus4));

ADD myadd_branchadder(.data1(_sum_pcplus4), .data2(_shift_out), .sum(_sum_branchadder));

MUX5B mymux_regfiledest( .mux_in_1(_Instruction[20:16]), .mux_in_2(_Instruction[15:11]), .sel(_RegDst), .mux_out(_mux_out_regfiledest_5b) );

MUX mymux_alusrc( .mux_in_1(_ReadData2), .mux_in_2(_sign_out), .sel(_ALUSrc), .mux_out(_mux_out_alusrc) );

AND a(_sel_branchornot,Branch,isZero);

MUX mymux_branchornot( .mux_in_1(_sum_pcplus4), .mux_in_2(_sum_branchadder), .sel(_sel_branchornot), .mux_out(_mux_out_branchornot) );

MUX mymux_regfiledata( .mux_in_1(_ReadData), .mux_in_2(_ALUresult), .sel(_MemtoReg), .mux_out(_mux_out_regfiledata) );

ALUCONTROL myalucontrol( .ALUop(_ALUOp), .Funct(_Instruction[5:0]), .ALUControl(_ALUControl) );

DATAMEMORY mydatamemory(.Address(_ALUresult),.MemWrite(_MemWrite),.MemRead(_MemRead),.WriteData(_ReadData2),.ReadData(_ReadData));

ALU myalu( .Read_data_1(_ReadData1), .Read_data_2(_mux_out_alusrc), .ALUControl(_ALUControl), .ALUresult(_ALUresult),.isZero(_isZero) );

endmodule

Page 21: Project single cyclemips processor_verilog

Pros-Cons

Pros

I Simple to design

I CPI is always 1.

Cons

I It is inefficient.

I Every clockcycle must have the same length as the longestpossible path(Load instruction) in the design making the otherinstructions which work in lesser cycle time are forced to workfor extra time.

I Though the CPI is 1, the overall system performance of thedesign is not good.

Page 22: Project single cyclemips processor_verilog

Conclusion

In this academic project,

I A single cycle MIPS microprocessor is designed.

I Understood the design flow for the datapath design in aProcessor design.

I Experience gained in Verilog coding and debugging.

I Experience gained in usage of ModelSim 6.2 SE.

I Understood the necessity of Pipelining and other advancedtechniques for processor design.