mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-20 12:17:19 -04:00
Fix issue #119
This commit is contained in:
parent
af484fa2b9
commit
be866578b3
7 changed files with 89 additions and 187 deletions
1
Makefile
1
Makefile
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
58
src/lsu.sv
58
src/lsu.sv
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue