From 681756b70c4accd8c4caec6e97d8275a6359e5f9 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Fri, 15 Dec 2023 18:28:43 +0100 Subject: [PATCH] chore: recover singlecycle version --- src/cpu_singlecycle.sv | 195 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 src/cpu_singlecycle.sv diff --git a/src/cpu_singlecycle.sv b/src/cpu_singlecycle.sv new file mode 100644 index 0000000..9c0a430 --- /dev/null +++ b/src/cpu_singlecycle.sv @@ -0,0 +1,195 @@ +import cpu_types::*; + +module cpu( + input clk, + input rst_n, + + // program memory + input [31:0] instruction, + output reg [31:0] pc, + + // ram + output [31:0] memory_address, + input [31:0] memory_out, + output reg [31:0] memory_write, + output [3:0] memory_byte_enable, + output reg memory_we, + + output ebreak +); + parameter WIDTH = 32; + + reg [31:0] pc_next; + wire pc_src; + + reg [31:0] alu_1, alu_2; + wire alu_1_src, alu_2_src; + + wire [2:0] alu_op; + wire alu_add_one, alu_negate, alu_signed; + wire alu_zero; + wire [31:0] alu_out; + + wire [4:0] reg_a_1, reg_a_2, reg_a_w; + wire [31:0] reg_rd1, reg_rd2; + reg [31:0] reg_write; + wire [1:0] reg_write_src; + wire reg_we; + + wire [31:0] immediate; + + wire jump_instruction, jump_negate_zero; + wire jump_taken; + + wire memory_sign_extension; + + memory_mask_t memory_mask; + + function bit[31:0] mem_sext_maybe; + input [31:0] num; + input memory_mask_t mask; + input sext; + begin + case(mask) + MEM_BYTE: return {{(32 - 8){sext & num[7]}}, num[7:0]}; + MEM_HALFWORD: return {{(32 - 16){sext & num[15]}}, num[15:0]}; + MEM_WORD: return num[31:0]; // rv32i, no 64 bit regs, no sign extension needed + default: return 0; + endcase + end + endfunction + + function bit[3:0] mask_to_mask_bytes; + input memory_mask_t mask; + begin + case(mask) + MEM_BYTE: return 4'b0001; + MEM_HALFWORD: return 4'b0011; + MEM_WORD: return 4'b1111; + default: return 0; + endcase + end + endfunction + + assign memory_byte_enable = mask_to_mask_bytes(.mask(memory_mask)) << memory_address[1:0]; + assign memory_write = reg_rd2 << (8*memory_address[1:0]); + assign memory_address = alu_out; + + // alu source 1 + always_comb begin + case (alu_1_src) + REG_FILE_RS1 : alu_1 = reg_rd1; + PC : alu_1 = pc; + endcase + end + + // alu source 2 + always_comb begin + case (alu_2_src) + REG_FILE_RS2 : alu_2 = reg_rd2; + IMMEDIATE : alu_2 = immediate; + endcase + end + + // pc source + assign jump_taken = jump_instruction && (alu_zero ^ jump_negate_zero); + always_comb begin + if (ebreak) + pc_next = pc; + else + case (pc_src) + PC_PLUS : begin + if (jump_taken) + pc_next = pc + immediate; + else + pc_next = pc + 4; + end + PC_ALU : pc_next = alu_out; + endcase + end + + // register file write source + always_comb begin + case (reg_write_src) + RD_ALU : reg_write = alu_out; + RD_PC_PLUS : reg_write = pc + 4; + RD_MEMORY : reg_write = mem_sext_maybe(.num(memory_out >> (8*memory_address[1:0])), .mask(memory_mask), .sext(memory_sign_extension)); + default : ; + endcase + end + + control_unit control_unit_inst( + .instruction(instruction), + + .ebreak(ebreak), + + .immediate(immediate), + + .alu_op(alu_op), + .alu_add_one(alu_add_one), + .alu_negate(alu_negate), + .alu_signed(alu_signed), + + .memory_mask(memory_mask), + .memory_sign_extension(memory_sign_extension), + + .memory_we(memory_we), + + .jump_instruction(jump_instruction), + .jump_negate_zero(jump_negate_zero), + + .pc_src(pc_src), + .alu_src_1(alu_1_src), + .alu_src_2(alu_2_src), + .reg_rd_src(reg_write_src), + + .reg_rs1(reg_a_1), + .reg_rs2(reg_a_2), + .reg_rd(reg_a_w), + .reg_we(reg_we) + ); + + alu #(.WIDTH(WIDTH)) alu_inst( + .a(alu_1), + .b(alu_2), + + .out(alu_out), + + .op(alu_op), + .b_add_one(alu_add_one), + .b_negate(alu_negate), + .sign(alu_signed), + .zero_flag(alu_zero) + ); + + register_file #(.WIDTH(WIDTH), .ADDRESS_LENGTH(5)) register_file_inst( + .clk(clk), + .a1(reg_a_1), + .a2(reg_a_2), + .a3(reg_a_w), + .we3(reg_we), + .wd3(reg_write), + .rd1(reg_rd1), + .rd2(reg_rd2) + ); + + program_counter program_counter_inst( + .clk(clk), + .rst_n(rst_n), + .pc(pc[11:0]), + .pc_next(pc_next[11:0]) + ); + + // program_memory program_memory_inst( + // .addr(pc[11:0]), + // .instruction(instruction) + // ); + + // ram memory_inst( + // .clk(clk), + // .a(memory_address), + // .we(memory_we), + // .wd(memory_write), + // .rd(memory_out) + // ); +endmodule -- 2.48.1