This commit is contained in:
ClF3 2024-06-29 14:20:54 +08:00
commit 1be7b4b14e
10 changed files with 502 additions and 0 deletions

View File

@ -0,0 +1 @@
create_clock -name clk -period 1000.000 [get_ports clk]

View File

@ -0,0 +1,60 @@
module ALU(
input [32 -1:0] in1 ,
input [32 -1:0] in2 ,
input [5 -1:0] ALUCtl ,
input Sign ,
output reg [32 -1:0] out ,
output zero
);
reg signed [7:0] in11,in12,in13,in14,in21,in22,in23,in24;
reg [31:0] MACout;
// zero means whether the output is zero or not
assign zero = (out == 0);
wire ss;
assign ss = {in1[31], in2[31]};
wire lt_31;
assign lt_31 = (in1[30:0] < in2[30:0]);
// lt_signed means whether (in1 < in2)
wire lt_signed;
assign lt_signed = (in1[31] ^ in2[31])?
((ss == 2'b01)? 0: 1): lt_31;
always @(*)
begin
in11=in1[31:24];
in12=in1[23:16];
in13=in1[15:8];
in14=in1[7:0];
in21=in2[31:24];
in22=in2[23:16];
in23=in2[15:8];
in24=in2[7:0];
MACout=in11*in21+in12*in22+in13*in23+in14*in24;
end
// different ALU operations
always @(*)
case (ALUCtl)
5'b00000: out <= in1 & in2;
5'b00001: out <= in1 | in2;
5'b00010: out <= in1 + in2;
5'b00110: out <= in1 - in2;
5'b00111: out <= {31'h00000000, Sign? lt_signed: (in1 < in2)};
5'b01100: out <= ~(in1 | in2);
5'b01101: out <= in1 ^ in2;
5'b10000: out <= (in2 << in1[4:0]);
5'b11000: out <= (in2 >> in1[4:0]);
5'b11001: out <= ({{32{in2[31]}}, in2} >> in1[4:0]);
5'b11010: out <= in1 * in2; // mul
5'b11011: out <= MACout;
default: out <= 32'h00000000;
endcase
endmodule

View File

@ -0,0 +1,61 @@
module ALUControl(
input [4 -1:0] ALUOp ,
input [6 -1:0] Funct ,
output reg [5 -1:0] ALUCtl ,
output Sign
);
// funct number for different operation
parameter aluAND = 5'b00000;
parameter aluOR = 5'b00001;
parameter aluADD = 5'b00010;
parameter aluSUB = 5'b00110;
parameter aluSLT = 5'b00111;
parameter aluNOR = 5'b01100;
parameter aluXOR = 5'b01101;
parameter aluSLL = 5'b10000;
parameter aluSRL = 5'b11000;
parameter aluSRA = 5'b11001;
parameter aluMUL = 5'b11010; //mul
parameter aluMAC = 5'b11011;
// Sign means whether the ALU treats the input as a signed number or an unsigned number
assign Sign = (ALUOp[2:0] == 3'b010)? ~Funct[0]: ~ALUOp[3];
// set aluFunct
reg [4:0] aluFunct;
always @(*)
case (Funct)
6'b00_0000: aluFunct <= aluSLL;
6'b00_0010: aluFunct <= aluSRL;
6'b00_0011: aluFunct <= aluSRA;
6'b10_0000: aluFunct <= aluADD;
6'b10_0001: aluFunct <= aluADD;
6'b10_0010: aluFunct <= aluSUB;
6'b10_0011: aluFunct <= aluSUB;
6'b10_0100: aluFunct <= aluAND;
6'b10_0101: aluFunct <= aluOR;
6'b10_0110: aluFunct <= aluXOR;
6'b10_0111: aluFunct <= aluNOR;
6'b10_1010: aluFunct <= aluSLT;
6'b10_1011: aluFunct <= aluSLT;
6'b10_1101: aluFunct <= aluMAC;
default: aluFunct <= aluADD;
endcase
// set ALUCtrl
always @(*)
case (ALUOp[2:0])
3'b000: ALUCtl <= aluADD;
3'b001: ALUCtl <= aluSUB;
3'b100: ALUCtl <= aluAND;
3'b101: ALUCtl <= aluSLT;
3'b010: ALUCtl <= aluFunct;
3'b110: ALUCtl <= aluMUL; //mul
default: ALUCtl <= aluADD;
endcase
endmodule

View File

@ -0,0 +1,154 @@
module CPU(
input reset ,
input clk ,
output MemRead ,
output MemWrite ,
output [32 -1:0] MemBus_Address ,
output [32 -1:0] MemBus_Write_Data ,
input [32 -1:0] Device_Read_Data
);
// PC register
reg [31 :0] PC;
wire [31 :0] PC_next;
wire [31 :0] PC_plus_4;
always @(posedge reset or posedge clk)
if (reset)
PC <= 32'h00000000;
else
PC <= PC_next;
assign PC_plus_4 = PC + 32'd4;
// Instruction Memory
wire [31 :0] Instruction;
InstructionMemory instruction_memory1(
.Address (PC ),
.Instruction (Instruction )
);
// Control
wire [2 -1:0] RegDst ;
wire [2 -1:0] PCSrc ;
wire Branch ;
wire MemRead ;
wire MemWrite ;
wire [2 -1:0] MemtoReg ;
wire ALUSrc1 ;
wire ALUSrc2 ;
wire [4 -1:0] ALUOp ;
wire ExtOp ;
wire LuOp ;
wire RegWrite ;
Control control1(
.OpCode (Instruction[31:26] ),
.Funct (Instruction[5 : 0] ),
.PCSrc (PCSrc ),
.Branch (Branch ),
.RegWrite (RegWrite ),
.RegDst (RegDst ),
.MemRead (MemRead ),
.MemWrite (MemWrite ),
.MemtoReg (MemtoReg ),
.ALUSrc1 (ALUSrc1 ),
.ALUSrc2 (ALUSrc2 ),
.ExtOp (ExtOp ),
.LuOp (LuOp ),
.ALUOp (ALUOp )
);
// Register File
wire [32 -1:0] Databus1;
wire [32 -1:0] Databus2;
wire [32 -1:0] Databus3;
wire [5 -1:0] Write_register;
assign Write_register = (RegDst == 2'b00)? Instruction[20:16]: (RegDst == 2'b01)? Instruction[15:11]: 5'b11111;
RegisterFile register_file1(
.reset (reset ),
.clk (clk ),
.RegWrite (RegWrite ),
.Read_register1 (Instruction[25:21] ),
.Read_register2 (Instruction[20:16] ),
.Write_register (Write_register ),
.Write_data (Databus3 ),
.Read_data1 (Databus1 ),
.Read_data2 (Databus2 )
);
// Extend
wire [32 -1:0] Ext_out;
assign Ext_out = { ExtOp? {16{Instruction[15]}}: 16'h0000, Instruction[15:0]};
wire [32 -1:0] LU_out;
assign LU_out = LuOp? {Instruction[15:0], 16'h0000}: Ext_out;
// ALU Control
wire [5 -1:0] ALUCtl;
wire Sign ;
ALUControl alu_control1(
.ALUOp (ALUOp ),
.Funct (Instruction[5:0] ),
.ALUCtl (ALUCtl ),
.Sign (Sign )
);
// ALU
wire [32 -1:0] ALU_in1;
wire [32 -1:0] ALU_in2;
wire [32 -1:0] ALU_out;
wire Zero ;
assign ALU_in1 = ALUSrc1? {27'h00000, Instruction[10:6]}: Databus1;
assign ALU_in2 = ALUSrc2? LU_out: Databus2;
ALU alu1(
.in1 (ALU_in1 ),
.in2 (ALU_in2 ),
.ALUCtl (ALUCtl ),
.Sign (Sign ),
.out (ALU_out ),
.zero (Zero )
);
// Data Memory
wire [32 -1:0] Memory_Read_Data ;
wire Memory_Read ;
wire Memory_Write ;
wire [32 -1:0] MemBus_Read_Data ;
DataMemory data_memory1(
.reset (reset ),
.clk (clk ),
.Address (MemBus_Address ),
.Write_data (MemBus_Write_Data ),
.Read_data (Memory_Read_Data ),
.MemRead (Memory_Read ),
.MemWrite (Memory_Write )
);
assign Memory_Read = MemRead ;
assign Memory_Write = MemWrite;
assign MemBus_Address = ALU_out ;
assign MemBus_Write_Data = Databus2;
assign MemBus_Read_Data = Memory_Read_Data;
// write back
assign Databus3 = (MemtoReg == 2'b00)? ALU_out: (MemtoReg == 2'b01)? MemBus_Read_Data: PC_plus_4;
// PC jump and branch
wire [32 -1:0] Jump_target;
assign Jump_target = {PC_plus_4[31:28], Instruction[25:0], 2'b00};
wire [32 -1:0] Branch_target;
assign Branch_target = (Branch & Zero)? PC_plus_4 + {LU_out[29:0], 2'b00}: PC_plus_4;
assign PC_next = (PCSrc == 2'b00)? Branch_target: (PCSrc == 2'b01)? Jump_target: Databus1;
endmodule

View File

@ -0,0 +1,68 @@
module Control(
input [6 -1:0] OpCode ,
input [6 -1:0] Funct ,
output [2 -1:0] PCSrc ,
output Branch ,
output RegWrite ,
output [2 -1:0] RegDst ,
output MemRead ,
output MemWrite ,
output [2 -1:0] MemtoReg ,
output ALUSrc1 ,
output ALUSrc2 ,
output ExtOp ,
output LuOp ,
output [4 -1:0] ALUOp
);
// Your code below (for question 1)
assign PCSrc =
(OpCode == 6'h00 && Funct == 6'h08)? 2'b10:
(OpCode == 6'h02 || OpCode == 6'h03)? 2'b01:
2'b00;
assign Branch = (OpCode == 6'h04)? 1'b1: 1'b0;
assign RegWrite =
(OpCode == 6'h2b || OpCode == 6'h04 || OpCode == 6'h02)? 1'b0:
(OpCode == 6'h00 && Funct == 6'h08)? 1'b0:
1'b1;
assign RegDst =
(OpCode[5:3] == 3'b001)? 2'b00:
(OpCode == 6'h23)? 2'b00:
(OpCode == 6'h03)? 2'b10:
2'b01;
assign MemRead = (OpCode == 6'h23)? 1'b1: 1'b0;
assign MemWrite = (OpCode == 6'h2b)? 1'b1: 1'b0;
assign MemtoReg =
(OpCode == 6'h23)? 2'b01:
(OpCode == 6'h03)? 2'b10:
2'b00;
assign ALUSrc1 = (OpCode == 6'h00 && Funct[5:2] == 4'b0000)? 1'b1: 1'b0;
assign ALUSrc2 =
(OpCode[5:3] == 3'b001)? 1'b1:
(OpCode == 6'h23 || OpCode == 6'h2b)? 1'b1:
1'b0;
assign ExtOp =
(OpCode == 6'h0c)? 1'b0:
1'b1;
assign LuOp =
(OpCode == 6'h0f)? 1'b1:
1'b0;
// Your code above (for question 1)
// set ALUOp
assign ALUOp[2:0] =
(OpCode == 6'h00)? 3'b010:
(OpCode == 6'h04)? 3'b001:
(OpCode == 6'h0c)? 3'b100:
(OpCode == 6'h0a || OpCode == 6'h0b)? 3'b101:
(OpCode == 6'h1c && Funct == 6'h02)? 3'b110:
3'b000; //mul
assign ALUOp[3] = OpCode[0];
endmodule

View File

@ -0,0 +1,57 @@
module DataMemory(
input reset ,
input clk ,
input MemRead ,
input MemWrite ,
input [32 -1:0] Address ,
input [32 -1:0] Write_data ,
output [32 -1:0] Read_data
);
// RAM size is 256 words, each word is 32 bits, valid address is 8 bits
parameter RAM_SIZE = 256;
parameter RAM_SIZE_BIT = 8;
// RAM_data is an array of 256 32-bit registers
reg [31:0] RAM_data [RAM_SIZE - 1: 0];
// read data from RAM_data as Read_data
assign Read_data = MemRead? RAM_data[Address[RAM_SIZE_BIT + 1:2]]: 32'h00000000;
// write Write_data to RAM_data at clock posedge
integer i;
always @(posedge reset or posedge clk)begin
if (reset) begin
// -------- Paste Data Memory Configuration Below (Data-q1.txt)
// Data Input: X = [[X11, X12, X13, X14, X15, X16, X17, X18], [X21, X22, X23, X24, X25, X26, X27, X28]]
// Data Input: Y = [[Y11, Y12], [Y21, Y22], [Y31, Y32], [Y41, Y42], [Y51, Y52], [Y61, Y62], [Y71, Y72], [Y81, Y82]]
// Data Output: Z = matmul(X,Y) = [[Z11, Z12], [Z21, Z22]]
// Calculation in cpu: Z11 = X11*Y11 + X12*Y21 + X13*Y31 + X14*Y41 + X15*Y51 + X16*Y61 + X17*Y71 + X18*Y81
// Calculation in cpu: Z12 = X11*Y12 + X12*Y22 + X13*Y32 + X14*Y42 + X15*Y52 + X16*Y62 + X17*Y72 + X18*Y82
// Calculation in cpu: Z21 = X21*Y11 + X22*Y21 + X23*Y31 + X24*Y41 + X25*Y51 + X26*Y61 + X27*Y71 + X28*Y81
// Calculation in cpu: Z22 = X21*Y12 + X22*Y22 + X23*Y32 + X24*Y42 + X25*Y52 + X26*Y62 + X27*Y72 + X28*Y82
// paste in DataMemory.v
RAM_data[0] <= 32'hd328fef9; // X11, X12, X13, X14, to be stored in $t0
RAM_data[1] <= 32'h0324063a; // X15, X16, X17, X18, to be stored in $t1
RAM_data[2] <= 32'h12da0c13; // X21, X22, X23, X24, to be stored in $t2
RAM_data[3] <= 32'hde1015d6; // X25, X26, X27, X28, to be stored in $t3
RAM_data[4] <= 32'hdaf20624; // Y11, Y21, Y31, Y41, to be stored in $t4
RAM_data[5] <= 32'hc31f27c9; // Y51, Y61, Y71, Y81, to be stored in $t5
RAM_data[6] <= 32'h3ce4c0c6; // Y12, Y22, Y32, Y42, to be stored in $t6
RAM_data[7] <= 32'h12ea09c2; // Y52, Y62, Y72, Y82, to be stored in $t7
for (i = 8; i < RAM_SIZE; i = i + 1)
RAM_data[i] <= 32'h00000000;
// -------- Paste Data Memory Configuration Above
end
else if (MemWrite) begin
RAM_data[Address[RAM_SIZE_BIT + 1:2]] <= Write_data;
end
end
endmodule

View File

@ -0,0 +1,39 @@
module InstructionMemory(
input [32 -1:0] Address,
output reg [32 -1:0] Instruction
);
always @(*)
case (Address[9:2])
// -------- Paste Binary Instruction Below (Inst-q1-1/Inst-q1-2.txt)
8'd0: Instruction <= 32'h8c080000;
8'd1: Instruction <= 32'h8c090004;
8'd2: Instruction <= 32'h8c0a0008;
8'd3: Instruction <= 32'h8c0b000c;
8'd4: Instruction <= 32'h8c0c0010;
8'd5: Instruction <= 32'h8c0d0014;
8'd6: Instruction <= 32'h8c0e0018;
8'd7: Instruction <= 32'h8c0f001c;
8'd8: Instruction <= 32'h010c802d;
8'd9: Instruction <= 32'h012d202d;
8'd10: Instruction <= 32'h02048020;
8'd11: Instruction <= 32'h010e882d;
8'd12: Instruction <= 32'h012f202d;
8'd13: Instruction <= 32'h02248820;
8'd14: Instruction <= 32'h014c902d;
8'd15: Instruction <= 32'h016d202d;
8'd16: Instruction <= 32'h02449020;
8'd17: Instruction <= 32'h014e982d;
8'd18: Instruction <= 32'h016f202d;
8'd19: Instruction <= 32'h02649820;
8'd20: Instruction <= 32'hac100020;
8'd21: Instruction <= 32'hac110024;
8'd22: Instruction <= 32'hac120028;
8'd23: Instruction <= 32'hac13002c;
8'd24: Instruction <= 32'h08100018;
// -------- Paste Binary Instruction Above
default: Instruction <= 32'h00000000;
endcase
endmodule

View File

@ -0,0 +1,32 @@
module RegisterFile(
input reset ,
input clk ,
input RegWrite ,
input [5 -1:0] Read_register1 ,
input [5 -1:0] Read_register2 ,
input [5 -1:0] Write_register ,
input [32 -1:0] Write_data ,
output [32 -1:0] Read_data1 ,
output [32 -1:0] Read_data2
);
// RF_data is an array of 32 32-bit registers
// here RF_data[0] is not defined because RF_data[0] identically equal to 0
reg [31:0] RF_data[31:1];
// read data from RF_data as Read_data1 and Read_data2
assign Read_data1 = (Read_register1 == 5'b00000)? 32'h00000000: RF_data[Read_register1];
assign Read_data2 = (Read_register2 == 5'b00000)? 32'h00000000: RF_data[Read_register2];
integer i;
// write Wrtie_data to RF_data at clock posedge
always @(posedge reset or posedge clk)
if (reset)
for (i = 1; i < 32; i = i + 1)
RF_data[i] <= 32'h00000000;
else if (RegWrite && (Write_register != 5'b00000))
RF_data[Write_register] <= Write_data;
endmodule

View File

@ -0,0 +1,30 @@
module test_cpu();
reg reset ;
reg clk ;
wire MemRead ;
wire MemWrite ;
wire [31:0] MemBus_Address ;
wire [31:0] MemBus_Write_Data ;
wire [31:0] Device_Read_Data ;
CPU cpu1(
.reset (reset ),
.clk (clk ),
.MemBus_Address (MemBus_Address ),
.Device_Read_Data (Device_Read_Data ),
.MemBus_Write_Data (MemBus_Write_Data ),
.MemRead (MemRead ),
.MemWrite (MemWrite )
);
initial begin
reset = 1;
clk = 1;
#100 reset = 0;
end
always #50 clk = ~clk;
endmodule

Binary file not shown.