Shri Ramdeobaba College of Engineering and
Shri Ramdeobaba College of Engineering and
Shri Ramdeobaba College of Engineering and
Session: 2020-21(EVEN)
Project report on
“16 bit Single Cycle MIPS CPU Design and Implementation on FPGA ”
Verilog code for the MIPS processor. The Verilog code for the whole design of the
MIPS processor as follows:
module data_memory
(
input clk,
// address input, shared by read and write port
input [15:0] mem_access_addr,
// write port
input [15:0] mem_write_data, input
mem_write_en,
input mem_read,
// read port
output [15:0] mem_read_data
);
integer i;
reg [15:0] ram [255:0]; wire [7 : 0] ram_addr =
mem_access_addr[8 : 1]; initial begin
for(i=0;i<256;i=i+1) ram[i] <= 16'd0; end
always @(posedge clk) begin if (mem_write_en)
ram[ram_addr] <= mem_write_data;
end
assign mem_read_data = (mem_read==1'b1) ? ram[ram_addr]: 16'd0;
endmodule
== 0)? 16'b0 :
reg_array[reg_read_addr_1]; assign reg_read_data_2 = == 0)? 16'b0 :
( reg_read_addr_2
reg_array[reg_read_addr_2];
endmodule
// Verilog code for 16 bit single cycle MIPS CPU module mips_16( input
clk,reset,
output[15:0] pc_out, alu_result
//,reg3,reg4
);
reg[15:0] pc_current; wire
signed[15:0] pc_next,pc2;
wire [15:0] instr;
wire[1:0] reg_dst,mem_to_reg,alu_op; wire
jump,branch,mem_read,mem_write,alu_src,reg_write ; wire [2:0]
reg_write_dest; wire [15:0] reg_write_data; wire [2:0]
reg_read_addr_1; wire [15:0] reg_read_data_1; wire [2:0]
reg_read_addr_2; wire [15:0] reg_read_data_2;
wire [15:0] sign_ext_im,read_data2,zero_ext_im,imm_ext; wire JRControl;
wire [2:0] ALU_Control; wire [15:0] ALU_out; wire zero_flag; wire
signed[15:0] im_shift_1, PC_j, PC_beq, PC_4beq,PC_4beqj,PC_jr; wire
beq_control; wire [14:0] jump_shift_1; wire [15:0]mem_read_data; wire [15:0]
no_sign_ext; wire sign_or_zero;
// PC
always @(posedge clk or posedge reset) begin
if(reset) pc_current <=
16'd0; else pc_current
<= pc_next;
end // PC +
2
assign pc2 = pc_current + 16'd2; //
instruction memory instr_mem
instrucion_memory(.pc(pc_current),.instruction(instr)); // jump shift left
1
.mem_write(mem_write),.alu_src(alu_src),.reg_write(reg_write),.sign_or_zer
o(sign_or_zero));
// multiplexer regdest assign reg_write_dest = (reg_dst==2'b10) ? 3'b111: ((reg_dst==2'b01)
? instr[6:4]
:instr[9:7]);
// register file assign reg_read_addr_1 = instr[12:10]; assign reg_read_addr_2 = instr[9:7];
register_file reg_file(.clk(clk),.rst(reset),.reg_write_en(reg_write),
.reg_write_dest(reg_write_dest),
.reg_write_data(reg_write_data),
.reg_read_addr_1(reg_read_addr_1),
.reg_read_data_1(reg_read_data_1),
.reg_read_addr_2(reg_read_addr_2),
.reg_read_data_2(reg_read_data_2));
//.reg3(reg3),
//.reg4(reg4)); // sign extend
assign sign_ext_im = {{9{instr[6]}},instr[6:0]}; assign zero_ext_im =
{{9{1'b0}},instr[6:0]}; assign imm_ext = (sign_or_zero==1'b1) ? sign_ext_im :
zero_ext_im; // JR control
JR_Control
JRControl_unit(.alu_op(alu_op),.funct(instr[3:0]),.JRControl(JRControl)); // ALU control
unit
ALUContro
l ALU_Control_unit(.ALUOp(alu_op),.Function(instr[3:0]),.ALU_Control(ALU_
Control));
// multiplexer alu_src
assign read_data2 = (alu_src==1'b1) ? imm_ext : reg_read_data_2; // ALU
alu
alu_unit(.a(reg_read_data_1),.b(read_data2),.alu_control(ALU_Control),.res
ult(ALU_out),.zero(zero_flag)); // immediate shift 1
assign im_shift_1 = {imm_ext[14:0],1'b0};
//
assign no_sign_ext = ~(im_shift_1) + 1'b1;
// PC beq add assign PC_beq = (im_shift_1[15] == 1'b1) ? (pc2 - no_sign_ext):
(pc2 +im_shift_1); // beq control assign
beq_control = branch & zero_flag;
// PC_beq
assign PC_4beq = (beq_control==1'b1) ? PC_beq : pc2;
// PC_j
assign PC_j = {pc2[15],jump_shift_1};
// PC_4beqj
assign PC_4beqj = (jump == 1'b1) ? PC_j : PC_4beq;
// PC_jr
assign PC_jr = reg_read_data_1;
// PC_next
assign pc_next = (JRControl==1'b1) ? PC_jr : PC_4beqj;
// data memory
data_memory datamem(.clk(clk),.mem_access_addr(ALU_out),
.
mem_write_data(reg_read_data_2),.mem_write_en(mem_write),.mem_read( mem_r
ead),
.mem_read_data(mem_read_data));
// write back assign reg_write_data = (mem_to_reg == 2'b10) ? pc2:((mem_to_reg
== 2'b01)? mem_read_data: ALU_out);
// output
assign pc_out = pc_current; assign alu_result
= ALU_out; endmodule
Testbench
`timescale 1ns / 1ps
Output
Important term
It is a very important hardware component of central processing unit of a computer. ALU is the
main hardware part where the operations get executed.
3] Register File:
In processor, ALU gets data from a Register Bank / Register File. As we have designed our
ISA, our register file should have 16 registers. And the design should be easy enough to choose
rs, rt, rd values.
4] Control Unit
Control unit is the circuit in processor which controls the flow of data and operation of ALU.
Initially an instruction is loaded in instruction memory. According to Opcode of that instruction,
control unit gets understood what the instruction wants to execute. Then it flows the data in
such a path so that ALU gets necessary data to execute.
Single cycle processor is a processor that carries out 1 instruction in a single clock cycle.
6] FPGA
Field Programmable Gate Arrays (FPGAs) are semiconductor devices that are
Fibonacci Series - Fibonacci series is a series of numbers, where the next number is
The Fibonacci numbers are the numbers in the following integer sequence.
module fib(input clock, reset, input [5:0] n, output reg ready, output [15:0] value);
reg [15:0] previous, current; reg [5:0] counter;
if (counter == n) ready
<= 1;
end
// Read the value of the nth fibonacci number from the internal register assign
value = current;
endmodule
Output
Result