`include "def.h" module pocop( input clk, rst_n, input [`DATA_W-1:0] idatain, input [`DATA_W-1:0] ddatain, output [`DATA_W-1:0] iaddr, daddr, output [`DATA_W-1:0] ddataout, output we); // Instruction Fetch // reg [`DATA_W-1:0] pc; reg [`DATA_W-1:0] ir; assign iaddr = pc; always @(posedge clk or negedge rst_n) begin if(!rst_n) pc <= 0; else pc <= pc+1; end always @(posedge clk or negedge rst_n) begin if(!rst_n) ir <= 0; else ir <= idatain; end // Instruction Decode & Register Fetch // wire st_op, addi_op, ld_op, alu_op, nop_op; wire ldi_op, ldiu_op, ldhi_op, addiu_op; wire [`SEL_W-1:0] com; wire [`OPCODE_W-1:0] opcode; wire [`OPCODE_W-1:0] func; wire [`REG_W-1:0] rs, rd; wire [`IMM_W-1:0] imm; wire [`DATA_W-1:0] rf_a, rf_b, rf_c, alu_b; reg [`SEL_W-1:0] com_id; reg st_op_id, ld_op_id; wire rwe; reg rwe_id; reg [`REG_W-1:0] rd_id; reg [`DATA_W-1:0] areg, breg; wire [`DATA_W-1:0] fwddata, fwda ; wire [`DATA_W-1:0] alu_y; reg [`REG_W-1:0] rd_ex; reg rwe_ex; assign {opcode, rd, rs, func} = ir; assign imm = ir[`IMM_W-1:0]; assign st_op = (opcode == `OP_REG) & (func == `F_ST); assign ld_op = (opcode == `OP_REG) & (func == `F_LD); assign alu_op = (opcode == `OP_REG) & (func[4:3] == 2'b00); assign nop_op = (opcode == `OP_REG) & (func == `F_NOP); assign ldi_op = (opcode == `OP_LDI); assign ldiu_op = (opcode == `OP_LDIU); assign addi_op = (opcode == `OP_ADDI); assign addiu_op = (opcode == `OP_ADDIU); assign ldhi_op = (opcode == `OP_LDHI); assign fwddata = (ld_op_id) ? ddatain: alu_y; assign alu_b = ((rd_id == rs)& rwe_id) ? fwddata : (addi_op | ldi_op) ? {{8{imm[7]}},imm} : (addiu_op | ldiu_op) ? {8'b0,imm} : (ldhi_op) ? {imm, 8'b0} : rf_b; assign fwda = ((rd_id == rd)& rwe_id) ? fwddata: rf_a; assign com = (addi_op | addiu_op ) ? `ALU_ADD: (ldi_op | ldiu_op | ldhi_op) ? `ALU_THB: func[`SEL_W-1:0]; assign rwe = ld_op | (alu_op& ~nop_op) | ldi_op | ldiu_op | addi_op | addiu_op | ldhi_op ; rfile rfile_1(.clk(clk), .a(rf_a), .aadr(rd), .b(rf_b), .badr(rs), .c(rf_c), .cadr(rd_ex), .we(rwe_ex )); always @(posedge clk or negedge rst_n ) begin if(!rst_n) rwe_id <= `DISABLE; else begin st_op_id <= st_op; ld_op_id <= ld_op; rwe_id <= rwe; com_id <= com; rd_id <= rd; areg <= fwda; breg <= alu_b; end end // Execution reg [`DATA_W-1:0] creg, dreg; reg ld_op_ex ; alu alu_1(.a(areg), .b(breg), .s(com_id), .y(alu_y)); assign ddataout = areg; assign daddr = breg; assign we = st_op_id; always @(posedge clk ) begin creg <= alu_y; dreg <= ddatain; ld_op_ex <= ld_op_id; rd_ex <= rd_id; rwe_ex <= rwe_id; end // Write back assign rf_c = ld_op_ex ? dreg : creg; endmodule