Lab Report 06
Lab Report 06
ENGINEERING
COLLEGE OF E&ME, NUST, RAWALPINDI
Subject Name
Computer System Architecture
Lab Report
02
SUBMITTED TO:
Dr. Muhammad Yasin
LE Malyka Awais
SUBMITTED BY:
Student Name
1. Muhammad Mussa Kazim #404047
2. Bazil bin Amir #432243
3. Hashir Ashraf #408557
4. Sohaib Afzal #411928
MIPS 32 Processor:
Code:
1. Top Level:
initial
begin
counter = 21'd0;
end
wire[31:0] pcOut;
wire[31:0] instruction;
wire[5:0] opcode;
wire[5:0] funct;
wire[31:0] extendedtemp;
wire zeroFlag;
wire pcSrc;
instructionFetch uut1(pcOut,instruction,opcode,funct,clk,branchAddress,jumpAddress,tempJump,pcSrc,extendedtemp,zeroFlag);
wire RegDst;
wire RegWrite;
wire ALUSrc;
wire [2:0] ALUOp;
wire MemWrite;
wire MemRead;
wire MemToReg;
wire ExtOp;
wire Branch;
wire Jump;
controlUnit uut2(RegDst,RegWrite,ALUSrc,ALUOp,MemWrite,MemRead,MemToReg,ExtOp,Branch,Jump,pcSrc,opcode,funct,clk);
// assign tempJump = Jump;
//assign temppcSrc = pcSrc;
wire[31:0] rsData;
wire[31:0] rtData;
wire[31:0] rdData;
wire[31:0] extendedImmediate;
//wire[5:0] funct;
wire[4:0] shamt;
//wire[5:0] opcode;
wire [4:0]writeDataAddress;
wire[4:0] rs;
wire[4:0] rt;
instructionDecoder
uut3(rsData,rtData,rdData,extendedImmediate,shamt,writeDataAddress,rs,rt,clk,instruction,writeData,RegWrite,RegDst,ExtOp);
wire[31:0] ALUResult;
ALUmodule uut4(zeroFlag,ALUResult,rsData,rtData,extendedImmediate,ALUOp,ALUSrc);
DataMemory uut5(Result,storedWord,rtData,rs,rs,ALUResult,MemWrite,MemToReg,clk);
wire[31:0] rsData2;
wire[31:0] rtData2;
wire[31:0] rdData2;
wire[31:0] extendedImmediate2;
//output[5:0] funct,
wire[4:0] shamt2;
//output[5:0] opcode,
wire[4:0]writeDataAddress2;
wire[4:0] rs2;
wire[4:0] rt2;
instructionDecoder
uut6(rsData2,rtData2,rdData2,extendedImmediate2,shamt2,writeDataAddress2,rs2,rt2,clk,instruction,Result,RegWrite,RegDst,ExtOp);
always@(*)
begin
if(sw==1'b0)
begin
res = Result[15:0];
end
else
begin
res = Result[31:16];
end
end
always@(posedge clk)
begin
if(counter == 21'd4000000)
begin
anodes <= 4'b1110;
end
else if(counter == 21'd8000000)
begin
anodes <= 4'b1101;
end
else if(counter == 21'd12000000 )
begin
anodes <= 4'b1011;
end
else if(counter == 21'd16000000)
begin
anodes <= 4'b0111;
counter <= 21'd0;
end
counter <=counter+21'd1;
end
initial
begin
sevenseg = ~8'b00111111;
end
always @(posedge clk)
begin
case(anodes)
4'b0111:
case(res[15:12])
4'b0000: sevenseg = ~8'b00111111;
4'b0001: sevenseg = ~8'b00000110;
4'b0010: sevenseg = ~8'b01011011;
4'b0011: sevenseg = ~8'b01001111;
4'b0100: sevenseg = ~8'b01100110;
4'b0101: sevenseg = ~8'b01101101;
4'b0110: sevenseg = ~8'b01111101;
4'b0111: sevenseg = ~8'b00000111;
4'b1000: sevenseg = ~8'b01111111;
4'b1001: sevenseg = ~8'b01101111;
4'b1010: sevenseg = ~8'b01110111;
4'b1011: sevenseg = ~8'b11111111;
4'b1100: sevenseg = ~8'b00111001;
4'b1101: sevenseg = ~8'b00111111;
4'b1110: sevenseg = ~8'b01111001;
4'b1111: sevenseg = ~8'b01110001;
default: sevenseg = 8'b00000000;
endcase
4'b1011:
case(res[11:8])
4'b0000: sevenseg = ~8'b00111111;
4'b0001: sevenseg = ~8'b00000110;
4'b0010: sevenseg = ~8'b01011011;
4'b0011: sevenseg = ~8'b01001111;
4'b0100: sevenseg = ~8'b01100110;
4'b0101: sevenseg = ~8'b01101101;
4'b0110: sevenseg = ~8'b01111101;
4'b0111: sevenseg = ~8'b00000111;
4'b1000: sevenseg = ~8'b01111111;
4'b1001: sevenseg = ~8'b01101111;
4'b1010: sevenseg = ~8'b01110111;
4'b1011: sevenseg = ~8'b11111111;
4'b1100: sevenseg = ~8'b00111001;
4'b1101: sevenseg = ~8'b00111111;
4'b1110: sevenseg = ~8'b01111001;
4'b1111: sevenseg = ~8'b01110001;
default: sevenseg = 8'b00000000;
endcase
4'b1101:
case(res[7:4])
4'b0000: sevenseg = ~8'b00111111;
4'b0001: sevenseg = ~8'b00000110;
4'b0010: sevenseg = ~8'b01011011;
4'b0011: sevenseg = ~8'b01001111;
4'b0100: sevenseg = ~8'b01100110;
4'b0101: sevenseg = ~8'b01101101;
4'b0110: sevenseg = ~8'b01111101;
4'b0111: sevenseg = ~8'b00000111;
4'b1000: sevenseg = ~8'b01111111;
4'b1001: sevenseg = ~8'b01101111;
4'b1010: sevenseg = ~8'b01110111;
4'b1011: sevenseg = ~8'b11111111;
4'b1100: sevenseg = ~8'b00111001;
4'b1101: sevenseg = ~8'b00111111;
4'b1110: sevenseg = ~8'b01111001;
4'b1111: sevenseg = ~8'b01110001;
default: sevenseg = 8'b00000000;
endcase
4'b1110:
case(res[3:0])
4'b0000: sevenseg = ~8'b00111111;
4'b0001: sevenseg = ~8'b00000110;
4'b0010: sevenseg = ~8'b01011011;
4'b0011: sevenseg = ~8'b01001111;
4'b0100: sevenseg = ~8'b01100110;
4'b0101: sevenseg = ~8'b01101101;
4'b0110: sevenseg = ~8'b01111101;
4'b0111: sevenseg = ~8'b00000111;
4'b1000: sevenseg = ~8'b01111111;
4'b1001: sevenseg = ~8'b01101111;
4'b1010: sevenseg = ~8'b01110111;
4'b1011: sevenseg = ~8'b11111111;
4'b1100: sevenseg = ~8'b00111001;
4'b1101: sevenseg = ~8'b00111111;
4'b1110: sevenseg = ~8'b01111001;
4'b1111: sevenseg = ~8'b01110001;
default: sevenseg = 8'b00000000;
endcase
default: sevenseg = ~8'b00111111;
endcase
end
endmodule
2. Control Unit:
// Define the timescale
`timescale 1ns / 1ps
endmodule
3. ALU Module:
// Assign outputs
assign ALUResult = tempALUResult;
assign zeroFlag = tempzeroFlag;
endmodule
4. Data Memory:
module DataMemory(
output[31:0] Result,
output[31:0] storedWord,
input[31:0] rtData,
input[4:0] writeDataAddress, //rs
input[4:0] readDataAddress, //rs
input [31:0] ALUResult,
input MemWrite,
input MemToReg,
input clk
);
/* initial
begin
dataMemory[0] = 32'd0;
dataMemory[1] = 32'd1;
dataMemory[2] = 32'd2;
dataMemory[3] = 32'd3;
dataMemory[4] = 32'd4;
dataMemory[5] = 32'd5;
dataMemory[6] = 32'd6;
dataMemory[7] = 32'd7;
dataMemory[8] = 32'd8;
dataMemory[9] = 32'd9;
dataMemory[10] = 32'd10;
dataMemory[11] = 32'd11;
dataMemory[12] = 32'd12;
dataMemory[13] = 32'd13;
dataMemory[14] = 32'd14;
dataMemory[15] = 32'd15;
dataMemory[16] = 32'd16;
dataMemory[17] = 32'd17;
dataMemory[18] = 32'd18;
dataMemory[19] = 32'd19;
dataMemory[20] = 32'd20;
dataMemory[21] = 32'd21;
dataMemory[22] = 32'd22;
dataMemory[23] = 32'd23;
dataMemory[24] = 32'd24;
dataMemory[25] = 32'd25;
dataMemory[26] = 32'd26;
dataMemory[27] = 32'd27;
dataMemory[28] = 32'd28;
dataMemory[29] = 32'd29;
dataMemory[30] = 32'd30;
dataMemory[31] = 32'd31;
end */
(* RAM_STYLE="BLOCK" *)
reg [31:0] dataMemory [31:0];
// The forllowing code is only necessary if you wish to initialize the RAM
// contents via an external file (use $readmemb for binary data)
initial
$readmemh(DATA_FILE, dataMemory, INIT_START_ADDR, INIT_END_ADDR);
reg[31:0] tempResult;
reg[31:0] tempstoredWord;
always@(*)
begin
if(MemWrite==1)
begin
dataMemory[writeDataAddress] = rtData; //dataMemory[rs] = rtData (sw)
tempstoredWord = dataMemory[writeDataAddress];
end
if(MemToReg==1)
begin
tempResult = dataMemory[readDataAddress]; // rt = dataMemory[rs] (lw)
end
else
begin
tempResult = ALUResult;
end
end
endmodule
5. Instruction Decoder:
module instructionDecoder(
output[31:0] rsData,
output[31:0] rtData,
output[31:0] rdData,
output[31:0] extendedImmediate,
//output[5:0] funct,
output[4:0] shamt,
//output[5:0] opcode,
output [4:0]writeDataAddress,
output[4:0] rs,
output[4:0] rt,
input clk,
input[31:0] instruction,
input[31:0] writeData,
input RegWrite, //� Write Enable signal for the Register File
input RegDst, //� Selects the write address for the Register File
input ExtOp //� selects between Sign and Zero extension of the immediate field
);
(* RAM_STYLE="BLOCK" *)
reg [31:0] registerFile [31:0];
// The forllowing code is only necessary if you wish to initialize the RAM
// contents via an external file (use $readmemb for binary data)
initial
$readmemh(DATA_FILE, registerFile, INIT_START_ADDR, INIT_END_ADDR);
/* initial
begin
registerFile[0] = 32'd5;
registerFile[1] = 32'd10;
registerFile[2] = 32'd20;
registerFile[3] = 32'd30;
registerFile[4] = 32'd40;
registerFile[5] = 32'd50;
registerFile[6] = 32'd60;
registerFile[7] = 32'd70;
registerFile[8] = 32'd80;
registerFile[9] = 32'd90;
registerFile[10] = 32'd100;
registerFile[11] = 32'd110;
registerFile[12] = 32'd120;
registerFile[13] = 32'd130;
registerFile[14] = 32'd140;
registerFile[15] = 32'd150;
registerFile[16] = 32'd160;
registerFile[17] = 32'd170;
registerFile[18] = 32'd180;
registerFile[19] = 32'd190;
registerFile[20] = 32'd200;
registerFile[21] = 32'd210;
registerFile[22] = 32'd220;
registerFile[23] = 32'd230;
registerFile[24] = 32'd240;
registerFile[25] = 32'd250;
registerFile[26] = 32'd260;
registerFile[27] = 32'd270;
registerFile[28] = 32'd280;
registerFile[29] = 32'd290;
registerFile[30] = 32'd300;
registerFile[31] = 32'd310;
end */
reg[4:0] temprs;
reg[4:0] temprt;
reg[4:0] rd;
reg[15:0] immediate;
reg[25:0] jumpConst;
always@(*)
begin
temprs = instruction[25:21];
temprt = instruction[20:16];
rd = instruction[15:11];
immediate = instruction[15:0];
jumpConst = instruction[25:0];
end
assign rs = temprs;
assign rt= temprt;
reg[31:0] tempextendedImmediate;
always@(posedge clk)
begin
if(ExtOp==1)
begin
tempextendedImmediate[14:0] = immediate[14:0];
if(immediate[15] == 1'b0)
begin
tempextendedImmediate[30:15] = 16'd0;
end
else
begin
tempextendedImmediate[30:15] = 16'b1111111111111111;
end
tempextendedImmediate[31] = immediate[15];
end
end
reg[31:0] temprsData;
reg[31:0] temprtData;
always@(*)
begin
if(RegDst == 0)
begin
writeAddress <= rt;
end
else
begin
writeAddress <= rd;
end
if(RegWrite==1)
begin
registerFile[writeAddress] <= writeData;
end
end
endmodule
6. Instruction Fetch:
`timescale 1ns / 1ps
module instructionFetch(
output [31:0] pcOut,
output [31:0] instruction,
output [5:0] opcode,
output [5:0] funct,
input clk,
input [31:0] branchAddress,
input [31:0] jumpAddress,
input jump,
input pcSrc,
input [31:0] constant,
input zeroflag
);
initial
begin
pc=31'd0;
end
if (pcSrc != 1) begin
pc = pc + 1; // Increment PC if pcSrc is 0
end else if (zeroflag == 1) begin
tempconstant = constant; // Store constant value
tempbranchAddress = tempconstant << 2; // Calculate branch address
pc = tempbranchAddress; // Set PC to branch address
end else begin
if (jump == 1) begin
pc = jumpAddress; // Set PC to jump address if jump signal is 1
end else begin
pc = pc; // Do nothing to PC if jump signal is 0
end
end
end
// Outputs
assign branchAddress = tempbranchAddress;
assign instruction = instrOut;
assign pcOut = pc - 1;
assign opcode = instruction[31:26];
assign funct = instruction[5:0];
endmodule
7. TestBench:
module topleveltb;
// Inputs
reg clk;
reg [31:0] branchAddress;
reg [31:0] jumpAddress;
reg jump;
reg pcSrc;
initial
begin
clk=0;
forever #100 clk=~clk;
end
initial begin
// Initialize Inputs
branchAddress = 0;
jumpAddress = 0;
jump = 0;
pcSrc = 0;
end
endmodule
FPGA Picture:
We are using the first two 7 segment displays for displaying 16 bits
alternatively.
The 16 Least significant bits are displayed using the ‘T10’ switch being
off (i.e. T10 = 1’b0) and the 16 most significant bits are being displayed
on the 7-segment display using the same switch ‘T10’ being on (i.e. T10 =
1’b1).