RVSCC/rtl/CPU.sv

100 lines
2.0 KiB
Systemverilog

`timescale 1ns / 1ps
module CPU(
input logic clk, reset
);
logic[31:0] pc, pc_next;
logic[31:0] imm_ext;
logic[31:0] pc_target = imm_ext + 'd4;
always_comb begin
case(pc_src)
'd0: pc_next = pc + 'd4;
'd1: pc_next = pc_target;
endcase
end
always_ff @(posedge clk) begin
if(reset)
pc <= 'b0;
else
pc <= pc_next;
end
logic[31:0] instr;
InstructionMemory #(.N(32)) instruction_memory(pc, instr);
logic reg_write;
logic[31:0] read_data_1, read_data_2;
RegisterFile #(.N_REG_ADDR(5), .N_DATA(32)) register_file(
clk,
instr[19:15],
instr[24:20],
instr[11:7],
reg_write,
result,
read_data_1,
read_data_2
);
logic[1:0] imm_src;
ControlUnit control_unit(
instr[6:0],
instr[14:12],
instr[31:25],
alu_status_zero,
pc_src,
result_src,
mem_write,
alu_ctrl,
alu_src,
imm_src,
reg_write
);
Extend imm_extend(
imm_src[1:0],
instr[31:7],
imm_ext[31:0]
);
logic[31:0] src_a = read_data_1;
logic[31:0] src_b;
always_comb begin
case(alu_src)
'd0: src_b = read_data_2;
'd1: src_b = imm_ext;
endcase
end
logic[31:0] alu_result;
logic[1:0] alu_ctrl;
logic[3:0] alu_status;
logic alu_status_zero = alu_status[1];
ALU alu(
src_a,
src_b,
alu_ctrl,
alu_result,
alu_status
);
logic[31:0] write_data = read_data_2;
logic[31:0] data_mem_read_data;
DataMemory data_memory(
clk,
alu_result,
mem_write,
write_data,
data_mem_read_data
);
logic[31:0] result;
always_comb begin
case(result_src)
'd0: result = alu_result;
'd1: result = data_mem_read_data;
endcase
end
endmodule