mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-20 04:07:36 -04:00
Adds cacheable region rules to the configuration script, modify instruction traces such that it can be used with VCS
This commit is contained in:
parent
50b4a5d58b
commit
0b95796858
19 changed files with 272 additions and 426 deletions
2
Makefile
2
Makefile
|
@ -68,8 +68,8 @@ ariane_pkg := $(addprefix $(root-dir), $(ariane_pkg))
|
|||
|
||||
# utility modules
|
||||
util := $(wildcard src/util/*.svh) \
|
||||
src/util/instruction_tracer_pkg.sv \
|
||||
src/util/instruction_tracer_if.sv \
|
||||
src/util/instruction_tracer.sv \
|
||||
src/tech_cells_generic/src/cluster_clock_gating.sv \
|
||||
tb/common/mock_uart.sv \
|
||||
src/util/sram.sv
|
||||
|
|
|
@ -86,7 +86,6 @@ module ariane_xilinx (
|
|||
// 24 MByte in 8 byte words
|
||||
localparam NumWords = (24 * 1024 * 1024) / 8;
|
||||
localparam NBSlave = 2; // debug, ariane
|
||||
localparam logic [63:0] CacheStartAddr = 64'h8000_0000;
|
||||
localparam AxiAddrWidth = 64;
|
||||
localparam AxiDataWidth = 64;
|
||||
localparam AxiIdWidthMaster = 4;
|
||||
|
@ -347,7 +346,7 @@ ariane_axi::req_t axi_ariane_req;
|
|||
ariane_axi::resp_t axi_ariane_resp;
|
||||
|
||||
ariane #(
|
||||
.CachedAddrBeg ( CacheStartAddr )
|
||||
.ArianeCfg ( ArianeSocCfg )
|
||||
) i_ariane (
|
||||
.clk_i ( clk ),
|
||||
.rst_ni ( ndmreset_n ),
|
||||
|
|
|
@ -31,46 +31,101 @@ package ariane_pkg;
|
|||
// This is the new user config interface system. If you need to parameterize something
|
||||
// within Ariane add a field here and assign a default value to the config. Please make
|
||||
// sure to add a propper parameter check to the `check_cfg` function.
|
||||
localparam NrMaxRules = 16;
|
||||
|
||||
typedef struct packed {
|
||||
int NrNonIdempotentRules; // Number of non idempotent rules
|
||||
logic [15:0][63:0] NonIdempotentAddrBase; // base which needs to match
|
||||
logic [15:0][63:0] NonIdempotentLength; // bit mask which bits to consider when matching the rule
|
||||
int NrExecuteRegionRules; // Number of regions which have execute property
|
||||
logic [15:0][63:0] ExecuteRegionAddrBase; // base which needs to match
|
||||
logic [15:0][63:0] ExecuteRegionLength; // bit mask which bits to consider when matching the rule
|
||||
// PMAs
|
||||
int NrNonIdempotentRules; // Number of non idempotent rules
|
||||
logic [NrMaxRules-1:0][63:0] NonIdempotentAddrBase; // base which needs to match
|
||||
logic [NrMaxRules-1:0][63:0] NonIdempotentLength; // bit mask which bits to consider when matching the rule
|
||||
int NrExecuteRegionRules; // Number of regions which have execute property
|
||||
logic [NrMaxRules-1:0][63:0] ExecuteRegionAddrBase; // base which needs to match
|
||||
logic [NrMaxRules-1:0][63:0] ExecuteRegionLength; // bit mask which bits to consider when matching the rule
|
||||
int NrCachedRegionRules; // Number of regions which have cached property
|
||||
logic [NrMaxRules-1:0][63:0] CachedRegionAddrBase; // base which needs to match
|
||||
logic [NrMaxRules-1:0][63:0] CachedRegionLength; // bit mask which bits to consider when matching the rule
|
||||
// cache config
|
||||
bit Axi64BitCompliant; // set to 1 when using in conjunction with 64bit AXI bus adapter
|
||||
bit SwapEndianess; // set to 1 to swap endianess inside L1.5 openpiton adapter
|
||||
//
|
||||
logic [63:0] DmBaseAddress; // offset of the debug module
|
||||
} ariane_cfg_t;
|
||||
|
||||
localparam ariane_cfg_t ArianeDefaultConfig = '{
|
||||
// idempotent region
|
||||
NrNonIdempotentRules: 2,
|
||||
NonIdempotentAddrBase: {64'b0, 64'b0},
|
||||
NonIdempotentLength: {64'b0, 64'b0},
|
||||
NrExecuteRegionRules: 3,
|
||||
// DRAM, Boot ROM, Debug Module
|
||||
ExecuteRegionAddrBase: {64'h8000_0000, 64'h1_0000, 64'h0},
|
||||
ExecuteRegionLength: {64'h40000000, 64'h10000, 64'h1000}
|
||||
ExecuteRegionLength: {64'h40000000, 64'h10000, 64'h1000},
|
||||
// cached region
|
||||
NrCachedRegionRules: 1,
|
||||
CachedRegionAddrBase: {64'h8000_0000},
|
||||
CachedRegionLength: {64'h40000000},
|
||||
// cache config
|
||||
Axi64BitCompliant: 1'b1,
|
||||
SwapEndianess: 1'b0,
|
||||
// debug
|
||||
DmBaseAddress: 64'h0
|
||||
};
|
||||
|
||||
// Function being called to check parameters
|
||||
function automatic void check_cfg (ariane_cfg_t Cfg);
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
assert(Cfg.NrNonIdempotentRules <= 16);
|
||||
assert(Cfg.NrExecuteRegionRules <= 16);
|
||||
assert(Cfg.NrNonIdempotentRules <= NrMaxRules);
|
||||
assert(Cfg.NrExecuteRegionRules <= NrMaxRules);
|
||||
assert(Cfg.NrCachedRegionRules <= NrMaxRules);
|
||||
`endif
|
||||
// pragma translate_on
|
||||
endfunction
|
||||
|
||||
// Generate a mask for a given power of two length
|
||||
function logic [63:0] gen_mask (input logic [63:0] len);
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
// check that the region we want is actually power of two aligned
|
||||
assert (2**$clog2(len) == len) else $error("Length must be a power of two");
|
||||
`endif
|
||||
// pragma translate_on
|
||||
return {64{1'b1}} << $clog2(len);
|
||||
endfunction
|
||||
|
||||
function automatic logic range_check(logic[63:0] base, logic[63:0] len, logic[63:0] address);
|
||||
// if len is a power of two, and base is properly aligned, this chack can be simplified
|
||||
automatic logic[63:0] mask;
|
||||
// mask = gen_mask(len);
|
||||
// if ((64'b1<<$clog2(len) == len) && (mask & base == base)) begin
|
||||
// return (address & mask) == (base & mask);
|
||||
// end else begin
|
||||
return (address >= base) && (address < (base+len));
|
||||
// end
|
||||
endfunction : range_check
|
||||
|
||||
function automatic logic is_inside_nonidempotent_regions (ariane_cfg_t Cfg, logic[63:0] address);
|
||||
logic[NrMaxRules-1:0] pass;
|
||||
pass = '0;
|
||||
for (int unsigned k=0; k<Cfg.NrNonIdempotentRules; k++) begin
|
||||
pass[k] = range_check(Cfg.NonIdempotentAddrBase[k], Cfg.NonIdempotentLength[k], address);
|
||||
end
|
||||
return |pass;
|
||||
endfunction : is_inside_nonidempotent_regions
|
||||
|
||||
function automatic logic is_inside_execute_regions (ariane_cfg_t Cfg, logic[63:0] address);
|
||||
// if we don't specify any region we assume everything is accessible
|
||||
logic[NrMaxRules-1:0] pass;
|
||||
pass = '0;
|
||||
for (int unsigned k=0; k<Cfg.NrExecuteRegionRules; k++) begin
|
||||
pass[k] = range_check(Cfg.ExecuteRegionAddrBase[k], Cfg.ExecuteRegionLength[k], address);
|
||||
end
|
||||
return |pass;
|
||||
endfunction : is_inside_execute_regions
|
||||
|
||||
function automatic logic is_inside_cacheable_regions (ariane_cfg_t Cfg, logic[63:0] address);
|
||||
automatic logic[NrMaxRules-1:0] pass;
|
||||
pass = '0;
|
||||
for (int unsigned k=0; k<Cfg.NrCachedRegionRules; k++) begin
|
||||
pass[k] = range_check(Cfg.CachedRegionAddrBase[k], Cfg.CachedRegionLength[k], address);
|
||||
end
|
||||
return |pass;
|
||||
endfunction : is_inside_cacheable_regions
|
||||
|
||||
// TODO: Slowly move those parameters to the new system.
|
||||
localparam NR_SB_ENTRIES = 8; // number of scoreboard entries
|
||||
localparam TRANS_ID_BITS = $clog2(NR_SB_ENTRIES); // depending on the number of scoreboard entries we need that many bits
|
||||
|
|
|
@ -14,10 +14,23 @@
|
|||
|
||||
|
||||
module ariane_verilog_wrap #(
|
||||
parameter logic [63:0] DmBaseAddress = 64'h0, // debug module base address
|
||||
parameter bit SwapEndianess = 1, // swap endianess in l15 adapter
|
||||
parameter logic [63:0] CachedAddrEnd = 64'h80_0000_0000, // end of cached region
|
||||
parameter logic [63:0] CachedAddrBeg = 64'h00_8000_0000 // begin of cached region
|
||||
// debug module base address
|
||||
parameter logic [63:0] DmBaseAddress = 64'h0,
|
||||
// swap endianess in l15 adapter
|
||||
parameter bit SwapEndianess = 1,
|
||||
// PMA configuration
|
||||
// idempotent region
|
||||
parameter int NrNonIdempotentRules = 0,
|
||||
parameter logic [NrMaxRules*64-1:0] NonIdempotentAddrBase = '0,
|
||||
parameter logic [NrMaxRules*64-1:0] NonIdempotentLength = '0,
|
||||
// executable regions
|
||||
parameter int NrExecuteRegionRules = 0,
|
||||
parameter logic [NrMaxRules*64-1:0] ExecuteRegionAddrBase = '0,
|
||||
parameter logic [NrMaxRules*64-1:0] ExecuteRegionLength = '0,
|
||||
// cacheable regions
|
||||
parameter int NrCachedRegionRules = 0,
|
||||
parameter logic [NrMaxRules*64-1:0] CachedRegionAddrBase = '0,
|
||||
parameter logic [NrMaxRules*64-1:0] CachedRegionLength = '0
|
||||
) (
|
||||
input clk_i,
|
||||
input reset_l, // this is an openpiton-specific name, do not change (hier. paths in TB use this)
|
||||
|
@ -150,11 +163,27 @@ module ariane_verilog_wrap #(
|
|||
// ariane instance
|
||||
/////////////////////////////
|
||||
|
||||
localparam ariane_pkg::ariane_cfg_t ArianeOpenPitonCfg = '{
|
||||
// idempotent region
|
||||
NrNonIdempotentRules: NrNonIdempotentRules,
|
||||
NonIdempotentAddrBase: NonIdempotentAddrBase,
|
||||
NonIdempotentLength: NonIdempotentLength,
|
||||
NrExecuteRegionRules: NrExecuteRegionRules,
|
||||
ExecuteRegionAddrBase: ExecuteRegionAddrBase,
|
||||
ExecuteRegionLength: ExecuteRegionLength,
|
||||
// cached region
|
||||
NrCachedRegionRules: NrCachedRegionRules,
|
||||
CachedRegionAddrBase: CachedRegionAddrBase,
|
||||
CachedRegionLength: CachedRegionLength,
|
||||
// cache config
|
||||
Axi64BitCompliant: 1'b0,
|
||||
SwapEndianess: SwapEndianess,
|
||||
// debug
|
||||
DmBaseAddress: DmBaseAddress
|
||||
};
|
||||
|
||||
ariane #(
|
||||
.DmBaseAddress ( DmBaseAddress ),
|
||||
.SwapEndianess ( SwapEndianess ),
|
||||
.CachedAddrEnd ( CachedAddrEnd ),
|
||||
.CachedAddrBeg ( CachedAddrBeg )
|
||||
.ArianeCfg ( ArianeOpenPitonCfg )
|
||||
) ariane (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( spc_grst_l ),
|
||||
|
|
|
@ -13,20 +13,11 @@
|
|||
// Description: Ariane Top-level module
|
||||
|
||||
import ariane_pkg::*;
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
import instruction_tracer_pkg::*;
|
||||
`endif
|
||||
// pragma translate_on
|
||||
|
||||
|
||||
module ariane #(
|
||||
parameter logic [63:0] DmBaseAddress = 64'h0, // debug module base address
|
||||
parameter int unsigned AxiIdWidth = 4,
|
||||
parameter bit SwapEndianess = 0, // swap endianess in l15 adapter
|
||||
parameter logic [63:0] CachedAddrEnd = 64'h80_0000_0000, // end of cached region
|
||||
parameter logic [63:0] CachedAddrBeg = 64'h00_8000_0000, // begin of cached region
|
||||
parameter ariane_pkg::ariane_cfg_t Cfg = ariane_pkg::ArianeDefaultConfig
|
||||
parameter int unsigned AxiIdWidth = 4,
|
||||
parameter bit SwapEndianess = 0, // swap endianess in l15 adapter
|
||||
parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -231,7 +222,7 @@ module ariane #(
|
|||
// Frontend
|
||||
// --------------
|
||||
frontend #(
|
||||
.DmBaseAddress ( DmBaseAddress )
|
||||
.DmBaseAddress ( ArianeCfg.DmBaseAddress )
|
||||
) i_frontend (
|
||||
.flush_i ( flush_ctrl_if ), // not entirely correct
|
||||
.flush_bp_i ( 1'b0 ),
|
||||
|
@ -341,7 +332,7 @@ module ariane #(
|
|||
// EX
|
||||
// ---------
|
||||
ex_stage #(
|
||||
.Cfg ( Cfg )
|
||||
.ArianeCfg ( ArianeCfg )
|
||||
) ex_stage_i (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
@ -465,7 +456,7 @@ module ariane #(
|
|||
// ---------
|
||||
csr_regfile #(
|
||||
.AsidWidth ( ASID_WIDTH ),
|
||||
.DmBaseAddress ( DmBaseAddress )
|
||||
.DmBaseAddress ( ArianeCfg.DmBaseAddress )
|
||||
) csr_regfile_i (
|
||||
.flush_o ( flush_csr_ctrl ),
|
||||
.halt_csr_o ( halt_csr_ctrl ),
|
||||
|
@ -580,9 +571,7 @@ module ariane #(
|
|||
// this is a cache subsystem that is compatible with OpenPiton
|
||||
wt_cache_subsystem #(
|
||||
.AxiIdWidth ( AxiIdWidth ),
|
||||
.CachedAddrBeg ( CachedAddrBeg ),
|
||||
.CachedAddrEnd ( CachedAddrEnd ),
|
||||
.SwapEndianess ( SwapEndianess )
|
||||
.ArianeCfg ( ArianeCfg )
|
||||
) i_cache_subsystem (
|
||||
// to D$
|
||||
.clk_i ( clk_i ),
|
||||
|
@ -620,7 +609,10 @@ module ariane #(
|
|||
`else
|
||||
|
||||
std_cache_subsystem #(
|
||||
.CACHE_START_ADDR ( CachedAddrBeg )
|
||||
// note: this only works with one cacheable region
|
||||
// not as important since this cache subsystem is about to be
|
||||
// deprecated
|
||||
.CACHE_START_ADDR ( ArianeCfg.CachedRegionAddrBase )
|
||||
) i_cache_subsystem (
|
||||
// to D$
|
||||
.clk_i ( clk_i ),
|
||||
|
@ -658,7 +650,7 @@ module ariane #(
|
|||
// -------------------
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
initial ariane_pkg::check_cfg(Cfg);
|
||||
initial ariane_pkg::check_cfg(ArianeCfg);
|
||||
`endif
|
||||
// pragma translate_on
|
||||
|
||||
|
@ -748,25 +740,11 @@ module ariane #(
|
|||
// assign current privilege level
|
||||
assign tracer_if.priv_lvl = priv_lvl;
|
||||
assign tracer_if.debug_mode = debug_mode;
|
||||
instr_tracer instr_tracer_i (tracer_if, hart_id_i);
|
||||
|
||||
program instr_tracer (
|
||||
instruction_tracer_if tracer_if,
|
||||
input logic [63:0] hart_id_i
|
||||
);
|
||||
|
||||
instruction_tracer it = new (tracer_if, 1'b0);
|
||||
|
||||
initial begin
|
||||
#15ns;
|
||||
it.create_file(hart_id_i);
|
||||
it.trace();
|
||||
end
|
||||
|
||||
final begin
|
||||
it.close();
|
||||
end
|
||||
endprogram
|
||||
instruction_tracer instr_tracer_i (
|
||||
.tracer_if(tracer_if),
|
||||
.hart_id_i
|
||||
);
|
||||
|
||||
// mock tracer for Verilator, to be used with spike-dasm
|
||||
`else
|
||||
|
|
|
@ -22,10 +22,8 @@ import ariane_pkg::*;
|
|||
import wt_cache_pkg::*;
|
||||
|
||||
module wt_cache_subsystem #(
|
||||
parameter int unsigned AxiIdWidth = 10,
|
||||
parameter logic [63:0] CachedAddrBeg = 64'h00_8000_0000, // begin of cached region
|
||||
parameter logic [63:0] CachedAddrEnd = 64'h80_0000_0000, // end of cached region
|
||||
parameter bit SwapEndianess = 0 // swap endianess in l15 adapter
|
||||
parameter int unsigned AxiIdWidth = 10,
|
||||
parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig // contains cacheable regions
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -75,15 +73,9 @@ module wt_cache_subsystem #(
|
|||
wt_cache_pkg::dcache_rtrn_t adapter_dcache;
|
||||
|
||||
wt_icache #(
|
||||
`ifdef PITON_ARIANE
|
||||
.Axi64BitCompliant ( 1'b0 ),
|
||||
`else
|
||||
.Axi64BitCompliant ( 1'b1 ),
|
||||
`endif
|
||||
// use ID 0 for icache reads
|
||||
.RdTxId ( 0 ),
|
||||
.CachedAddrBeg ( CachedAddrBeg ),
|
||||
.CachedAddrEnd ( CachedAddrEnd )
|
||||
.ArianeCfg ( ArianeCfg )
|
||||
) i_wt_icache (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
@ -107,16 +99,10 @@ module wt_cache_subsystem #(
|
|||
// they have equal prio and are RR arbited
|
||||
// Port 2 is write only and goes into the merging write buffer
|
||||
wt_dcache #(
|
||||
`ifdef PITON_ARIANE
|
||||
.Axi64BitCompliant ( 1'b0 ),
|
||||
`else
|
||||
.Axi64BitCompliant ( 1'b1 ),
|
||||
`endif
|
||||
// use ID 1 for dcache reads and amos. note that the writebuffer
|
||||
// uses all IDs up to DCACHE_MAX_TX-1 for write transactions.
|
||||
.RdAmoTxId ( 1 ),
|
||||
.CachedAddrBeg ( CachedAddrBeg ),
|
||||
.CachedAddrEnd ( CachedAddrEnd )
|
||||
.ArianeCfg ( ArianeCfg )
|
||||
) i_wt_dcache (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
@ -144,7 +130,7 @@ module wt_cache_subsystem #(
|
|||
|
||||
`ifdef PITON_ARIANE
|
||||
wt_l15_adapter #(
|
||||
.SwapEndianess ( SwapEndianess )
|
||||
.SwapEndianess ( ArianeCfg.SwapEndianess )
|
||||
) i_adapter (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
|
|
@ -16,12 +16,11 @@ import ariane_pkg::*;
|
|||
import wt_cache_pkg::*;
|
||||
|
||||
module wt_dcache #(
|
||||
parameter bit Axi64BitCompliant = 1'b0, // set this to 1 when using in conjunction with 64bit AXI bus adapter
|
||||
// ID to be used for read and AMO transactions.
|
||||
// note that the write buffer uses all IDs up to DCACHE_MAX_TX-1 for write transactions
|
||||
parameter logic [CACHE_ID_WIDTH-1:0] RdAmoTxId = 1,
|
||||
parameter logic [63:0] CachedAddrBeg = 64'h00_8000_0000, // begin of cached region
|
||||
parameter logic [63:0] CachedAddrEnd = 64'h80_0000_0000 // end of cached region
|
||||
// contains cacheable regions
|
||||
parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig
|
||||
) (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
|
@ -110,9 +109,9 @@ module wt_dcache #(
|
|||
///////////////////////////////////////////////////////
|
||||
|
||||
wt_dcache_missunit #(
|
||||
.Axi64BitCompliant ( Axi64BitCompliant ),
|
||||
.AmoTxId ( RdAmoTxId ),
|
||||
.NumPorts ( NumPorts )
|
||||
.Axi64BitCompliant ( ArianeCfg.Axi64BitCompliant ),
|
||||
.AmoTxId ( RdAmoTxId ),
|
||||
.NumPorts ( NumPorts )
|
||||
) i_wt_dcache_missunit (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
@ -170,8 +169,7 @@ module wt_dcache #(
|
|||
|
||||
wt_dcache_ctrl #(
|
||||
.RdTxId ( RdAmoTxId ),
|
||||
.CachedAddrBeg ( CachedAddrBeg ),
|
||||
.CachedAddrEnd ( CachedAddrEnd )
|
||||
.ArianeCfg ( ArianeCfg )
|
||||
) i_wt_dcache_ctrl (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
@ -213,8 +211,7 @@ module wt_dcache #(
|
|||
assign rd_prio[2] = 1'b0;
|
||||
|
||||
wt_dcache_wbuffer #(
|
||||
.CachedAddrBeg ( CachedAddrBeg ),
|
||||
.CachedAddrEnd ( CachedAddrEnd )
|
||||
.ArianeCfg ( ArianeCfg )
|
||||
) i_wt_dcache_wbuffer (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
@ -268,8 +265,8 @@ module wt_dcache #(
|
|||
///////////////////////////////////////////////////////
|
||||
|
||||
wt_dcache_mem #(
|
||||
.Axi64BitCompliant ( Axi64BitCompliant ),
|
||||
.NumPorts ( NumPorts )
|
||||
.Axi64BitCompliant ( ArianeCfg.Axi64BitCompliant ),
|
||||
.NumPorts ( NumPorts )
|
||||
) i_wt_dcache_mem (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
|
|
@ -16,9 +16,8 @@ import ariane_pkg::*;
|
|||
import wt_cache_pkg::*;
|
||||
|
||||
module wt_dcache_ctrl #(
|
||||
parameter logic [CACHE_ID_WIDTH-1:0] RdTxId = 1, // ID to use for read transactions
|
||||
parameter logic [63:0] CachedAddrBeg = 64'h00_8000_0000, // begin of cached region
|
||||
parameter logic [63:0] CachedAddrEnd = 64'h80_0000_0000 // end of cached region
|
||||
parameter logic [CACHE_ID_WIDTH-1:0] RdTxId = 1, // ID to use for read transactions
|
||||
parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig // contains cacheable regions
|
||||
) (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
|
@ -84,9 +83,9 @@ module wt_dcache_ctrl #(
|
|||
assign miss_paddr_o = {address_tag_q, address_idx_q, address_off_q};
|
||||
assign miss_size_o = (miss_nc_o) ? data_size_q : 3'b111;
|
||||
|
||||
assign miss_nc_o = (address_tag_q < (CachedAddrBeg>>DCACHE_INDEX_WIDTH)) ||
|
||||
(address_tag_q >= (CachedAddrEnd>>DCACHE_INDEX_WIDTH)) ||
|
||||
(!cache_en_i);
|
||||
// noncacheable if request goes to I/O space, or if cache is disabled
|
||||
assign miss_nc_o = (~cache_en_i) | (~ariane_pkg::is_inside_cacheable_regions(ArianeCfg, {address_tag_q, {DCACHE_INDEX_WIDTH{1'b0}}}));
|
||||
|
||||
|
||||
assign miss_we_o = '0;
|
||||
assign miss_wdata_o = '0;
|
||||
|
|
|
@ -52,8 +52,7 @@ import ariane_pkg::*;
|
|||
import wt_cache_pkg::*;
|
||||
|
||||
module wt_dcache_wbuffer #(
|
||||
parameter logic [63:0] CachedAddrBeg = 64'h00_8000_0000, // begin of cached region
|
||||
parameter logic [63:0] CachedAddrEnd = 64'h80_0000_0000 // end of cached region
|
||||
parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig // contains cacheable regions
|
||||
) (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
|
@ -136,9 +135,8 @@ module wt_dcache_wbuffer #(
|
|||
|
||||
assign miss_nc_o = nc_pending_q;
|
||||
|
||||
assign addr_is_nc = (req_port_i.address_tag < (CachedAddrBeg>>DCACHE_INDEX_WIDTH)) ||
|
||||
(req_port_i.address_tag >= (CachedAddrEnd>>DCACHE_INDEX_WIDTH)) ||
|
||||
(!cache_en_i);
|
||||
// noncacheable if request goes to I/O space, or if cache is disabled
|
||||
assign addr_is_nc = (~cache_en_i) | (~ariane_pkg::is_inside_cacheable_regions(ArianeCfg, {req_port_i.address_tag, {DCACHE_INDEX_WIDTH{1'b0}}}));
|
||||
|
||||
assign miss_we_o = 1'b1;
|
||||
assign miss_vld_bits_o = '0;
|
||||
|
|
|
@ -28,10 +28,8 @@ import ariane_pkg::*;
|
|||
import wt_cache_pkg::*;
|
||||
|
||||
module wt_icache #(
|
||||
parameter logic [CACHE_ID_WIDTH-1:0] RdTxId = 0, // ID to be used for read transactions
|
||||
parameter bit Axi64BitCompliant = 1'b0, // set this to 1 when using in conjunction with 64bit AXI bus adapter
|
||||
parameter logic [63:0] CachedAddrBeg = 64'h00_8000_0000, // begin of cached region
|
||||
parameter logic [63:0] CachedAddrEnd = 64'h80_0000_0000 // end of cached region
|
||||
parameter logic [CACHE_ID_WIDTH-1:0] RdTxId = 0, // ID to be used for read transactions
|
||||
parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig // contains cacheable regions
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -103,9 +101,7 @@ module wt_icache #(
|
|||
assign cl_tag_d = (areq_i.fetch_valid) ? areq_i.fetch_paddr[ICACHE_TAG_WIDTH+ICACHE_INDEX_WIDTH-1:ICACHE_INDEX_WIDTH] : cl_tag_q;
|
||||
|
||||
// noncacheable if request goes to I/O space, or if cache is disabled
|
||||
assign paddr_is_nc = (cl_tag_d < (CachedAddrBeg>>ICACHE_INDEX_WIDTH)) ||
|
||||
(cl_tag_d >= (CachedAddrEnd>>ICACHE_INDEX_WIDTH)) ||
|
||||
(!cache_en_q);
|
||||
assign paddr_is_nc = (~cache_en_q) | (~ariane_pkg::is_inside_cacheable_regions(ArianeCfg, {cl_tag_d, {ICACHE_INDEX_WIDTH{1'b0}}}));
|
||||
|
||||
// pass exception through
|
||||
assign dreq_o.ex = areq_i.fetch_exception;
|
||||
|
@ -119,7 +115,7 @@ module wt_icache #(
|
|||
assign cl_index = vaddr_d[ICACHE_INDEX_WIDTH-1:ICACHE_OFFSET_WIDTH];
|
||||
|
||||
|
||||
if (Axi64BitCompliant) begin : gen_axi_offset
|
||||
if (ArianeCfg.Axi64BitCompliant) begin : gen_axi_offset
|
||||
// if we generate a noncacheable access, the word will be at offset 0 or 4 in the cl coming from memory
|
||||
assign cl_offset_d = ( dreq_o.ready & dreq_i.req) ? {dreq_i.vaddr>>2, 2'b0} :
|
||||
( paddr_is_nc & mem_data_req_o ) ? cl_offset_q[2]<<2 : // needed since we transfer 32bit over a 64bit AXI bus in this case
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
import ariane_pkg::*;
|
||||
|
||||
module ex_stage #(
|
||||
parameter ariane_pkg::ariane_cfg_t Cfg = ariane_pkg::ArianeDefaultConfig
|
||||
parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig
|
||||
) (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
|
@ -252,7 +252,7 @@ module ex_stage #(
|
|||
assign lsu_data = lsu_valid_i ? fu_data_i : '0;
|
||||
|
||||
load_store_unit #(
|
||||
.Cfg ( Cfg )
|
||||
.ArianeCfg ( ArianeCfg )
|
||||
) lsu_i (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
|
|
|
@ -16,7 +16,7 @@ import ariane_pkg::*;
|
|||
|
||||
module load_store_unit #(
|
||||
parameter int unsigned ASID_WIDTH = 1,
|
||||
parameter ariane_pkg::ariane_cfg_t Cfg = ariane_pkg::ArianeDefaultConfig
|
||||
parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig
|
||||
)(
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -121,7 +121,7 @@ module load_store_unit #(
|
|||
.INSTR_TLB_ENTRIES ( 16 ),
|
||||
.DATA_TLB_ENTRIES ( 16 ),
|
||||
.ASID_WIDTH ( ASID_WIDTH ),
|
||||
.Cfg ( Cfg )
|
||||
.ArianeCfg ( ArianeCfg )
|
||||
) i_mmu (
|
||||
// misaligned bypass
|
||||
.misaligned_ex_i ( misaligned_exception ),
|
||||
|
|
20
src/mmu.sv
20
src/mmu.sv
|
@ -17,10 +17,10 @@
|
|||
import ariane_pkg::*;
|
||||
|
||||
module mmu #(
|
||||
parameter int unsigned INSTR_TLB_ENTRIES = 4,
|
||||
parameter int unsigned DATA_TLB_ENTRIES = 4,
|
||||
parameter int unsigned ASID_WIDTH = 1,
|
||||
parameter ariane_pkg::ariane_cfg_t Cfg = ariane_pkg::ArianeDefaultConfig
|
||||
parameter int unsigned INSTR_TLB_ENTRIES = 4,
|
||||
parameter int unsigned DATA_TLB_ENTRIES = 4,
|
||||
parameter int unsigned ASID_WIDTH = 1,
|
||||
parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -243,15 +243,9 @@ module mmu #(
|
|||
end
|
||||
end
|
||||
|
||||
always_comb begin : execute_addr_check
|
||||
// if we don't specify any region we assume everything is accessible
|
||||
match_any_execute_region = (Cfg.NrExecuteRegionRules == 0);
|
||||
// check for execute flag on memory
|
||||
for (int i = 0; i < Cfg.NrExecuteRegionRules; i++) begin
|
||||
match_any_execute_region |= (Cfg.ExecuteRegionAddrBase[i] & ariane_pkg::gen_mask(Cfg.ExecuteRegionLength[i]))
|
||||
== (icache_areq_o.fetch_paddr & ariane_pkg::gen_mask(Cfg.ExecuteRegionLength[i]));
|
||||
end
|
||||
end
|
||||
// check for execute flag on memory
|
||||
assign match_any_execute_region = ariane_pkg::is_inside_execute_regions(ArianeCfg, icache_areq_o.fetch_paddr);
|
||||
|
||||
//-----------------------
|
||||
// Data Interface
|
||||
//-----------------------
|
||||
|
|
|
@ -1,212 +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, ETH Zurich
|
||||
// Date: 16.05.2017
|
||||
// Description: Instruction Tracer Main Class
|
||||
|
||||
|
||||
class instruction_tracer;
|
||||
// interface to the core
|
||||
virtual instruction_tracer_if tracer_if;
|
||||
// keep the decoded instructions in a queue
|
||||
logic [31:0] decode_queue [$];
|
||||
// keep the issued instructions in a queue
|
||||
logic [31:0] issue_queue [$];
|
||||
// issue scoreboard entries
|
||||
scoreboard_entry_t issue_sbe_queue [$];
|
||||
scoreboard_entry_t issue_sbe;
|
||||
// store resolved branches, get (mis-)predictions
|
||||
branchpredict_t bp [$];
|
||||
// shadow copy of the register files
|
||||
logic [63:0] gp_reg_file [32];
|
||||
logic [63:0] fp_reg_file [32];
|
||||
// 64 bit clock tick count
|
||||
longint unsigned clk_ticks;
|
||||
int f, commit_log;
|
||||
// address mapping
|
||||
// contains mappings of the form vaddr <-> paddr
|
||||
// should it print the instructions to the console
|
||||
logic display_instructions;
|
||||
logic [63:0] store_mapping[$], load_mapping[$], address_mapping;
|
||||
|
||||
// static uvm_cmdline_processor uvcl = uvm_cmdline_processor::get_inst();
|
||||
|
||||
|
||||
function new(virtual instruction_tracer_if tracer_if, logic display_instructions);
|
||||
|
||||
this.tracer_if = tracer_if;
|
||||
this.display_instructions = display_instructions;
|
||||
|
||||
endfunction : new
|
||||
|
||||
function void create_file(logic [63:0] hart_id);
|
||||
string fn, fn_commit_log;
|
||||
$sformat(fn, "trace_hart_%04.0f.log", hart_id);
|
||||
$sformat(fn_commit_log, "trace_hart_%04.0f_commit.log", hart_id);
|
||||
$display("[TRACER] Output filename is: %s", fn);
|
||||
|
||||
this.f = $fopen(fn,"w");
|
||||
if (ENABLE_SPIKE_COMMIT_LOG) this.commit_log = $fopen(fn_commit_log, "w");
|
||||
endfunction : create_file
|
||||
|
||||
task trace();
|
||||
logic [31:0] decode_instruction, issue_instruction, issue_commit_instruction;
|
||||
scoreboard_entry_t commit_instruction;
|
||||
// initialize register 0
|
||||
gp_reg_file = '{default:0};
|
||||
fp_reg_file = '{default:0};
|
||||
|
||||
forever begin
|
||||
automatic branchpredict_t bp_instruction = '0;
|
||||
// new cycle, we are only interested if reset is de-asserted
|
||||
@(tracer_if.pck iff tracer_if.pck.rstn);
|
||||
// increment clock tick
|
||||
clk_ticks++;
|
||||
|
||||
// -------------------
|
||||
// Instruction Decode
|
||||
// -------------------
|
||||
// we are decoding an instruction
|
||||
if (tracer_if.pck.fetch_valid && tracer_if.pck.fetch_ack) begin
|
||||
decode_instruction = tracer_if.pck.instruction;
|
||||
decode_queue.push_back(decode_instruction);
|
||||
end
|
||||
// -------------------
|
||||
// Instruction Issue
|
||||
// -------------------
|
||||
// we got a new issue ack, so put the element from the decode queue to
|
||||
// the issue queue
|
||||
if (tracer_if.pck.issue_ack && !tracer_if.pck.flush_unissued) begin
|
||||
issue_instruction = decode_queue.pop_front();
|
||||
issue_queue.push_back(issue_instruction);
|
||||
// also save the scoreboard entry to a separate issue queue
|
||||
issue_sbe_queue.push_back(scoreboard_entry_t'(tracer_if.pck.issue_sbe));
|
||||
end
|
||||
|
||||
// --------------------
|
||||
// Address Translation
|
||||
// --------------------
|
||||
if (tracer_if.pck.st_valid) begin
|
||||
store_mapping.push_back(tracer_if.pck.st_paddr);
|
||||
end
|
||||
|
||||
if (tracer_if.pck.ld_valid && !tracer_if.pck.ld_kill) begin
|
||||
load_mapping.push_back(tracer_if.pck.ld_paddr);
|
||||
end
|
||||
// ----------------------
|
||||
// Store predictions
|
||||
// ----------------------
|
||||
if (tracer_if.pck.resolve_branch.valid) begin
|
||||
bp.push_back(tracer_if.pck.resolve_branch);
|
||||
end
|
||||
// --------------
|
||||
// Commit
|
||||
// --------------
|
||||
// we are committing an instruction
|
||||
for (int i = 0; i < 2; i++) begin
|
||||
if (tracer_if.pck.commit_ack[i]) begin
|
||||
commit_instruction = scoreboard_entry_t'(tracer_if.pck.commit_instr[i]);
|
||||
issue_commit_instruction = issue_queue.pop_front();
|
||||
issue_sbe = issue_sbe_queue.pop_front();
|
||||
// check if the instruction retiring is a load or store, get the physical address accordingly
|
||||
if (tracer_if.pck.commit_instr[i].fu == LOAD)
|
||||
address_mapping = load_mapping.pop_front();
|
||||
else if (tracer_if.pck.commit_instr[i].fu == STORE)
|
||||
address_mapping = store_mapping.pop_front();
|
||||
|
||||
if (tracer_if.pck.commit_instr[i].fu == CTRL_FLOW)
|
||||
bp_instruction = bp.pop_front();
|
||||
// the scoreboards issue entry still contains the immediate value as a result
|
||||
// check if the write back is valid, if not we need to source the result from the register file
|
||||
// as the most recent version of this register will be there.
|
||||
if (tracer_if.pck.we_gpr[i] || tracer_if.pck.we_fpr[i]) begin
|
||||
printInstr(issue_sbe, issue_commit_instruction, tracer_if.pck.wdata[i], address_mapping, tracer_if.pck.priv_lvl, tracer_if.pck.debug_mode, bp_instruction);
|
||||
end else if (is_rd_fpr(commit_instruction.op)) begin
|
||||
printInstr(issue_sbe, issue_commit_instruction, fp_reg_file[commit_instruction.rd], address_mapping, tracer_if.pck.priv_lvl, tracer_if.pck.debug_mode, bp_instruction);
|
||||
end else begin
|
||||
printInstr(issue_sbe, issue_commit_instruction, gp_reg_file[commit_instruction.rd], address_mapping, tracer_if.pck.priv_lvl, tracer_if.pck.debug_mode, bp_instruction);
|
||||
end
|
||||
end
|
||||
end
|
||||
// --------------
|
||||
// Exceptions
|
||||
// --------------
|
||||
if (tracer_if.pck.exception.valid && !(tracer_if.pck.debug_mode && tracer_if.pck.exception.cause == riscv::BREAKPOINT)) begin
|
||||
// print exception
|
||||
printException(tracer_if.pck.commit_instr[0].pc, tracer_if.pck.exception.cause, tracer_if.pck.exception.tval);
|
||||
end
|
||||
// ----------------------
|
||||
// Commit Registers
|
||||
// ----------------------
|
||||
// update shadow reg files here
|
||||
for (int i = 0; i < 2; i++) begin
|
||||
if (tracer_if.pck.we_gpr[i] && tracer_if.pck.waddr[i] != 5'b0) begin
|
||||
gp_reg_file[tracer_if.pck.waddr[i]] = tracer_if.pck.wdata[i];
|
||||
end else if (tracer_if.pck.we_fpr[i]) begin
|
||||
fp_reg_file[tracer_if.pck.waddr[i]] = tracer_if.pck.wdata[i];
|
||||
end
|
||||
end
|
||||
// --------------
|
||||
// Flush Signals
|
||||
// --------------
|
||||
// flush un-issued instructions
|
||||
if (tracer_if.pck.flush_unissued) begin
|
||||
this.flushDecode();
|
||||
end
|
||||
// flush whole pipeline
|
||||
if (tracer_if.pck.flush) begin
|
||||
this.flush();
|
||||
end
|
||||
end
|
||||
|
||||
endtask
|
||||
|
||||
// flush all decoded instructions
|
||||
function void flushDecode ();
|
||||
decode_queue = {};
|
||||
endfunction
|
||||
|
||||
// flush everything, we took an exception/interrupt
|
||||
function void flush ();
|
||||
this.flushDecode();
|
||||
// clear all elements in the queue
|
||||
issue_queue = {};
|
||||
issue_sbe_queue = {};
|
||||
// also clear mappings
|
||||
store_mapping = {};
|
||||
load_mapping = {};
|
||||
bp = {};
|
||||
endfunction
|
||||
|
||||
function void printInstr(scoreboard_entry_t sbe, logic [31:0] instr, logic [63:0] result, logic [63:0] paddr, riscv::priv_lvl_t priv_lvl, logic debug_mode, branchpredict_t bp);
|
||||
instruction_trace_item iti = new ($time, clk_ticks, sbe, instr, this.gp_reg_file, this.fp_reg_file, result, paddr, priv_lvl, debug_mode, bp);
|
||||
// print instruction to console
|
||||
string print_instr = iti.printInstr();
|
||||
if (ENABLE_SPIKE_COMMIT_LOG && !debug_mode) begin
|
||||
$fwrite(this.commit_log, riscv::spikeCommitLog(sbe.pc, priv_lvl, instr, sbe.rd, result, is_rd_fpr(sbe.op)));
|
||||
end
|
||||
uvm_report_info( "Tracer", print_instr, UVM_HIGH);
|
||||
$fwrite(this.f, {print_instr, "\n"});
|
||||
endfunction
|
||||
|
||||
function void printException(logic [63:0] pc, logic [63:0] cause, logic [63:0] tval);
|
||||
exception_trace_item eti = new (pc, cause, tval);
|
||||
string print_ex = eti.printException();
|
||||
uvm_report_info( "Tracer", print_ex, UVM_HIGH);
|
||||
$fwrite(this.f, {print_ex, "\n"});
|
||||
endfunction
|
||||
|
||||
function void close();
|
||||
if (f) $fclose(this.f);
|
||||
if (ENABLE_SPIKE_COMMIT_LOG && this.commit_log) $fclose(this.commit_log);
|
||||
endfunction
|
||||
|
||||
endclass : instruction_tracer
|
|
@ -1,27 +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, ETH Zurich
|
||||
// Date: 16.05.2017
|
||||
// Description: Instruction Tracer Package
|
||||
|
||||
package instruction_tracer_pkg;
|
||||
|
||||
import ariane_pkg::*;
|
||||
//pragma translate_off
|
||||
import uvm_pkg::*;
|
||||
`include "uvm_macros.svh"
|
||||
`include "instruction_tracer_defines.svh"
|
||||
`include "instruction_trace_item.svh"
|
||||
`include "exception_trace_item.svh"
|
||||
`include "instruction_tracer.svh"
|
||||
//pragma translate_on
|
||||
|
||||
endpackage
|
|
@ -11,58 +11,78 @@
|
|||
// Author: Florian Zaruba, ETH Zurich
|
||||
// Description: Contains SoC information as constants
|
||||
package ariane_soc;
|
||||
// M-Mode Hart, S-Mode Hart
|
||||
localparam int unsigned NumTargets = 2;
|
||||
// Uart, SPI, Ethernet, reserved
|
||||
localparam int unsigned NumSources = 30;
|
||||
localparam int unsigned MaxPriority = 7;
|
||||
// M-Mode Hart, S-Mode Hart
|
||||
localparam int unsigned NumTargets = 2;
|
||||
// Uart, SPI, Ethernet, reserved
|
||||
localparam int unsigned NumSources = 30;
|
||||
localparam int unsigned MaxPriority = 7;
|
||||
|
||||
localparam NrSlaves = 2; // actually masters, but slaves on the crossbar
|
||||
localparam NrSlaves = 2; // actually masters, but slaves on the crossbar
|
||||
|
||||
// 4 is recommended by AXI standard, so lets stick to it, do not change
|
||||
localparam IdWidth = 4;
|
||||
localparam IdWidthSlave = IdWidth + $clog2(NrSlaves);
|
||||
// 4 is recommended by AXI standard, so lets stick to it, do not change
|
||||
localparam IdWidth = 4;
|
||||
localparam IdWidthSlave = IdWidth + $clog2(NrSlaves);
|
||||
|
||||
typedef enum int unsigned {
|
||||
DRAM = 0,
|
||||
GPIO = 1,
|
||||
Ethernet = 2,
|
||||
SPI = 3,
|
||||
UART = 4,
|
||||
PLIC = 5,
|
||||
CLINT = 6,
|
||||
ROM = 7,
|
||||
Debug = 8
|
||||
} axi_slaves_t;
|
||||
typedef enum int unsigned {
|
||||
DRAM = 0,
|
||||
GPIO = 1,
|
||||
Ethernet = 2,
|
||||
SPI = 3,
|
||||
UART = 4,
|
||||
PLIC = 5,
|
||||
CLINT = 6,
|
||||
ROM = 7,
|
||||
Debug = 8
|
||||
} axi_slaves_t;
|
||||
|
||||
localparam NB_PERIPHERALS = Debug + 1;
|
||||
localparam NB_PERIPHERALS = Debug + 1;
|
||||
|
||||
localparam logic[63:0] DebugLength = 64'h1000;
|
||||
localparam logic[63:0] ROMLength = 64'h10000;
|
||||
localparam logic[63:0] CLINTLength = 64'hC0000;
|
||||
localparam logic[63:0] PLICLength = 64'h3FF_FFFF;
|
||||
localparam logic[63:0] UARTLength = 64'h1000;
|
||||
localparam logic[63:0] SPILength = 64'h800000;
|
||||
localparam logic[63:0] EthernetLength = 64'h10000;
|
||||
localparam logic[63:0] GPIOLength = 64'h1000;
|
||||
localparam logic[63:0] DRAMLength = 64'h40000000; // 1GByte of DDR (split between two chips on Genesys2)
|
||||
localparam logic[63:0] SRAMLength = 64'h1800000; // 24 MByte of SRAM
|
||||
// Instantiate AXI protocol checkers
|
||||
localparam bit GenProtocolChecker = 1'b0;
|
||||
|
||||
typedef enum logic [63:0] {
|
||||
DebugBase = 64'h0000_0000,
|
||||
ROMBase = 64'h0001_0000,
|
||||
CLINTBase = 64'h0200_0000,
|
||||
PLICBase = 64'h0C00_0000,
|
||||
UARTBase = 64'h1000_0000,
|
||||
SPIBase = 64'h2000_0000,
|
||||
EthernetBase = 64'h3000_0000,
|
||||
GPIOBase = 64'h4000_0000,
|
||||
DRAMBase = 64'h8000_0000
|
||||
} soc_bus_start_t;
|
||||
localparam logic[63:0] DebugLength = 64'h1000;
|
||||
localparam logic[63:0] ROMLength = 64'h10000;
|
||||
localparam logic[63:0] CLINTLength = 64'hC0000;
|
||||
localparam logic[63:0] PLICLength = 64'h3FF_FFFF;
|
||||
localparam logic[63:0] UARTLength = 64'h1000;
|
||||
localparam logic[63:0] SPILength = 64'h800000;
|
||||
localparam logic[63:0] EthernetLength = 64'h10000;
|
||||
localparam logic[63:0] GPIOLength = 64'h1000;
|
||||
localparam logic[63:0] DRAMLength = 64'h40000000; // 1GByte of DDR (split between two chips on Genesys2)
|
||||
localparam logic[63:0] SRAMLength = 64'h1800000; // 24 MByte of SRAM
|
||||
// Instantiate AXI protocol checkers
|
||||
localparam bit GenProtocolChecker = 1'b0;
|
||||
|
||||
localparam NrRegion = 1;
|
||||
localparam logic [NrRegion-1:0][NB_PERIPHERALS-1:0] ValidRule = {{NrRegion * NB_PERIPHERALS}{1'b1}};
|
||||
typedef enum logic [63:0] {
|
||||
DebugBase = 64'h0000_0000,
|
||||
ROMBase = 64'h0001_0000,
|
||||
CLINTBase = 64'h0200_0000,
|
||||
PLICBase = 64'h0C00_0000,
|
||||
UARTBase = 64'h1000_0000,
|
||||
SPIBase = 64'h2000_0000,
|
||||
EthernetBase = 64'h3000_0000,
|
||||
GPIOBase = 64'h4000_0000,
|
||||
DRAMBase = 64'h8000_0000
|
||||
} soc_bus_start_t;
|
||||
|
||||
localparam NrRegion = 1;
|
||||
localparam logic [NrRegion-1:0][NB_PERIPHERALS-1:0] ValidRule = {{NrRegion * NB_PERIPHERALS}{1'b1}};
|
||||
|
||||
localparam ariane_pkg::ariane_cfg_t ArianeSocCfg = '{
|
||||
// idempotent region
|
||||
NrNonIdempotentRules: 0,
|
||||
NonIdempotentAddrBase: {64'b0},
|
||||
NonIdempotentLength: {64'b0},
|
||||
NrExecuteRegionRules: 3,
|
||||
ExecuteRegionAddrBase: {DRAMBase, ROMBase, DebugBase},
|
||||
ExecuteRegionLength: {DRAMLength, ROMLength, DebugLength},
|
||||
// cached region
|
||||
NrCachedRegionRules: 1,
|
||||
CachedRegionAddrBase: {DRAMBase},
|
||||
CachedRegionLength: {DRAMLength},
|
||||
// cache config
|
||||
Axi64BitCompliant: 1'b1,
|
||||
SwapEndianess: 1'b0,
|
||||
// debug
|
||||
DmBaseAddress: DebugBase
|
||||
};
|
||||
|
||||
endpackage
|
||||
|
|
|
@ -659,11 +659,8 @@ module ariane_testharness #(
|
|||
ariane_axi::resp_t axi_ariane_resp;
|
||||
|
||||
ariane #(
|
||||
.AxiIdWidth ( ariane_soc::IdWidth ),
|
||||
.SwapEndianess ( 0 ),
|
||||
.CachedAddrBeg ( ariane_soc::DRAMBase ),
|
||||
.CachedAddrEnd ( (ariane_soc::DRAMBase + ariane_soc::DRAMLength) ),
|
||||
.DmBaseAddress ( ariane_soc::DebugBase )
|
||||
.AxiIdWidth ( ariane_soc::IdWidth ),
|
||||
.ArianeCfg ( ariane_soc::ArianeSocCfg )
|
||||
) i_ariane (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( ndmreset_n ),
|
||||
|
|
|
@ -40,6 +40,26 @@ module tb;
|
|||
parameter logic [63:0] CachedAddrBeg = MemBytes>>3;//1/8th of the memory is NC
|
||||
parameter logic [63:0] CachedAddrEnd = 64'hFFFF_FFFF_FFFF_FFFF;
|
||||
|
||||
localparam ariane_cfg_t ArianeDefaultConfig = '{
|
||||
// idempotent region
|
||||
NrNonIdempotentRules: 0,
|
||||
NonIdempotentAddrBase: {64'b0},
|
||||
NonIdempotentLength: {64'b0},
|
||||
// executable region
|
||||
NrExecuteRegionRules: 0,
|
||||
ExecuteRegionAddrBase: {64'h0},
|
||||
ExecuteRegionLength: {64'h0},
|
||||
// cached region
|
||||
NrCachedRegionRules: 1,
|
||||
CachedRegionAddrBase: {CachedAddrBeg},//1/8th of the memory is NC
|
||||
CachedRegionLength: {CachedAddrEnd-CachedAddrBeg+64'b1},
|
||||
// cache config
|
||||
Axi64BitCompliant: 1'b1,
|
||||
SwapEndianess: 1'b0,
|
||||
// debug
|
||||
DmBaseAddress: 64'h0
|
||||
};
|
||||
|
||||
// contention and invalidation rates (in %)
|
||||
parameter MemRandHitRate = 75;
|
||||
parameter MemRandInvRate = 10;
|
||||
|
@ -204,9 +224,7 @@ module tb;
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
wt_dcache #(
|
||||
.CachedAddrBeg ( CachedAddrBeg ),
|
||||
.CachedAddrEnd ( CachedAddrEnd ),
|
||||
.Axi64BitCompliant ( 1'b1 )
|
||||
.ArianeCfg ( ArianeDefaultConfig )
|
||||
) i_dut (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
|
|
@ -39,6 +39,26 @@ module tb;
|
|||
parameter logic [63:0] CachedAddrBeg = MemBytes/4;
|
||||
parameter logic [63:0] CachedAddrEnd = 64'hFFFF_FFFF_FFFF_FFFF;
|
||||
|
||||
localparam ariane_cfg_t Cfg = '{
|
||||
// idempotent region
|
||||
NrNonIdempotentRules: 0,
|
||||
NonIdempotentAddrBase: {64'b0},
|
||||
NonIdempotentLength: {64'b0},
|
||||
// executable region
|
||||
NrExecuteRegionRules: 0,
|
||||
ExecuteRegionAddrBase: {64'h0},
|
||||
ExecuteRegionLength: {64'h0},
|
||||
// cached region
|
||||
NrCachedRegionRules: 1,
|
||||
CachedRegionAddrBase: {CachedAddrBeg},
|
||||
CachedRegionLength: {CachedAddrEnd-CachedAddrBeg+64'b1},
|
||||
// cache config
|
||||
Axi64BitCompliant: 1'b0,
|
||||
SwapEndianess: 1'b0,
|
||||
// debug
|
||||
DmBaseAddress: 64'h0
|
||||
};
|
||||
|
||||
// rates are in percent
|
||||
parameter TlbRandHitRate = 50;
|
||||
parameter MemRandHitRate = 50;
|
||||
|
@ -240,8 +260,7 @@ module tb;
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
wt_icache #(
|
||||
.CachedAddrBeg(CachedAddrBeg),
|
||||
.CachedAddrEnd(CachedAddrEnd)
|
||||
.ArianeCfg(Cfg)
|
||||
) dut (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue