commit 1be7b4b14ee37ea7d6dc117474396e9e0ffa91f8 Author: ClF3 Date: Sat Jun 29 14:20:54 2024 +0800 1 and 2 diff --git a/constrs_1/imports/mips/xdc_for_both.xdc b/constrs_1/imports/mips/xdc_for_both.xdc new file mode 100644 index 0000000..103c2dd --- /dev/null +++ b/constrs_1/imports/mips/xdc_for_both.xdc @@ -0,0 +1 @@ +create_clock -name clk -period 1000.000 [get_ports clk] \ No newline at end of file diff --git a/sources_1/imports/single-cycle/ALU.v b/sources_1/imports/single-cycle/ALU.v new file mode 100644 index 0000000..fddecbd --- /dev/null +++ b/sources_1/imports/single-cycle/ALU.v @@ -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 \ No newline at end of file diff --git a/sources_1/imports/single-cycle/ALUControl.v b/sources_1/imports/single-cycle/ALUControl.v new file mode 100644 index 0000000..01e8bb2 --- /dev/null +++ b/sources_1/imports/single-cycle/ALUControl.v @@ -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 diff --git a/sources_1/imports/single-cycle/CPU.v b/sources_1/imports/single-cycle/CPU.v new file mode 100644 index 0000000..a21c652 --- /dev/null +++ b/sources_1/imports/single-cycle/CPU.v @@ -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 diff --git a/sources_1/imports/single-cycle/Control.v b/sources_1/imports/single-cycle/Control.v new file mode 100644 index 0000000..b439f8d --- /dev/null +++ b/sources_1/imports/single-cycle/Control.v @@ -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 \ No newline at end of file diff --git a/sources_1/imports/single-cycle/DataMemory.v b/sources_1/imports/single-cycle/DataMemory.v new file mode 100644 index 0000000..f8e28e1 --- /dev/null +++ b/sources_1/imports/single-cycle/DataMemory.v @@ -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 diff --git a/sources_1/imports/single-cycle/InstructionMemory.v b/sources_1/imports/single-cycle/InstructionMemory.v new file mode 100644 index 0000000..5ab3594 --- /dev/null +++ b/sources_1/imports/single-cycle/InstructionMemory.v @@ -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 diff --git a/sources_1/imports/single-cycle/RegisterFile.v b/sources_1/imports/single-cycle/RegisterFile.v new file mode 100644 index 0000000..39ae3f6 --- /dev/null +++ b/sources_1/imports/single-cycle/RegisterFile.v @@ -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 + \ No newline at end of file diff --git a/sources_1/imports/single-cycle/test_cpu.v b/sources_1/imports/single-cycle/test_cpu.v new file mode 100644 index 0000000..d805dfd --- /dev/null +++ b/sources_1/imports/single-cycle/test_cpu.v @@ -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 diff --git a/utils_1/imports/synth_1/test_cpu.dcp b/utils_1/imports/synth_1/test_cpu.dcp new file mode 100644 index 0000000..50aad7b Binary files /dev/null and b/utils_1/imports/synth_1/test_cpu.dcp differ