Add CSR buffer which holds the CSR addr for commit

This commit is contained in:
Florian Zaruba 2017-05-05 11:43:13 +02:00
parent 4b75332d10
commit c62a6fc642
5 changed files with 112 additions and 29 deletions

View file

@ -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;

View file

@ -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 ),
.*
);

81
src/csr_buffer.sv Normal file
View file

@ -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

View file

@ -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

View file

@ -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