Microprocessor without interlocked pipelined stages using Verilog

MIPS-Singe-Cycle-Processor

MIPS (Microprocessor without Interlocked Pipelined Stages) is a family of reduced instruction set computer (RISC) instruction set architectures (ISA).
QuestaSim simulation environment to simulate the operation of the designed device and VIVADO for evaluating the RTL and the Synthesis design.
Supported instructions:

ADD
SUB
SLT
MUL
J
BEQ
ADDI
LW
SW

ALU ( arithmetic and Logic unit) code

module ALU (
        input [31:0] readData1, // First operand from register file
    input [31:0] readData2, // Second operand from register file
    input [31:0] extended, // Extended immediate value
    input [2:0] ALUControl, // ALU control signal
    input ALUSrc, // ALU source selector
    output reg [31:0] ALU_RESULT, // ALU result
    output reg Zero // Zero flag
);

    reg [31:0] B; // ALU second operand

    // ALU operation
    always @(*) begin
        //default value
            Zero=0;
            ALU_RESULT=0;
        // Select ALU's second operand
        if (ALUSrc) begin
            B = extended;
        end else begin
            B = readData2;
        end

        // ALU operation based on ALUControl
        case (ALUControl)
            3'b000: ALU_RESULT = readData1 & B; // AND
            3'b001: ALU_RESULT = readData1 | B; // OR
            3'b010: ALU_RESULT = readData1 + B; // ADD
            3'b110: ALU_RESULT = readData1 - B; // SUB
            3'b111: ALU_RESULT = (readData1 < B) ? 1 : 0; // SLT
            default: ALU_RESULT = 0;
        endcase

        // Set Zero flag
        Zero = (ALU_RESULT == 0) ? 1 : 0 ;
    end
endmodule

ALU decoder Verilog code
module ALU_Decoder(
    input [5:0] funct,
    input [1:0] ALUOp,
    output reg [2:0] ALUControl
);

always @(*) begin
    case (ALUOp)
        2'b00: ALUControl = 3'b010; // LW/SW (add)
        2'b01: ALUControl = 3'b110; // BEQ (subtract)
        2'b10: begin
            case (funct)
                6'b100000: ALUControl = 3'b010; // ADD
                6'b100010: ALUControl = 3'b110; // SUB
                6'b100100: ALUControl = 3'b000; // AND
                6'b100101: ALUControl = 3'b001; // OR
                6'b101010: ALUControl = 3'b111; // SLT
                default: ALUControl = 3'b010; // Default to ADD
            endcase
        end
        default: ALUControl = 3'b010; // Default case
    endcase
end

endmodule

Control Unit Verilog code:
module Control_Unit(
    input [5:0] opcode,
    input [5:0] funct, // For R-type instructions
    output wire RegDst,
    output wire ALUSrc,
    output wire MemToReg,
    output wire regWrite,
    output wire memWrite,
    output wire Branch,
    output wire Jump,
    output wire [2:0] ALUControl
);
    wire [1:0] ALUOp;

    // Instantiate the Main Decoder
    Main_Decoder main_decoder_inst (
        .opcode(opcode),
        .regWrite(regWrite),
        .RegDst(RegDst),
        .ALUSrc(ALUSrc),
        .memWrite(memWrite),
        .MemToReg(MemToReg),
        .Branch(Branch),
        .Jump(Jump),
        .ALUOp(ALUOp)
    );

    // Instantiate the ALU Decoder
    ALU_Decoder alu_decoder_inst (
        .funct(funct),
        .ALUOp(ALUOp),
        .ALUControl(ALUControl)
    );
endmodule
Data memory Verilog code 
module Data_Memory(address,writeData,readData,clk,rst,memWrite);
    input clk;
    input rst;
    input memWrite;
    input [31:0] address;
    input [31:0] writeData;
    output reg [31:0] readData;

        reg [31:0] mem [99:0];  

        always @(posedge clk or posedge rst) begin
    if (rst) begin
        if (memWrite) begin
            mem[address]<=writeData;
        end
    end
    end

    // MEMORY Read
    always @(*) begin
        readData[31:0]=0;
        if (rst) begin
            readData=0;
        end
        else begin
            readData=mem[address];
        end
    end
endmodule

Instrumentation memory Verilog 
module Instruction_Memory(address,instruction);
    input [31:0] address;
    output [31:0] instruction;

        reg [31:0] I_mem [99:0];  

        assign instruction = I_mem[address>>2];
endmodule
Main decoder Verilog code:
module Main_Decoder(
    input [5:0] opcode,
    output reg RegDst,
    output reg ALUSrc,
    output reg MemToReg,
    output reg regWrite,
    output reg memWrite,
    output reg Branch,
    output reg Jump,
    output reg [1:0] ALUOp
);

always @(*) begin
    // Default values
    regWrite = 0;
    RegDst = 0;
    ALUSrc = 0;
    memWrite = 0;
    MemToReg = 0;
    ALUOp = 2'b00;
    Branch = 0;
    Jump = 0;

    case (opcode)
        6'b00_0000: begin // R-type
            regWrite = 1;
            RegDst = 1;
            ALUOp = 2'b10;
        end
        6'b00_0010: begin // J-type (jump)
            Jump = 1;
        end
        6'b00_0100: begin // BEQ (branch)
            Branch = 1;
            ALUOp = 2'b01;
        end
        6'b00_1000: begin // ADDI (I-type)
            regWrite = 1;
            ALUSrc = 1;
        end
        6'b10_0011: begin // LW (load)
            regWrite = 1;
            ALUSrc = 1;
            MemToReg = 1;
        end
        6'b10_1011: begin // SW (store)
            ALUSrc = 1;
            memWrite = 1;
        end
        default: begin
             RegDst=0;
             ALUSrc=0;
             MemToReg=0;
             regWrite=0;
             memWrite=0;
             Branch=0;
             Jump=0;
             ALUOp=0;
        end
    endcase
end
endmodule

Program counter Verilog code:

module Program_Counter(clk,rst,next_pc,pc);
        input clk,rst;
        input [31:0] next_pc;
    output reg [31:0] pc;
    always@(posedge clk or posedge rst)begin
            if(rst)
                    pc <=0;
            else
                    pc<=next_pc;        
    end
endmodule

Register file Verilog code:

module Program_Counter(clk,rst,next_pc,pc);
        input clk,rst;
        input [31:0] next_pc;
    output reg [31:0] pc;
    always@(posedge clk or posedge rst)begin
            if(rst)
                    pc <=0;
            else
                    pc<=next_pc;        
    end
endmodule

Sign extension:
module Sign_Extend(in,extended); 

    input [15:0] in;
    output reg [31:0] extended;

    always@(*) begin
         if (in[15]) begin
            extended = {{16{1'b1}}, in};
        end
        else begin
            extended = {{16{1'b0}}, in};
        end
    end

endmodule

MIPS 

module MIPS_tb(
    input clk,
    input rst
);
    wire [31:0] instruction, pc, next_pc, pc_plus4, branch_target,address;
    wire [31:0] readData1, readData2, extended, ALU_RESULT, writeData, memData;
    wire [4:0] writeReg;
    wire [2:0] ALUControl;
    wire [5:0] opcode, funct;
    wire Zero, RegDst, ALUSrc, MemToReg, regWrite, memWrite, Branch, Jump;

    // Program Counter
    Program_Counter PC (
        .clk(clk),
        .rst(rst),
        .next_pc(next_pc),
        .pc(pc)
    );

    // Instruction Memory
    Instruction_Memory IM (
        .address(address),
        .instruction(instruction)
    );

    // Control Unit
    Control_Unit CU (
        .opcode(opcode),
        .funct(funct),
        .RegDst(RegDst),
        .ALUSrc(ALUSrc),
        .MemToReg(MemToReg),
        .regWrite(regWrite),
        .memWrite(memWrite),
        .Branch(Branch),
        .Jump(Jump),
        .ALUControl(ALUControl)
    );

    // Register File
    Register_File RF (
        .clk(clk),
        .rst(rst),
        .regWrite(regWrite),
        .readReg1(instruction[25:21]),
        .readReg2(instruction[20:16]),
        .writeReg(writeReg),
        .writeData(writeData),
        .readData1(readData1),
        .readData2(readData2)
    );

    // ALU Control and ALU
    ALU ALU_ (
        .readData1(readData1),
        .readData2(readData2),
        .extended(extended),
        .ALUControl(ALUControl),
        .ALUSrc(ALUSrc),
        .Zero(Zero),
        .ALU_RESULT(ALU_RESULT)
    );

    // Sign Extension
    Sign_Extend sign_extend (
        .in(instruction[15:0]),
        .extended(extended)
    );

    // Data Memory
    Data_Memory DM (
        .clk(clk),
        .rst(rst),
        .address(ALU_RESULT),
        .writeData(readData2),
        .memWrite(memWrite),
        .readData(memData)
    );

    // MUX for write register
    assign writeReg = RegDst ? instruction[15:11] : instruction[20:16];

    // MUX for ALU result or memory data
    assign writeData = MemToReg ? memData : ALU_RESULT;

    // Next PC logic
    assign pc_plus4 = pc + 4;
    assign branch_target = pc_plus4 + (extended << 2);
    assign next_pc = (Jump) ? {pc_plus4[31:28], instruction[25:0], 2'b00} :
                     (Branch & Zero) ? branch_target : pc_plus4;

    assign address = pc;        
    assign opcode = instruction[31:26];        
    assign funct = instruction[5:0];
endmodule

Test bench MIPS 


module mips_tb;
        reg clk;
        reg rst;

MIPS_tb DUT (clk,rst);

initial begin
    clk=0;
    forever begin
            #10 clk= ~clk;
    end
end
initial begin
    $readmemh("D:/MIPS_Project/mem.dat", DUT.DM.mem);
    $readmemh("D:/MIPS_Project/inst.dat", DUT.IM.I_mem);

    rst=1;
    repeat(2) @(negedge clk);
    rst=0;

    repeat(13) @(negedge clk);
    $stop;
end
endmodule


#verilog Verilog projects  ECE projects 2025 ECE projects latest #verilogprojects #qyestverse qyestverse 

Comments

Popular posts from this blog

Number system

Realme 13+ specifications

Vivo Y300 Pro key specifications