Skip to content

Commit

Permalink
Merge pull request openhwgroup#160 from msfschaffner/master
Browse files Browse the repository at this point in the history
Fix for address offset issue (fix openhwgroup#158)
  • Loading branch information
msfschaffner committed Jan 12, 2019
2 parents 3f536e1 + 975ca7a commit fae3459
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 82 deletions.
9 changes: 8 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ cache:
directories:
$RISCV
$VERILATOR_ROOT
timeout: 1000

# required packages to install
addons:
Expand Down Expand Up @@ -56,16 +57,22 @@ before_install:
- git submodule update --init --recursive

stages:
- checkout
- compile1
- compile2
- test

jobs:
include:
- stage: checkout
name: checkout gcc
script:
- ci/build-riscv-gcc.sh 0
- stage: compile1
name: build gcc
script:
- ci/build-riscv-gcc.sh
- ci/build-riscv-gcc.sh 1
- rm -rf $RISCV/riscv-gnu-toolchain
- stage: compile2
name: build tools
script:
Expand Down
25 changes: 17 additions & 8 deletions ci/build-riscv-gcc.sh
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
#!/bin/bash
# call with first argument = 0 to checkout only

set -e
ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
VERSION="691e4e826251c7ec59f883cab18440c87baf45e7"
cd $ROOT/tmp

mkdir -p $RISCV

cd $RISCV

if [ -z ${NUM_JOBS} ]; then
NUM_JOBS=1
fi


if ! [ -e $RISCV/bin ]; then
[ -d $ROOT/tmp/riscv-gnu-toolchain ] || git clone https://github.com/riscv/riscv-gnu-toolchain.git
if ! [ -e $RISCV/riscv-gnu-toolchain ]; then
git clone https://github.com/riscv/riscv-gnu-toolchain.git
fi

cd riscv-gnu-toolchain
git checkout $VERSION
git submodule update --init --recursive

mkdir -p $RISCV

echo "Compiling RISC-V Toolchain"
./configure --prefix=$RISCV > /dev/null
make -j${NUM_JOBS} > /dev/null
echo "Compilation Finished"
if [[ $1 -ne "0" || -z ${1} ]]; then
echo "Compiling RISC-V Toolchain"
./configure --prefix=$RISCV > /dev/null
make -j${NUM_JOBS} > /dev/null
echo "Compilation Finished"
fi
fi
44 changes: 14 additions & 30 deletions include/riscv_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -255,24 +255,6 @@ package riscv;
localparam OpcodeC2Swsp = 3'b110;
localparam OpcodeC2Sdsp = 3'b111;

// ----------------------
// Performance Counters
// ----------------------
localparam logic [11:0] PERF_L1_ICACHE_MISS = 12'h0; // L1 Instr Cache Miss
localparam logic [11:0] PERF_L1_DCACHE_MISS = 12'h1; // L1 Data Cache Miss
localparam logic [11:0] PERF_ITLB_MISS = 12'h2; // ITLB Miss
localparam logic [11:0] PERF_DTLB_MISS = 12'h3; // DTLB Miss
localparam logic [11:0] PERF_LOAD = 12'h4; // Loads
localparam logic [11:0] PERF_STORE = 12'h5; // Stores
localparam logic [11:0] PERF_EXCEPTION = 12'h6; // Taken exceptions
localparam logic [11:0] PERF_EXCEPTION_RET = 12'h7; // Exception return
localparam logic [11:0] PERF_BRANCH_JUMP = 12'h8; // Software change of PC
localparam logic [11:0] PERF_CALL = 12'h9; // Procedure call
localparam logic [11:0] PERF_RET = 12'hA; // Procedure Return
localparam logic [11:0] PERF_MIS_PREDICT = 12'hB; // Branch mis-predicted
localparam logic [11:0] PERF_SB_FULL = 12'hC; // Scoreboard full
localparam logic [11:0] PERF_IF_EMPTY = 12'hD; // instruction fetch queue empty

// ----------------------
// Virtual Memory
// ----------------------
Expand Down Expand Up @@ -390,18 +372,20 @@ package riscv;
CSR_TIME = 12'hC01,
CSR_INSTRET = 12'hC02,
// Performance counters
CSR_L1_ICACHE_MISS = PERF_L1_ICACHE_MISS + 12'hC03,
CSR_L1_DCACHE_MISS = PERF_L1_DCACHE_MISS + 12'hC03,
CSR_ITLB_MISS = PERF_ITLB_MISS + 12'hC03,
CSR_DTLB_MISS = PERF_DTLB_MISS + 12'hC03,
CSR_LOAD = PERF_LOAD + 12'hC03,
CSR_STORE = PERF_STORE + 12'hC03,
CSR_EXCEPTION = PERF_EXCEPTION + 12'hC03,
CSR_EXCEPTION_RET = PERF_EXCEPTION_RET + 12'hC03,
CSR_BRANCH_JUMP = PERF_BRANCH_JUMP + 12'hC03,
CSR_CALL = PERF_CALL + 12'hC03,
CSR_RET = PERF_RET + 12'hC03,
CSR_MIS_PREDICT = PERF_MIS_PREDICT + 12'hC03
CSR_L1_ICACHE_MISS = 12'hC03, // L1 Instr Cache Miss
CSR_L1_DCACHE_MISS = 12'hC04, // L1 Data Cache Miss
CSR_ITLB_MISS = 12'hC05, // ITLB Miss
CSR_DTLB_MISS = 12'hC06, // DTLB Miss
CSR_LOAD = 12'hC07, // Loads
CSR_STORE = 12'hC08, // Stores
CSR_EXCEPTION = 12'hC09, // Taken exceptions
CSR_EXCEPTION_RET = 12'hC0A, // Exception return
CSR_BRANCH_JUMP = 12'hC0B, // Software change of PC
CSR_CALL = 12'hC0C, // Procedure call
CSR_RET = 12'hC0D, // Procedure Return
CSR_MIS_PREDICT = 12'hC0E, // Branch mis-predicted
CSR_SB_FULL = 12'hC0F, // Scoreboard full
CSR_IF_EMPTY = 12'hC10 // instruction fetch queue empty
} csr_reg_t;

localparam logic [63:0] SSTATUS_UIE = 64'h00000001;
Expand Down
68 changes: 54 additions & 14 deletions openpiton/ariane_verilog_wrap.sv
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ module ariane_verilog_wrap #(
serpent_cache_pkg::l15_req_t l15_req, l15_req_remapped;
serpent_cache_pkg::l15_rtrn_t l15_rtrn;

/////////////////////////////
// Debug module address translation
/////////////////////////////

always_comb begin : p_remap
l15_req_remapped = l15_req;
if (l15_req.l15_address < 64'h1000) begin
Expand All @@ -72,6 +76,11 @@ module ariane_verilog_wrap #(
assign l15_rtrn = l15_rtrn_i;
`endif


/////////////////////////////
// Core wakeup mechanism
/////////////////////////////

// // this is a workaround since interrupts are not fully supported yet.
// // the logic below catches the initial wake up interrupt that enables the cores.
// logic wake_up_d, wake_up_q;
Expand Down Expand Up @@ -112,34 +121,65 @@ module ariane_verilog_wrap #(
// reset gate this
assign rst_n = wake_up_cnt_q[$high(wake_up_cnt_q)] & reset_l;

// reset_synchronizer #(
// .NUM_REGS(2)
// ) i_sync (
// .clk_i ( clk_i ),
// .rst_ni ( rst_n ),
// .tmode_i ( 1'b0 ),
// .rst_no ( spc_grst_l )
// );

/////////////////////////////
// synchronizers
/////////////////////////////

logic [1:0] irq;
logic ipi, time_irq, debug_req;

// reset synchronization
synchronizer i_sync (
.clk ( clk_i ),
.presyncdata ( rst_n ),
.syncdata ( spc_grst_l )
);

// interrupts
for (genvar k=0; k<$size(irq_i); k++) begin
synchronizer i_irq_sync (
.clk ( clk_i ),
.presyncdata ( irq_i[k] ),
.syncdata ( irq[k] )
);
end

synchronizer i_ipi_sync (
.clk ( clk_i ),
.presyncdata ( ipi_i ),
.syncdata ( ipi )
);

synchronizer i_timer_sync (
.clk ( clk_i ),
.presyncdata ( time_irq_i ),
.syncdata ( time_irq )
);

synchronizer i_debug_sync (
.clk ( clk_i ),
.presyncdata ( debug_req_i ),
.syncdata ( debug_req )
);

/////////////////////////////
// ariane instance
/////////////////////////////

ariane #(
.SwapEndianess ( SwapEndianess ),
.CachedAddrEnd ( CachedAddrEnd ),
.CachedAddrBeg ( CachedAddrBeg )
) ariane (
.clk_i ( clk_i ),
.rst_ni ( spc_grst_l ),
.boot_addr_i ,
.hart_id_i ,
.irq_i ,
.ipi_i ,
.time_irq_i ,
.debug_req_i ,
.boot_addr_i ,// constant
.hart_id_i ,// constant
.irq_i ( irq ),
.ipi_i ( ipi ),
.time_irq_i ( time_irq ),
.debug_req_i ( debug_req ),
`ifdef AXI64_CACHE_PORTS
.axi_req_o ( axi_req ),
.axi_resp_i ( axi_resp )
Expand Down
2 changes: 1 addition & 1 deletion src/ariane.sv
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ module ariane #(
// ----------------------------
// Performance Counters <-> *
// ----------------------------
logic [11:0] addr_csr_perf;
logic [4:0] addr_csr_perf;
logic [63:0] data_csr_perf, data_perf_csr;
logic we_csr_perf;

Expand Down
9 changes: 5 additions & 4 deletions src/csr_regfile.sv
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ module csr_regfile #(
output logic icache_en_o, // L1 ICache Enable
output logic dcache_en_o, // L1 DCache Enable
// Performance Counter
output logic [11:0] perf_addr_o, // address to performance counter module
output logic [4:0] perf_addr_o, // read/write address to performance counter module (up to 29 aux counters possible in riscv encoding.h)
output logic [63:0] perf_data_o, // write data to performance counter module
input logic [63:0] perf_data_i, // read data from performance counter module
output logic perf_we_o
Expand Down Expand Up @@ -149,8 +149,7 @@ module csr_regfile #(
// a read access exception can only occur if we attempt to read a CSR which does not exist
read_access_exception = 1'b0;
csr_rdata = 64'b0;
// feed through address of performance counter
perf_addr_o = csr_addr.address;
perf_addr_o = csr_addr.address[4:0];;

if (csr_read) begin
unique case (csr_addr.address)
Expand Down Expand Up @@ -249,7 +248,9 @@ module csr_regfile #(
riscv::CSR_BRANCH_JUMP,
riscv::CSR_CALL,
riscv::CSR_RET,
riscv::CSR_MIS_PREDICT: csr_rdata = perf_data_i;
riscv::CSR_MIS_PREDICT,
riscv::CSR_SB_FULL,
riscv::CSR_IF_EMPTY: csr_rdata = perf_data_i;
default: read_access_exception = 1'b1;
endcase
end
Expand Down
44 changes: 20 additions & 24 deletions src/perf_counters.sv
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module perf_counters #(
input logic rst_ni,
input logic debug_mode_i, // debug mode
// SRAM like interface
input logic [11:0] addr_i, // read/write address
input logic [4:0] addr_i, // read/write address (up to 29 aux counters possible in riscv encoding.h)
input logic we_i, // write enable
input logic [63:0] data_i, // data to write
output logic [63:0] data_o, // data to read
Expand All @@ -45,7 +45,7 @@ module perf_counters #(
input branchpredict_t resolved_branch_i
);

logic [13:0][63:0] perf_counter_d, perf_counter_q;
logic [riscv::CSR_IF_EMPTY[4:0] : riscv::CSR_L1_ICACHE_MISS[4:0]][63:0] perf_counter_d, perf_counter_q;

always_comb begin : perf_counters
perf_counter_d = perf_counter_q;
Expand All @@ -57,66 +57,62 @@ module perf_counters #(
// Update Performance Counters
// ------------------------------
if (l1_icache_miss_i)
perf_counter_d[riscv::PERF_L1_ICACHE_MISS] = perf_counter_q[riscv::PERF_L1_ICACHE_MISS] + 1'b1;
perf_counter_d[riscv::CSR_L1_ICACHE_MISS[4:0]] = perf_counter_q[riscv::CSR_L1_ICACHE_MISS[4:0]] + 1'b1;

if (l1_dcache_miss_i)
perf_counter_d[riscv::PERF_L1_DCACHE_MISS] = perf_counter_q[riscv::PERF_L1_DCACHE_MISS] + 1'b1;
perf_counter_d[riscv::CSR_L1_DCACHE_MISS[4:0]] = perf_counter_q[riscv::CSR_L1_DCACHE_MISS[4:0]] + 1'b1;

if (itlb_miss_i)
perf_counter_d[riscv::PERF_ITLB_MISS] = perf_counter_q[riscv::PERF_ITLB_MISS] + 1'b1;
perf_counter_d[riscv::CSR_ITLB_MISS[4:0]] = perf_counter_q[riscv::CSR_ITLB_MISS[4:0]] + 1'b1;

if (dtlb_miss_i)
perf_counter_d[riscv::PERF_DTLB_MISS] = perf_counter_q[riscv::PERF_DTLB_MISS] + 1'b1;
perf_counter_d[riscv::CSR_DTLB_MISS[4:0]] = perf_counter_q[riscv::CSR_DTLB_MISS[4:0]] + 1'b1;

// instruction related perf counters
for (int unsigned i = 0; i < NR_COMMIT_PORTS-1; i++) begin
if (commit_ack_i[i]) begin
if (commit_instr_i[i].fu == LOAD)
perf_counter_d[riscv::PERF_LOAD] = perf_counter_q[riscv::PERF_LOAD] + 1'b1;
perf_counter_d[riscv::CSR_LOAD[4:0]] = perf_counter_q[riscv::CSR_LOAD[4:0]] + 1'b1;

if (commit_instr_i[i].fu == STORE)
perf_counter_d[riscv::PERF_STORE] = perf_counter_q[riscv::PERF_STORE] + 1'b1;
perf_counter_d[riscv::CSR_STORE[4:0]] = perf_counter_q[riscv::CSR_STORE[4:0]] + 1'b1;

if (commit_instr_i[i].fu == CTRL_FLOW)
perf_counter_d[riscv::PERF_BRANCH_JUMP] = perf_counter_q[riscv::PERF_BRANCH_JUMP] + 1'b1;
perf_counter_d[riscv::CSR_BRANCH_JUMP[4:0]] = perf_counter_q[riscv::CSR_BRANCH_JUMP[4:0]] + 1'b1;

// The standard software calling convention uses register x1 to hold the return address on a call
// the unconditional jump is decoded as ADD op
if (commit_instr_i[i].fu == CTRL_FLOW && commit_instr_i[i].op == '0 && commit_instr_i[i].rd == 'b1)
perf_counter_d[riscv::PERF_CALL] = perf_counter_q[riscv::PERF_CALL] + 1'b1;
perf_counter_d[riscv::CSR_CALL[4:0]] = perf_counter_q[riscv::CSR_CALL[4:0]] + 1'b1;

// Return from call
if (commit_instr_i[i].op == JALR && commit_instr_i[i].rs1 == 'b1)
perf_counter_d[riscv::PERF_RET] = perf_counter_q[riscv::PERF_RET] + 1'b1;
perf_counter_d[riscv::CSR_RET[4:0]] = perf_counter_q[riscv::CSR_RET[4:0]] + 1'b1;
end
end

if (ex_i.valid)
perf_counter_d[riscv::PERF_EXCEPTION] = perf_counter_q[riscv::PERF_EXCEPTION] + 1'b1;
perf_counter_d[riscv::CSR_EXCEPTION[4:0]] = perf_counter_q[riscv::CSR_EXCEPTION[4:0]] + 1'b1;

if (eret_i)
perf_counter_d[riscv::PERF_EXCEPTION_RET] = perf_counter_q[riscv::PERF_EXCEPTION_RET] + 1'b1;
perf_counter_d[riscv::CSR_EXCEPTION_RET[4:0]] = perf_counter_q[riscv::CSR_EXCEPTION_RET[4:0]] + 1'b1;

if (resolved_branch_i.valid && resolved_branch_i.is_mispredict)
perf_counter_d[riscv::PERF_MIS_PREDICT] = perf_counter_q[riscv::PERF_MIS_PREDICT] + 1'b1;
perf_counter_d[riscv::CSR_MIS_PREDICT[4:0]] = perf_counter_q[riscv::CSR_MIS_PREDICT[4:0]] + 1'b1;

if (sb_full_i) begin
perf_counter_d[riscv::PERF_SB_FULL] = perf_counter_q[riscv::PERF_SB_FULL] + 1'b1;
perf_counter_d[riscv::CSR_SB_FULL[4:0]] = perf_counter_q[riscv::CSR_SB_FULL[4:0]] + 1'b1;
end

if (if_empty_i) begin
perf_counter_d[riscv::PERF_IF_EMPTY] = perf_counter_q[riscv::PERF_IF_EMPTY] + 1'b1;
perf_counter_d[riscv::CSR_IF_EMPTY[4:0]] = perf_counter_q[riscv::CSR_IF_EMPTY[4:0]] + 1'b1;
end
end

// Read Port
if (!we_i) begin
data_o = perf_counter_q[addr_i[2:0]];
// write port
end else begin
// on a write also output the current value
data_o = perf_counter_q[addr_i[2:0]];
perf_counter_d[addr_i[2:0]] = data_i;
// write after read
data_o = perf_counter_q[addr_i];
if (we_i) begin
perf_counter_d[addr_i] = data_i;
end
end

Expand Down

0 comments on commit fae3459

Please sign in to comment.