This commit is contained in:
Florian Zaruba 2018-10-17 20:58:56 +02:00
parent af484fa2b9
commit be866578b3
No known key found for this signature in database
GPG key ID: E742FFE8EC38A792
7 changed files with 89 additions and 187 deletions

View file

@ -91,6 +91,7 @@ src := $(filter-out src/ariane_regfile.sv, $(wildcard src/*.sv)) \
src/common_cells/src/fifo_v1.sv \
src/common_cells/src/lzc.sv \
src/common_cells/src/rrarbiter.sv \
src/common_cells/src/pipe_reg_simple.sv \
src/common_cells/src/lfsr_8bit.sv \
src/tech_cells_generic/src/cluster_clock_inverter.sv \
src/tech_cells_generic/src/pulp_clock_mux2.sv \

View file

@ -33,6 +33,11 @@ package ariane_pkg;
localparam ENABLE_RENAME = 1'b1;
// amount of pipeline registers inserted for load/store return path
// this can be tuned to trade-off IPC vs. cycle time
localparam NR_LOAD_PIPE_REGS = 1;
localparam NR_STORE_PIPE_REGS = 0;
// Floating-point extensions configuration
localparam bit RVF = 1'b0; // Is F extension enabled
localparam bit RVD = 1'b0; // Is D extension enabled
@ -109,9 +114,9 @@ package ariane_pkg;
// if set to zero a flush will not invalidate the cache-lines, in a single core environment
// where coherence is not necessary this can improve performance. This needs to be switched on
// when more than one core is in a system
localparam logic INVALIDATE_ON_FLUSH = 1'b1;
localparam logic INVALIDATE_ON_FLUSH = 1'b0;
localparam NR_WB_PORTS = 3;
localparam NR_WB_PORTS = 4;
// ---------------
// Fetch Stage

View file

@ -89,12 +89,18 @@ module ariane #(
branchpredict_sbe_t branch_predict_id_ex;
logic resolve_branch_ex_id;
// LSU
logic [TRANS_ID_BITS-1:0] lsu_trans_id_ex_id;
logic lsu_valid_id_ex;
logic [63:0] lsu_result_ex_id;
logic lsu_ready_ex_id;
logic lsu_valid_ex_id;
exception_t lsu_exception_ex_id;
logic [TRANS_ID_BITS-1:0] load_trans_id_ex_id;
logic [63:0] load_result_ex_id;
logic load_valid_ex_id;
exception_t load_exception_ex_id;
logic [63:0] store_result_ex_id;
logic [TRANS_ID_BITS-1:0] store_trans_id_ex_id;
logic store_valid_ex_id;
exception_t store_exception_ex_id;
// MULT
logic mult_valid_id_ex;
// FPU
@ -299,10 +305,10 @@ module ariane #(
.csr_valid_o ( csr_valid_id_ex ),
// Commit
.resolved_branch_i ( resolved_branch ),
.trans_id_i ( {flu_trans_id_ex_id, lsu_trans_id_ex_id, fpu_trans_id_ex_id }),
.wbdata_i ( {flu_result_ex_id, lsu_result_ex_id, fpu_result_ex_id }),
.ex_ex_i ( {flu_exception_ex_id, lsu_exception_ex_id, fpu_exception_ex_id }),
.wb_valid_i ( {flu_valid_ex_id, lsu_valid_ex_id, fpu_valid_ex_id }),
.trans_id_i ( {flu_trans_id_ex_id, load_trans_id_ex_id, store_trans_id_ex_id, fpu_trans_id_ex_id }),
.wbdata_i ( {flu_result_ex_id, load_result_ex_id, store_result_ex_id, fpu_result_ex_id }),
.ex_ex_i ( {flu_exception_ex_id, load_exception_ex_id, store_exception_ex_id, fpu_exception_ex_id }),
.wb_valid_i ( {flu_valid_ex_id, load_valid_ex_id, store_valid_ex_id, fpu_valid_ex_id }),
.waddr_i ( waddr_commit_id ),
.wdata_i ( wdata_commit_id ),
@ -345,12 +351,19 @@ module ariane #(
// LSU
.lsu_ready_o ( lsu_ready_ex_id ),
.lsu_valid_i ( lsu_valid_id_ex ),
.lsu_result_o ( lsu_result_ex_id ),
.lsu_trans_id_o ( lsu_trans_id_ex_id ),
.lsu_valid_o ( lsu_valid_ex_id ),
.load_result_o ( load_result_ex_id ),
.load_trans_id_o ( load_trans_id_ex_id ),
.load_valid_o ( load_valid_ex_id ),
.load_exception_o ( load_exception_ex_id ),
.store_result_o ( store_result_ex_id ),
.store_trans_id_o ( store_trans_id_ex_id ),
.store_valid_o ( store_valid_ex_id ),
.store_exception_o ( store_exception_ex_id ),
.lsu_commit_i ( lsu_commit_commit_ex ), // from commit
.lsu_commit_ready_o ( lsu_commit_ready_ex_commit ), // to commit
.lsu_exception_o ( lsu_exception_ex_id ),
.no_st_pending_o ( no_st_pending_ex_commit ),
// FPU
.fpu_ready_o ( fpu_ready_ex_id ),

@ -1 +1 @@
Subproject commit 3b18d9ce9889fb140cd39c8d7c86b3a6cc68872e
Subproject commit 1bea86b04d0c341c555e2ff83a8e247c7d1a3260

View file

@ -45,14 +45,20 @@ module ex_stage (
// MULT
input logic mult_valid_i, // Output is valid
// LSU
output logic lsu_ready_o, // FU is ready
input logic lsu_valid_i, // Input is valid
output logic lsu_valid_o, // Output is valid
output logic [63:0] lsu_result_o,
output logic [TRANS_ID_BITS-1:0] lsu_trans_id_o,
output logic lsu_ready_o, // FU is ready
input logic lsu_valid_i, // Input is valid
output logic load_valid_o,
output logic [63:0] load_result_o,
output logic [TRANS_ID_BITS-1:0] load_trans_id_o,
output exception_t load_exception_o,
output logic store_valid_o,
output logic [63:0] store_result_o,
output logic [TRANS_ID_BITS-1:0] store_trans_id_o,
output exception_t store_exception_o,
input logic lsu_commit_i,
output logic lsu_commit_ready_o, // commit queue is ready to accept another commit request
output exception_t lsu_exception_o,
output logic lsu_commit_ready_o, // commit queue is ready to accept another commit request
output logic no_st_pending_o,
input logic amo_valid_commit_i,
// FPU
@ -251,11 +257,16 @@ module ex_stage (
.fu_data_i ( lsu_data ),
.lsu_ready_o,
.lsu_valid_i,
.lsu_trans_id_o,
.lsu_result_o,
.lsu_valid_o,
.commit_i (lsu_commit_i ),
.commit_ready_o (lsu_commit_ready_o ),
.load_trans_id_o,
.load_result_o,
.load_valid_o,
.load_exception_o,
.store_trans_id_o,
.store_result_o,
.store_valid_o,
.store_exception_o,
.commit_i ( lsu_commit_i ),
.commit_ready_o ( lsu_commit_ready_o ),
.enable_translation_i,
.en_ld_st_translation_i,
.icache_areq_i,
@ -271,7 +282,6 @@ module ex_stage (
.dtlb_miss_o,
.dcache_req_ports_i,
.dcache_req_ports_o,
.lsu_exception_o,
.amo_valid_commit_i,
.amo_req_o,
.amo_resp_i

View file

@ -26,9 +26,17 @@ module lsu #(
input fu_data_t fu_data_i,
output logic lsu_ready_o, // FU is ready e.g. not busy
input logic lsu_valid_i, // Input is valid
output logic [TRANS_ID_BITS-1:0] lsu_trans_id_o, // ID of scoreboard entry at which to write back
output logic [63:0] lsu_result_o,
output logic lsu_valid_o, // transaction id for which the output is the requested one
output logic [TRANS_ID_BITS-1:0] load_trans_id_o, // ID of scoreboard entry at which to write back
output logic [63:0] load_result_o,
output logic load_valid_o,
output exception_t load_exception_o, // to WB, signal exception status LD exception
output logic [TRANS_ID_BITS-1:0] store_trans_id_o, // ID of scoreboard entry at which to write back
output logic [63:0] store_result_o,
output logic store_valid_o,
output exception_t store_exception_o, // to WB, signal exception status ST exception
input logic commit_i, // commit the pending store
output logic commit_ready_o, // commit queue is ready to accept another commit request
@ -55,9 +63,7 @@ module lsu #(
output dcache_req_i_t [2:0] dcache_req_ports_o,
// AMO interface
output amo_req_t amo_req_o,
input amo_resp_t amo_resp_i,
output exception_t lsu_exception_o // to WB, signal exception status LD/ST exception
input amo_resp_t amo_resp_i
);
// data is misaligned
logic data_misaligned;
@ -196,27 +202,27 @@ module lsu #(
.*
);
// ---------------------
// Result Sequentialize
// ---------------------
lsu_arbiter i_lsu_arbiter (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.flush_i ( flush_i ),
.ld_valid_i ( ld_valid ),
.ld_trans_id_i ( ld_trans_id ),
.ld_result_i ( ld_result ),
.ld_ex_i ( ld_ex ),
// ----------------------------
// Output Pipeline Register
// ----------------------------
pipe_reg_simple #(
.dtype ( logic[$bits(ld_valid) + $bits(ld_trans_id) + $bits(ld_result) + $bits(ld_ex) - 1: 0]),
.Depth ( NR_LOAD_PIPE_REGS )
) i_pipe_reg_load (
.clk_i,
.rst_ni,
.d_i ( {ld_valid, ld_trans_id, ld_result, ld_ex} ),
.d_o ( {load_valid_o, load_trans_id_o, load_result_o, load_exception_o} )
);
.st_valid_i ( st_valid ),
.st_trans_id_i ( st_trans_id ),
.st_result_i ( st_result ),
.st_ex_i ( st_ex ),
.valid_o ( lsu_valid_o ),
.trans_id_o ( lsu_trans_id_o ),
.result_o ( lsu_result_o ),
.ex_o ( lsu_exception_o )
pipe_reg_simple #(
.dtype ( logic[$bits(st_valid) + $bits(st_trans_id) + $bits(st_result) + $bits(st_ex) - 1: 0]),
.Depth ( NR_STORE_PIPE_REGS )
) i_pipe_reg_store (
.clk_i,
.rst_ni,
.d_i ( {st_valid, st_trans_id, st_result, st_ex} ),
.d_o ( {store_valid_o, store_trans_id_o, store_result_o, store_exception_o} )
);
// determine whether this is a load or store

View file

@ -1,133 +0,0 @@
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>, ETH Zurich
// Michael Schaffner <schaffner@iis.ee.ethz.ch>, ETH Zurich
// Date: 15.08.2018
// Description: Arbitrates the LSU result port
import ariane_pkg::*;
module lsu_arbiter (
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
input logic flush_i,
// Load Port
input logic ld_valid_i,
input logic [TRANS_ID_BITS-1:0] ld_trans_id_i,
input logic [63:0] ld_result_i,
input exception_t ld_ex_i,
// Store Port
input logic st_valid_i,
input logic [TRANS_ID_BITS-1:0] st_trans_id_i,
input logic [63:0] st_result_i,
input exception_t st_ex_i,
// Output Port
output logic valid_o,
output logic [TRANS_ID_BITS-1:0] trans_id_o,
output logic [63:0] result_o,
output exception_t ex_o
);
// the two fifos are used to buffer results from ld and st paths, and arbits between these results in
// RR fashion. FIFOs need to be 2 deep in order to unconditionally accept loads and stores since we can
// have a maximum of 2 outstanding loads.
// if there are valid elements in the fifos, the unit posts the result on its output ports and expects it
// to be consumed unconditionally
// Important: this needs to be greater than 2 to unconditionally acept incoming requests
localparam int DEPTH = 4;
typedef struct packed {
logic [TRANS_ID_BITS-1:0] trans_id;
logic [63:0] result;
exception_t ex;
} fifo_t;
fifo_t st_in, st_out, ld_in, ld_out;
logic ld_full, ld_empty, ld_ren;
logic st_full, st_empty, st_ren;
logic idx;
assign st_in.trans_id = st_trans_id_i;
assign st_in.result = st_result_i;
assign st_in.ex = st_ex_i;
assign ld_in.trans_id = ld_trans_id_i;
assign ld_in.result = ld_result_i;
assign ld_in.ex = ld_ex_i;
assign trans_id_o = (idx) ? st_out.trans_id : ld_out.trans_id;
assign result_o = (idx) ? st_out.result : ld_out.result;
assign ex_o = (idx) ? st_out.ex : ld_out.ex;
// round robin with "lookahead" for 2 requesters
rrarbiter #(
.NUM_REQ ( 2 )
) i_rrarbiter (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.flush_i ( flush_i ),
.en_i ( 1'b1 ),
.req_i ( {~st_empty, ~ld_empty} ),
.ack_o ( { st_ren, ld_ren } ),
.vld_o ( valid_o ),
.idx_o ( idx )
);
fifo_v2 #(
.dtype ( fifo_t ),
.DEPTH ( DEPTH )
) i_ld_fifo (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.flush_i ( flush_i ),
.testmode_i ( 1'b0 ),
.full_o ( ld_full ),
.empty_o ( ld_empty ),
.alm_full_o ( ),
.alm_empty_o ( ),
.data_i ( ld_in ),
.push_i ( ld_valid_i ),
.data_o ( ld_out ),
.pop_i ( ld_ren )
);
fifo_v2 #(
.dtype ( fifo_t ),
.DEPTH ( DEPTH )
) i_st_fifo (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.flush_i ( flush_i ),
.testmode_i ( 1'b0 ),
.full_o ( st_full ),
.empty_o ( st_empty ),
.alm_full_o ( ),
.alm_empty_o ( ),
.data_i ( st_in ),
.push_i ( st_valid_i ),
.data_o ( st_out ),
.pop_i ( st_ren )
);
//pragma translate_off
`ifndef VERILATOR
// check fifo control signals
assert property (@(posedge clk_i) disable iff (~rst_ni) ld_full |-> !ld_valid_i) else $fatal ("cannot write full ld_fifo");
assert property (@(posedge clk_i) disable iff (~rst_ni) st_full |-> !st_valid_i) else $fatal ("cannot write full st_fifo");
assert property (@(posedge clk_i) disable iff (~rst_ni) ld_empty |-> !ld_ren) else $fatal ("cannot read empty ld_fifo");
assert property (@(posedge clk_i) disable iff (~rst_ni) st_empty |-> !st_ren) else $fatal ("cannot read empty st_fifo");
`endif
//pragma translate_on
endmodule