Assignment 3: 1. Given The MIPS Assembly Code
Assignment 3: 1. Given The MIPS Assembly Code
Instruction Meaning
addi $s2, $zero, 55 load immediate value 55 to register $S2
addi $s3, $zero, 22 load immediate value 22 to register $S3
addi $s5, $zero, 33 load immediate value 55 to register $S3
add $s4,$s2,$s3 $s4 = $s2 + $s3
sub $s1,$s2,$s3 $s1 = $s2 – $s3
sw $s1,100($s2) Memory[$s2+100] = $s1
lw $s1,100($s2) $s1 = Memory[$s2+100]
bne $s1,$s5,End Next instr. is at End if $s4 !=$s5
addi $s6, $zero, 10 load immediate value 10 to register $s6
beq $s4,$s5, End Next instr. is at End if $s4 = $s5
addi $s6, $zero, 20 load immediate value 20 to register $s6
End: j End jump Here
a) Compile the Assembly Assembly Code sample 1 into machine code (decimal
code and binary code)
b) Explain briefly the meaning of Assembly Code sample 1
c) Compile the Assembly Assembly Code sample 2 into machine code (decimal
code and binary code)
d) Explain briefly the meaning of Assembly Code sample 2
Solve:
a)
addi $s0,$zero,33
Machine code:
Op Rs Rt Address
Decimal 8 0 16 33
Binary 001000 00000 10000 0000 0000 0010 0001
=> 0x20100021
sw $s3, 10($s2)
Machine code:
Op Rs Rt Address
Decimal 43 18 19 10
Binary 101011 10010 10011 0000 0000 0000 1010
=> 0xAE53000A
lw $s1, 10($s2)
Machine code:
Op Rs Rt Address
Decimal 35 18 17 10
Binary 100011 10010 10001 0000 0000 0000 1010
=> 0x8E51000A
c)
add $s4,$s2,$s3
Machine code:
Op Rs Rt Rd Shamt Funct
Decimal 0 18 19 20 0 32
Binary 000000 10010 10011 10100 00000 100000
=> 0x0253A020
sub $s1,$s2,$s3
Machine code:
Op Rs Rt Rd Shamt Funct
Decimal 0 18 19 17 0 34
Binary 000000 10010 10011 10001 00000 100010
=> 0x02538822
sw $s1,100($s2)
Machine code:
Op Rs Rt Address
Decimal 43 18 17 100
Binary 101011 10010 10001 0000 0000 0110 0100
=> 0xAE510064
lw $s1,100($s2)
Machine code:
Op Rs Rt Address
Decimal 35 18 17 100
Binary 100011 10010 10001 0000 0000 0110 0100
=> 0x8E510064
bne $s1,$s5,End
Machine code:
Op Rs Rt Address
Decimal 5 21 17 3
Binary 000101 10101 10001 0000 0000 0000 0011
=> 0x16B10003
a) Compile this Code into Machine Binary code and store in the Instruction of
instruction memory of the Single Microprocessor.
b) Implement the Verilog Simple Single Microprocessor Code for R-Type
Instruction Datapath given in the figure 2.1
c) Develop testbench to verify the system.
Figure 2.1 R-type Processor Datapath
Verilog code:
// PC
module Program_Counter (reset, PC_in, PC_out);
input clk, reset;
input [31:0] PC_in;
output [31:0] PC_out;
reg [31:0] PC_out;
always @ (posedge clk or posedge reset)
begin
if(reset==1'b1)
PC_out<=0;
else
PC_out<=PC_in;
end
endmodule
// Add32
module Adder32Bit(input1, input2, out);
input [31:0] input1, input2;
output [31:0] out;
reg [31:0]out;
always@( input1 or input2)
begin
out <= input1 + input2;
end
endmodule
// In_memory
module Instruction_Memory (read_address, instruction, reset);
input reset;
input [31:0] read_address;
output [31:0] instruction;
reg [31:0] Imemory [63:0];
integer k;
// I-MEM in this case is addressed by word, not by byte
assign instruction = Imemory[read_address];
always @(posedge reset)
begin
for (k=16; k<64; k=k+1)
begin
// here Out changes k=0 to k=16
Imemory[k] = 32'b0;
end
Imemory[0] = 32'b00100000000010000000000000100000;
//addi $t0, $zero, 32
Imemory[1] = 32'b00100000000010010000000000110111;
//addi $t1, $zero, 55
Imemory[2] = 32'b00000001000010011000000000100100;
//and $s0, $t0, $t1
Imemory[3] = 32'b00000001000010011000000000100101;
//or $s0, $t0, $t1
Imemory[4] = 32'b10101100000100000000000000000100;
//sw $s0, 4($zero)
Imemory[5] = 32'b10101100000010000000000000001000;
//sw $t0, 8($zero)
Imemory[6] = 32'b00000001000010011000100000100000;
//add $s1, $t0, $t1
Imemory[7] = 32'b00000001000010011001000000100010;
//sub $s2, $t0, $t1
Imemory[8] = 32'b00010010001100100000000000001001;
//beq $s1, $s2, error0
Imemory[9] = 32'b10001100000100010000000000000100;
//lw $s1, 4($zero)
Imemory[10]= 32'b00110010001100100000000001001000;
//andi $s2, $s1, 48
Imemory[11] =32'b00010010001100100000000000001001;
//beq $s1, $s2, error1
Imemory[12] =32'b10001100000100110000000000001000;
//lw $s3, 8($zero)
Imemory[13] =32'b00010010000100110000000000001010;
//beq $s0, $s3, error2
Imemory[14] =32'b00000010010100011010000000101010;
//slt $s4, $s2, $s1 (Last)
Imemory[15] =32'b00010010100000000000000000001111;
//beq $s4, $0, EXIT
Imemory[16] =32'b00000010001000001001000000100000;
//add $s2, $s1, $0
Imemory[17] =32'b00001000000000000000000000001110;
//j Last
Imemory[18] =32'b00100000000010000000000000000000;
//addi $t0, $0, 0(error0)
Imemory[19] =32'b00100000000010010000000000000000;
//addi $t1, $0, 0
Imemory[20] =32'b00001000000000000000000000011111;
//j EXIT
Imemory[21] =32'b00100000000010000000000000000001;
//addi $t0, $0, 1(error1)
Imemory[22] =32'b00100000000010010000000000000001;
//addi $t1, $0, 1
Imemory[23] =32'b00001000000000000000000000011111;
//j EXIT
Imemory[24] =32'b00100000000010000000000000000010;
//addi $t0, $0, 2(error2)
Imemory[25] =32'b00100000000010010000000000000010;
//addi $t1, $0, 2
Imemory[26] =32'b00001000000000000000000000011111;
//j EXIT
Imemory[27] =32'b00100000000010000000000000000011;
//addi $t0, $0, 3(error3)
Imemory[28] =32'b00100000000010010000000000000011;
//addi $t1, $0, 3
Imemory[29] =32'b00001000000000000000000000011111;
//j EXIT
end
endmodule
// Register file
module Register_File (read_addr_1, read_addr_2, write_addr, read_data_1,
read_data_2, write_data, RegWrite, reset);
input [4:0] read_addr_1, read_addr_2, write_addr;
input [31:0] write_data;
input clk, reset, RegWrite;
output reg [31:0] read_data_1, read_data_2;
always @(posedge clk or posedge reset) // Ou combines the block of reset into
the block of posedge clk
begin
if (reset==1'b1)
begin
for (k=0; k<32; k=k+1)
begin
Regfile[k] = 32'b0;
end
end
else if (RegWrite == 1'b1) Regfile[write_addr] = write_data;
end
endmodule
// ALU
module alu(
input [2:0] alufn,
input [31:0] ra,
input [31:0] rb_or_imm,
output reg [31:0] aluout,
output reg zero);
parameter ALU_OP_ADD = 3'b000,
ALU_OP_SUB = 3'b001,
ALU_OP_AND = 3'b010,
ALU_OP_OR = 3'b011,
ALU_OP_NOT_A = 3'b100,
ALU_OP_LW = 3'b101,
ALU_OP_SW = 3'b110,
ALU_OP_BEQ = 3'b111;
always @(*)
begin
case(alufn)
ALU_OP_ADD : aluout = ra + rb_or_imm;
ALU_OP_SUB : aluout = ra - rb_or_imm;
ALU_OP_AND : aluout = ra & rb_or_imm;
ALU_OP_OR : aluout = ra | rb_or_imm;
ALU_OP_NOT_A: aluout = ~ra;
ALU_OP_LW : aluout = ra + rb_or_imm;
ALU_OP_SW : aluout = ra + rb_or_imm;
ALU_OP_BEQ : begin
zero = (ra==rb_or_imm)? 1'b1 : 1'b0;
aluout = ra - rb_or_imm;
end
endcase
end
endmodule
// Tong hop
module R_Type(reset,RegWrite,Zero,ALU_out);
input reset;
input RegWrite;
output [31:0] ALU_out;
output Zero;
wire [31:0] w1, w2, w3, w4, w5, w6, w7;
reg [4:0] w_rs,w_rt,w_rd;
reg [2:0] w_code;
assign ALU_out = w7;
assign w1 = 32'b00100000000010000000000000100000;
always @(*)
begin
w_rs[4:0] <= w3[25:21];
w_rt[4:0] <= w3[20:16];
w_rd[4:0] <= w3[15:11];
w_code[2:0] <= w3[2:0];
end
Program_Counter c1(reset, w1, w2);
Adder32Bit c2(w2,32'd4, w1);
Instruction_Memory c3(w2, w3, reset);
Register_File c4( w_rs, w_rt, w_rd, w5, w6, w7, RegWrite, reset);
alu c5(w_code,w5,w6,ALU_out,Zero);
endmodule
// TEST BENCH
module TBench;
reg reset;
reg RegWrite;
wire [31:0] ALU_out;
wire Zero;
R_Type dut(reset,RegWrite,Zero,ALU_out);
initial begin
$monitor($time," reset=%b RegWrite=%d Zero=%b | ALU_out=%b
",reset, RegWrite,Zero,ALU_out);
reset=0; RegWrite=1;
#5 reset=1; RegWrite=1;
#5 reset=1; RegWrite=0;
#5 $finish;
end
endmodule