aboutsummaryrefslogtreecommitdiff
path: root/src/cpu.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu.v')
-rw-r--r--src/cpu.v179
1 files changed, 98 insertions, 81 deletions
diff --git a/src/cpu.v b/src/cpu.v
index e420252..bd282d0 100644
--- a/src/cpu.v
+++ b/src/cpu.v
@@ -1,142 +1,159 @@
-module cpu #(
- parameter N = 32,
- parameter XLEN = 32
-)(
+module cpu (
input clk,
input rst
);
-wire pc_we;
+// Control Unit
+
wire mem_addr_src;
-wire mem_we;
+wire pc_we;
wire instr_we;
wire rf_we;
-wire [1:0] imm_src;
-wire [1:0] alu_src0_src;
-wire [1:0] alu_src1_src;
-wire [3:0] alu_op;
wire alu_zero;
+wire [3:0] alu_op;
+wire [1:0] alu_src_a;
+wire [1:0] alu_src_b;
wire [1:0] result_src;
-reg [N-1:0] result;
-
-
// Fetch
-reg [N-1:0] pc, pc_old, instr;
+reg [31:0] pc;
always @ (posedge clk or posedge rst) begin
- if (rst) pc <= 32'h0001_0000;
- else if (pc_we) pc <= result;
+ if (rst) pc <= 32'h0001_0000;
+ else if (pc_we) pc <= result;
end
-always @ (posedge clk) begin
- if (instr_we) begin
- pc_old <= pc;
- instr <= mem_data_read;
- end
-end
+wire [31:0] mem_addr = mem_addr_src ? result : pc;
-// Memory
-wire [N-1:0] mem_addr;
-assign mem_addr = mem_addr_src ? pc : result;
+wire [31:0] mem_read_data;
-wire [N-1:0] mem_data_write;
-wire [N-1:0] mem_data_read;
-reg [N-1:0] data;
-
-memory_unit #(.N(N)) mu (
+memory_unit mu (
.clk(clk),
.rst(rst),
.we(mem_we),
.addr(mem_addr),
- .data_read(mem_data_read),
- .data_write(mem_data_write)
+ .read_data(mem_read_data),
+ .write_data(b_buf)
);
-always @ (posedge clk) begin
- data <= mem_data_read;
+reg [31:0] instruction;
+reg [31:0] pc_buf;
+
+always @ (posedge clk or posedge rst) begin
+ if (rst) begin
+ pc_buf <= 32'b0;
+ instruction <= 32'b0;
+ end else begin
+ if (instr_we) begin
+ pc_buf <= pc;
+ instruction <= mem_read_data;
+ end
+ end
+end
+
+reg [31:0] data;
+
+always @(posedge clk or posedge rst) begin
+ if (rst) data <= 32'b0;
+ else data <= mem_read_data;
end
-// Register file
+// Instruction Decode
+
+wire [6:0] opcode;
+wire [2:0] funct3;
+wire [6:0] funct7;
+wire [31:0] immediate;
+wire [4:0] rs1, rs2, rd;
+
+instruction_decode id (
+ .instruction(instruction),
+ .opcode(opcode),
+ .funct3(funct3),
+ .funct7(funct7),
+ .immediate(immediate),
+ .rs1(rs1),
+ .rs2(rs2),
+ .rd(rd)
+);
+
+// Register File
-reg [N-1:0] rf_data0_old, rf_data1_old;
-wire [N-1:0] rf_data0, rf_data1;
+wire [31:0] rs1_data, rs2_data;
-register_file #(.N(N), .XLEN(XLEN)) rf(
+register_file rf (
.clk(clk),
.rst(rst),
.we(rf_we),
- .addr_read0(instr[19:15]),
- .addr_read1(instr[24:20]),
- .addr_write2(instr[11:7]),
- .data_read0(rf_data0),
- .data_read1(rf_data1),
- .data_write2(result)
+ .rs1(rs1),
+ .rs2(rs2),
+ .rd(rd),
+ .rs1_data(rs1_data),
+ .rs2_data(rs2_data),
+ .rd_data(result)
);
-always @ (posedge clk) begin
- rf_data0_old <= rf_data0;
- rf_data1_old <= rf_data1;
-end
-
-assign mem_data_write = rf_data1_old;
+reg [31:0] a_buf, b_buf;
-reg [N-1:0] imm;
-
-always @ (*) begin
- case (imm_src)
- 2'b00: imm <= {{20{instr[31]}}, instr[31:20]};
- 2'b01: imm <= {{20{instr[31]}}, instr[31:25], instr[11:7]};
- 2'b10: imm <= {{20{instr[31]}}, instr[7], instr[30:25], instr[11:8], 1'b0};
- endcase
+always @ (posedge clk or posedge rst) begin
+ if (rst) begin
+ a_buf <= 32'b0;
+ b_buf <= 32'b0;
+ end else begin
+ a_buf <= rs1;
+ b_buf <= rs2;
+ end
end
-reg [N-1:0] alu_src0, alu_src1;
+// Execute
+
+reg [31:0] a, b;
+wire [31:0] alu_result;
always @ (*) begin
- case(alu_src0_src)
- 2'b00: alu_src0 <= pc;
- 2'b01: alu_src0 <= pc_old;
- 2'b10: alu_src0 <= rf_data0_old;
+ case(alu_src_a)
+ 2'b00: a <= pc;
+ 2'b01: a <= pc_buf;
+ 2'b10: a <= a_buf;
+ default: a <= 32'b0;
endcase
end
always @ (*) begin
- case(alu_src1_src)
- 2'b00: alu_src1 <= rf_data1_old;
- 2'b01: alu_src1 <= imm;
- 2'b10: alu_src1 <= {{(N-3){1'b0}}, 3'h4};
+ case(alu_src_b)
+ 2'b00: b <= b_buf;
+ 2'b01: b <= immediate;
+ 2'b10: b <= 32'h4;
+ default: b <= 32'b0;
endcase
end
-// Execute
-
-wire [N-1:0] alu_result;
-
-alu #(.N(N)) alu (
- .src0(alu_src0),
- .src1(alu_src1),
+alu alu (
+ .a(a),
+ .b(b),
.op(alu_op),
.result(alu_result),
.zero(alu_zero)
);
-reg [N-1:0] alu_out;
+reg [31:0] result_buf;
-always @ (posedge clk) begin
- alu_out <= alu_result;
+always @ (posedge clk or posedge rst) begin
+ if (rst) result_buf <= 32'b0;
+ else result_buf <= alu_result;
end
+reg [31:0] result;
+
always @ (*) begin
- case (result_src)
- 2'b00: result <= alu_out;
+ case(result_src)
+ 2'b00: result <= result_buf;
2'b01: result <= data;
2'b10: result <= alu_result;
+ default: result <= 32'b0;
endcase
end
-
-
endmodule