2023-02-28 02:22:34 +00:00
|
|
|
`include "timescale.sv"
|
|
|
|
|
2023-02-26 23:26:11 +00:00
|
|
|
import rv32i_defs::*;
|
|
|
|
|
|
|
|
module single_cycle_datapath (
|
|
|
|
input logic clk,
|
|
|
|
input logic rst,
|
2023-02-27 01:40:05 +00:00
|
|
|
instr_memory_if.datapath instr_mem_if,
|
|
|
|
data_memory_if.datapath data_mem_if
|
2023-02-26 23:26:11 +00:00
|
|
|
);
|
|
|
|
logic [InstructionSize-1:0] pc, pc_next;
|
|
|
|
logic [OperandSize-1:0] imm_ext;
|
|
|
|
logic [InstructionSize-1:0] pc_target;
|
|
|
|
assign pc_target = imm_ext + pc;
|
|
|
|
|
|
|
|
logic pc_src;
|
|
|
|
always_comb begin
|
|
|
|
case (pc_src)
|
|
|
|
'd0: pc_next = pc + 'd4;
|
|
|
|
'd1: pc_next = pc_target;
|
|
|
|
default: pc_next = 'dx;
|
|
|
|
endcase
|
|
|
|
end
|
|
|
|
|
|
|
|
always_ff @(posedge clk) begin
|
|
|
|
if (rst) pc <= 'b0;
|
|
|
|
else pc <= pc_next;
|
|
|
|
end
|
|
|
|
|
2023-02-27 01:40:05 +00:00
|
|
|
assign instr_mem_if.addr = instr_mem_if.AddrSize'(pc);
|
2023-02-26 23:26:11 +00:00
|
|
|
|
|
|
|
logic reg_write;
|
|
|
|
logic [OperandSize-1:0] read_data_1, read_data_2;
|
|
|
|
logic [OperandSize-1:0] result;
|
|
|
|
register_file register_file (
|
|
|
|
.clk(clk),
|
|
|
|
.rst(rst),
|
2023-02-27 01:40:05 +00:00
|
|
|
.addr_1(instr_mem_if.instr[19:15]),
|
|
|
|
.addr_2(instr_mem_if.instr[24:20]),
|
|
|
|
.addr_3(instr_mem_if.instr[11:7]),
|
2023-02-26 23:26:11 +00:00
|
|
|
.write_enable_3(reg_write),
|
|
|
|
.write_data_3(result),
|
|
|
|
.read_data_1(read_data_1),
|
|
|
|
.read_data_2(read_data_2)
|
|
|
|
);
|
|
|
|
|
|
|
|
logic [1:0] result_src;
|
|
|
|
logic [1:0] imm_src;
|
|
|
|
logic [2:0] alu_ctrl;
|
|
|
|
logic alu_src;
|
|
|
|
logic alu_status_zero;
|
|
|
|
logic jump;
|
|
|
|
logic branch;
|
|
|
|
logic branch_alu_neg;
|
|
|
|
control_unit control_unit (
|
2023-02-27 01:40:05 +00:00
|
|
|
.opcode(instr_mem_if.instr[6:0]),
|
|
|
|
.funct_3(instr_mem_if.instr[14:12]),
|
|
|
|
.funct_7(instr_mem_if.instr[31:25]),
|
2023-02-26 23:26:11 +00:00
|
|
|
.result_src(result_src),
|
2023-02-27 01:40:05 +00:00
|
|
|
.mem_write(data_mem_if.write_enable),
|
2023-02-26 23:26:11 +00:00
|
|
|
.alu_ctrl(alu_ctrl),
|
|
|
|
.alu_src(alu_src),
|
|
|
|
.imm_src(imm_src),
|
|
|
|
.reg_write(reg_write),
|
|
|
|
.jump(jump),
|
|
|
|
.branch(branch),
|
|
|
|
.branch_alu_neg(branch_alu_neg)
|
|
|
|
);
|
|
|
|
|
|
|
|
jump_control jump_control (
|
|
|
|
.jump(jump),
|
|
|
|
.branch(branch),
|
|
|
|
.branch_alu_neg(branch_alu_neg),
|
|
|
|
.zero(alu_status_zero),
|
|
|
|
.pc_src(pc_src)
|
|
|
|
);
|
|
|
|
|
|
|
|
imm_extend imm_extend (
|
|
|
|
.imm_src(imm_src[1:0]),
|
2023-02-27 01:40:05 +00:00
|
|
|
.instr (instr_mem_if.instr[31:7]),
|
2023-02-26 23:26:11 +00:00
|
|
|
.imm_ext(imm_ext[31:0])
|
|
|
|
);
|
|
|
|
|
|
|
|
logic [OperandSize-1:0] src_b;
|
|
|
|
always_comb begin
|
|
|
|
case (alu_src)
|
|
|
|
'd0: src_b = read_data_2;
|
|
|
|
'd1: src_b = imm_ext;
|
|
|
|
default: src_b = 'dx;
|
|
|
|
endcase
|
|
|
|
end
|
|
|
|
|
|
|
|
logic [OperandSize-1:0] alu_result;
|
|
|
|
logic [3:0] alu_status;
|
|
|
|
assign alu_status_zero = alu_status[2];
|
|
|
|
alu alu (
|
|
|
|
.a(read_data_1),
|
|
|
|
.b(src_b),
|
2023-02-27 05:45:14 +00:00
|
|
|
.operation(alu_opcode_t'(alu_ctrl)),
|
2023-02-26 23:26:11 +00:00
|
|
|
.result(alu_result),
|
|
|
|
.status(alu_status)
|
|
|
|
);
|
|
|
|
|
2023-02-27 01:40:05 +00:00
|
|
|
assign data_mem_if.write_data = read_data_2;
|
|
|
|
assign data_mem_if.addr = alu_result;
|
2023-02-26 23:26:11 +00:00
|
|
|
|
|
|
|
always_comb begin
|
|
|
|
case (result_src)
|
|
|
|
'b00: result = alu_result;
|
2023-02-27 01:40:05 +00:00
|
|
|
'b01: result = data_mem_if.read_data;
|
2023-02-26 23:26:11 +00:00
|
|
|
'b10: result = pc + 'd4;
|
|
|
|
'b11: result = 'dx;
|
|
|
|
default: result = 'dx;
|
|
|
|
endcase
|
|
|
|
end
|
|
|
|
endmodule
|