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
Post a Comment