diff --git a/include/ariane_pkg.svh b/include/ariane_pkg.svh index 0335d9aa6..8363ab34f 100644 --- a/include/ariane_pkg.svh +++ b/include/ariane_pkg.svh @@ -46,7 +46,7 @@ package ariane_pkg; } misspredict; typedef enum logic[3:0] { - NONE, LSU, ALU, MULT + NONE, LSU, ALU, MULT, CSR } fu_t; localparam EXC_OFF_RST = 8'h80; diff --git a/src/ariane.sv b/src/ariane.sv index aaf4dba33..805b966c8 100644 --- a/src/ariane.sv +++ b/src/ariane.sv @@ -206,12 +206,19 @@ module ariane .operand_b_o ( operand_b_id_ex ), .imm_o ( imm_id_ex ), .trans_id_o ( trans_id_id_ex ), + .alu_ready_i ( alu_ready_ex_id ), .alu_valid_o ( alu_valid_id_ex ), + .lsu_ready_i ( lsu_ready_ex_id ), .lsu_valid_o ( lsu_valid_id_ex ), + .mult_ready_i ( ), .mult_valid_o ( ), + + .csr_ready_i ( ), + .csr_valid_o ( ), + .trans_id_i ( {alu_trans_id_ex_id, lsu_trans_id_ex_id} ), .wdata_i ( {alu_result_ex_id, lsu_result_ex_id} ), .ex_ex_i ( {'b0, lsu_exception_ex_id } ), @@ -269,13 +276,13 @@ module ariane ); commit_stage commit_stage_i ( - .priv_lvl_o ( priv_lvl ), - .exception_o ( ), - .commit_instr_i ( commit_instr_id_commit ), - .commit_ack_o ( commit_ack_commit_id ), - .waddr_a_o ( waddr_a_commit_id ), - .wdata_a_o ( wdata_a_commit_id ), - .we_a_o ( we_a_commit_id ), + .priv_lvl_o ( priv_lvl ), + .exception_o ( ), + .commit_instr_i ( commit_instr_id_commit ), + .commit_ack_o ( commit_ack_commit_id ), + .waddr_a_o ( waddr_a_commit_id ), + .wdata_a_o ( wdata_a_commit_id ), + .we_a_o ( we_a_commit_id ), .* ); diff --git a/src/csr_buffer.sv b/src/csr_buffer.sv new file mode 100644 index 000000000..9dfc89add --- /dev/null +++ b/src/csr_buffer.sv @@ -0,0 +1,81 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 05.05.2017 +// Description: Buffer to hold CSR address, this acts like a functional unit +// to the scoreboard. +// +// +// Copyright (C) 2017 ETH Zurich, University of Bologna +// All rights reserved. +// +// This code is under development and not yet released to the public. +// Until it is released, the code is under the copyright of ETH Zurich and +// the University of Bologna, and may contain confidential and/or unpublished +// work. Any reuse/redistribution is strictly forbidden without written +// permission from ETH Zurich. +// +// Bug fixes and contributions will eventually be released under the +// SolderPad open hardware license in the context of the PULP platform +// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the +// University of Bologna. +// +import ariane_pkg::*; + +module csr_buffer ( + input logic clk_i, // Clock + input logic rst_ni, // Asynchronous reset active low + input logic flush_i, + + input fu_op operator_i, + input logic [63:0] operand_a_i, + input logic [63:0] operand_b_i, + input logic [TRANS_ID_BITS-1:0] trans_id_i, // transaction id, needed for WB + + output logic csr_ready_o, // FU is ready e.g. not busy + input logic csr_valid_i, // Input is valid + output logic [TRANS_ID_BITS-1:0] csr_trans_id_o, // ID of scoreboard entry at which to write back + output logic [63:0] csr_result_o, + output logic csr_valid_o, // transaction id for which the output is the requested one + input logic commit_i, // commit the pending CSR OP + + // to CSR file + input logic [11:0] csr_addr_o // CSR address to commit stage +); + // control logic, scoreboard signals + assign csr_trans_id_o = trans_id_i; + assign csr_valid_o = csr_reg_q.valid | csr_valid_i; + assign csr_result_o = operand_a_i; + assign csr_ready_o = (csr_reg_q.valid && ~commit_i) ? 1'b0 : 1'b1; + assign csr_addr_o = csr_reg_q.csr_address; + + // this is a single entry store buffer for the address of the CSR + // which we are going to need in the commit stage + struct { + logic [11:0] csr_address; + logic valid; + } csr_reg_n, csr_reg_q; + + // write logic + always_comb begin : write + csr_reg_n = csr_reg_q; + + // if we got a valid from the scoreboard + // store the CSR address + if (csr_valid_i) begin + csr_reg_n.csr_address = operand_b_i[11:0]; + csr_reg_n.valid = 1'b1; + end + // if we get a commit and no new valid instruction -> clear the valid bit + if (commit_i && ~csr_valid_i) begin + csr_reg_n.valid = 1'b0; + end + end + // sequential process + always_ff @(posedge clk_i or negedge rst_ni) begin + if(~rst_ni) begin + csr_reg_q <= '{default: 0}; + end else begin + csr_reg_q <= csr_reg_n; + end + end + +endmodule \ No newline at end of file diff --git a/src/id_stage.sv b/src/id_stage.sv index 41e622de2..7e5fa2ce3 100644 --- a/src/id_stage.sv +++ b/src/id_stage.sv @@ -50,6 +50,10 @@ module id_stage #( input logic mult_ready_i, output logic mult_valid_o, + + input logic csr_ready_i, + output logic csr_valid_o, + // write back port input logic [NR_WB_PORTS-1:0][TRANS_ID_BITS-1:0] trans_id_i, input logic [NR_WB_PORTS-1:0][63:0] wdata_i, @@ -100,8 +104,6 @@ module id_stage #( ) scoreboard_i ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), .full_o ( full_o ), .flush_i ( flush_i ), .rd_clobber_o ( rd_clobber_o ), @@ -121,15 +123,11 @@ module id_stage #( .trans_id_i ( trans_id_i ), .wdata_i ( wdata_i ), .ex_i ( ex_ex_i ), - .wb_valid_i ( wb_valid_i ) + .* ); issue_read_operands issue_read_operands_i ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .flush_i ( flush_i ), - .test_en_i ( test_en_i ), .issue_instr_i ( issue_instr_o ), .issue_instr_valid_i ( issue_instr_valid_o), .issue_ack_o ( issue_ack_i ), @@ -140,20 +138,7 @@ module id_stage #( .rs2_i ( rs2_o ), .rs2_valid_i ( rs2_valid_o ), .rd_clobber_i ( rd_clobber_o ), - .operator_o ( operator_o ), - .operand_a_o ( operand_a_o ), - .operand_b_o ( operand_b_o ), - .imm_o ( imm_o ), - .trans_id_o ( trans_id_o ), - .alu_ready_i ( alu_ready_i ), - .alu_valid_o ( alu_valid_o ), - .lsu_ready_i ( lsu_ready_i ), - .lsu_valid_o ( lsu_valid_o ), - .mult_ready_i ( mult_ready_i ), - .mult_valid_o ( mult_valid_o ), - .waddr_a_i ( waddr_a_i ), - .wdata_a_i ( wdata_a_i ), - .we_a_i ( we_a_i ) + .* ); endmodule \ No newline at end of file diff --git a/src/issue_read_operands.sv b/src/issue_read_operands.sv index dbf5e4117..ed329593d 100644 --- a/src/issue_read_operands.sv +++ b/src/issue_read_operands.sv @@ -53,6 +53,9 @@ module issue_read_operands ( // MULT input logic mult_ready_i, // FU is ready output logic mult_valid_o, // Output is valid + // CSR + input logic csr_ready_i, // FU is ready + output logic csr_valid_o, // Output is valid // commit port input logic [4:0] waddr_a_i, input logic [63:0] wdata_a_i, @@ -112,6 +115,7 @@ module issue_read_operands ( end // select the right busy signal + // this obviously depends on the functional unit we need always_comb begin : unit_busy unique case (issue_instr_i.fu) NONE: @@ -122,6 +126,8 @@ module issue_read_operands ( fu_busy = ~mult_ready_i; LSU: fu_busy = ~lsu_ready_i; + CSR: + fu_busy = ~csr_ready_i; default: fu_busy = 1'b0; endcase @@ -199,8 +205,10 @@ module issue_read_operands ( alu_valid_n = 1'b0; lsu_valid_o = 1'b0; mult_valid_o = 1'b0; + csr_valid_o = 1'b0; // Exception pass through // if an exception has occurred simply pass it through + // we do not want to issue this instruction if (~issue_instr_i.ex.valid && issue_instr_valid_i) begin case (issue_instr_i.fu) ALU: @@ -209,6 +217,8 @@ module issue_read_operands ( mult_valid_o = 1'b1; LSU: lsu_valid_o = 1'b1; + CSR: + csr_valid_o = 1'b1; default: begin end