cva6/tb/ariane_testharness.sv
Michael Schaffner 88eb7de742
🎨 Beautify
2019-04-25 19:02:25 +02:00

769 lines
27 KiB
Systemverilog

// 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: 19.03.2017
// Description: Test-harness for Ariane
// Instantiates an AXI-Bus and memories
module ariane_testharness #(
parameter int unsigned AXI_USER_WIDTH = 1,
parameter int unsigned AXI_ADDRESS_WIDTH = 64,
parameter int unsigned AXI_DATA_WIDTH = 64,
parameter bit InclSimDTM = 1'b1,
parameter int unsigned NUM_WORDS = 2**25, // memory size
parameter bit StallRandomOutput = 1'b0,
parameter bit StallRandomInput = 1'b0
) (
input logic clk_i,
input logic rtc_i,
input logic rst_ni,
output logic [31:0] exit_o
);
// disable test-enable
logic test_en;
logic ndmreset;
logic ndmreset_n;
logic debug_req_core;
int jtag_enable;
logic init_done;
logic [31:0] jtag_exit, dmi_exit;
logic jtag_TCK;
logic jtag_TMS;
logic jtag_TDI;
logic jtag_TRSTn;
logic jtag_TDO_data;
logic jtag_TDO_driven;
logic debug_req_valid;
logic debug_req_ready;
logic debug_resp_valid;
logic debug_resp_ready;
logic jtag_req_valid;
logic [6:0] jtag_req_bits_addr;
logic [1:0] jtag_req_bits_op;
logic [31:0] jtag_req_bits_data;
logic jtag_resp_ready;
logic jtag_resp_valid;
logic dmi_req_valid;
logic dmi_resp_ready;
logic dmi_resp_valid;
dm::dmi_req_t jtag_dmi_req;
dm::dmi_req_t dmi_req;
dm::dmi_req_t debug_req;
dm::dmi_resp_t debug_resp;
assign test_en = 1'b0;
AXI_BUS #(
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
.AXI_ID_WIDTH ( ariane_soc::IdWidth ),
.AXI_USER_WIDTH ( AXI_USER_WIDTH )
) slave[ariane_soc::NrSlaves-1:0]();
AXI_BUS #(
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
.AXI_ID_WIDTH ( ariane_soc::IdWidthSlave ),
.AXI_USER_WIDTH ( AXI_USER_WIDTH )
) master[ariane_soc::NB_PERIPHERALS-1:0]();
rstgen i_rstgen_main (
.clk_i ( clk_i ),
.rst_ni ( rst_ni & (~ndmreset) ),
.test_mode_i ( test_en ),
.rst_no ( ndmreset_n ),
.init_no ( ) // keep open
);
// ---------------
// Debug
// ---------------
assign init_done = rst_ni;
initial begin
if (!$value$plusargs("jtag_rbb_enable=%b", jtag_enable)) jtag_enable = 'h0;
end
// debug if MUX
assign debug_req_valid = (jtag_enable[0]) ? jtag_req_valid : dmi_req_valid;
assign debug_resp_ready = (jtag_enable[0]) ? jtag_resp_ready : dmi_resp_ready;
assign debug_req = (jtag_enable[0]) ? jtag_dmi_req : dmi_req;
assign exit_o = (jtag_enable[0]) ? jtag_exit : dmi_exit;
assign jtag_resp_valid = (jtag_enable[0]) ? debug_resp_valid : 1'b0;
assign dmi_resp_valid = (jtag_enable[0]) ? 1'b0 : debug_resp_valid;
// SiFive's SimJTAG Module
// Converts to DPI calls
SimJTAG i_SimJTAG (
.clock ( clk_i ),
.reset ( ~rst_ni ),
.enable ( jtag_enable[0] ),
.init_done ( init_done ),
.jtag_TCK ( jtag_TCK ),
.jtag_TMS ( jtag_TMS ),
.jtag_TDI ( jtag_TDI ),
.jtag_TRSTn ( jtag_TRSTn ),
.jtag_TDO_data ( jtag_TDO_data ),
.jtag_TDO_driven ( jtag_TDO_driven ),
.exit ( jtag_exit )
);
dmi_jtag i_dmi_jtag (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.testmode_i ( test_en ),
.dmi_req_o ( jtag_dmi_req ),
.dmi_req_valid_o ( jtag_req_valid ),
.dmi_req_ready_i ( debug_req_ready ),
.dmi_resp_i ( debug_resp ),
.dmi_resp_ready_o ( jtag_resp_ready ),
.dmi_resp_valid_i ( jtag_resp_valid ),
.dmi_rst_no ( ), // not connected
.tck_i ( jtag_TCK ),
.tms_i ( jtag_TMS ),
.trst_ni ( jtag_TRSTn ),
.td_i ( jtag_TDI ),
.td_o ( jtag_TDO_data ),
.tdo_oe_o ( jtag_TDO_driven )
);
// SiFive's SimDTM Module
// Converts to DPI calls
logic [1:0] debug_req_bits_op;
assign dmi_req.op = dm::dtm_op_e'(debug_req_bits_op);
if (InclSimDTM) begin
SimDTM i_SimDTM (
.clk ( clk_i ),
.reset ( ~rst_ni ),
.debug_req_valid ( dmi_req_valid ),
.debug_req_ready ( debug_req_ready ),
.debug_req_bits_addr ( dmi_req.addr ),
.debug_req_bits_op ( debug_req_bits_op ),
.debug_req_bits_data ( dmi_req.data ),
.debug_resp_valid ( dmi_resp_valid ),
.debug_resp_ready ( dmi_resp_ready ),
.debug_resp_bits_resp ( debug_resp.resp ),
.debug_resp_bits_data ( debug_resp.data ),
.exit ( dmi_exit )
);
end else begin
assign dmi_req_valid = '0;
assign debug_req_bits_op = '0;
assign dmi_exit = 1'b0;
end
// this delay window allows the core to read and execute init code
// from the bootrom before the first debug request can interrupt
// core. this is needed in cases where an fsbl is involved that
// expects a0 and a1 to be initialized with the hart id and a
// pointer to the dev tree, respectively.
localparam int unsigned DmiDelCycles = 500;
logic debug_req_core_ungtd;
int dmi_del_cnt_d, dmi_del_cnt_q;
assign dmi_del_cnt_d = (dmi_del_cnt_q) ? dmi_del_cnt_q - 1 : 0;
assign debug_req_core = (dmi_del_cnt_q) ? 1'b0 : debug_req_core_ungtd;
always_ff @(posedge clk_i or negedge rst_ni) begin : p_dmi_del_cnt
if(!rst_ni) begin
dmi_del_cnt_q <= DmiDelCycles;
end else begin
dmi_del_cnt_q <= dmi_del_cnt_d;
end
end
ariane_axi::req_t dm_axi_m_req;
ariane_axi::resp_t dm_axi_m_resp;
logic dm_slave_req;
logic dm_slave_we;
logic [64-1:0] dm_slave_addr;
logic [64/8-1:0] dm_slave_be;
logic [64-1:0] dm_slave_wdata;
logic [64-1:0] dm_slave_rdata;
logic dm_master_req;
logic [64-1:0] dm_master_add;
logic dm_master_we;
logic [64-1:0] dm_master_wdata;
logic [64/8-1:0] dm_master_be;
logic dm_master_gnt;
logic dm_master_r_valid;
logic [64-1:0] dm_master_r_rdata;
// debug module
dm_top #(
.NrHarts ( 1 ),
.BusWidth ( AXI_DATA_WIDTH ),
.SelectableHarts ( 1'b1 )
) i_dm_top (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ), // PoR
.testmode_i ( test_en ),
.ndmreset_o ( ndmreset ),
.dmactive_o ( ), // active debug session
.debug_req_o ( debug_req_core_ungtd ),
.unavailable_i ( '0 ),
.hartinfo_i ( {ariane_pkg::DebugHartInfo} ),
.slave_req_i ( dm_slave_req ),
.slave_we_i ( dm_slave_we ),
.slave_addr_i ( dm_slave_addr ),
.slave_be_i ( dm_slave_be ),
.slave_wdata_i ( dm_slave_wdata ),
.slave_rdata_o ( dm_slave_rdata ),
.master_req_o ( dm_master_req ),
.master_add_o ( dm_master_add ),
.master_we_o ( dm_master_we ),
.master_wdata_o ( dm_master_wdata ),
.master_be_o ( dm_master_be ),
.master_gnt_i ( dm_master_gnt ),
.master_r_valid_i ( dm_master_r_valid ),
.master_r_rdata_i ( dm_master_r_rdata ),
.dmi_rst_ni ( rst_ni ),
.dmi_req_valid_i ( debug_req_valid ),
.dmi_req_ready_o ( debug_req_ready ),
.dmi_req_i ( debug_req ),
.dmi_resp_valid_o ( debug_resp_valid ),
.dmi_resp_ready_i ( debug_resp_ready ),
.dmi_resp_o ( debug_resp )
);
axi2mem #(
.AXI_ID_WIDTH ( ariane_soc::IdWidthSlave ),
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
.AXI_USER_WIDTH ( AXI_USER_WIDTH )
) i_dm_axi2mem (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.slave ( master[ariane_soc::Debug] ),
.req_o ( dm_slave_req ),
.we_o ( dm_slave_we ),
.addr_o ( dm_slave_addr ),
.be_o ( dm_slave_be ),
.data_o ( dm_slave_wdata ),
.data_i ( dm_slave_rdata )
);
axi_master_connect i_dm_axi_master_connect (
.axi_req_i(dm_axi_m_req),
.axi_resp_o(dm_axi_m_resp),
.master(slave[1])
);
axi_adapter #(
.DATA_WIDTH ( AXI_DATA_WIDTH )
) i_dm_axi_master (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.req_i ( dm_master_req ),
.type_i ( ariane_axi::SINGLE_REQ ),
.gnt_o ( dm_master_gnt ),
.gnt_id_o ( ),
.addr_i ( dm_master_add ),
.we_i ( dm_master_we ),
.wdata_i ( dm_master_wdata ),
.be_i ( dm_master_be ),
.size_i ( 2'b11 ), // always do 64bit here and use byte enables to gate
.id_i ( '0 ),
.valid_o ( dm_master_r_valid ),
.rdata_o ( dm_master_r_rdata ),
.id_o ( ),
.critical_word_o ( ),
.critical_word_valid_o ( ),
.axi_req_o ( dm_axi_m_req ),
.axi_resp_i ( dm_axi_m_resp )
);
// ---------------
// ROM
// ---------------
logic rom_req;
logic [AXI_ADDRESS_WIDTH-1:0] rom_addr;
logic [AXI_DATA_WIDTH-1:0] rom_rdata;
axi2mem #(
.AXI_ID_WIDTH ( ariane_soc::IdWidthSlave ),
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
.AXI_USER_WIDTH ( AXI_USER_WIDTH )
) i_axi2rom (
.clk_i ( clk_i ),
.rst_ni ( ndmreset_n ),
.slave ( master[ariane_soc::ROM] ),
.req_o ( rom_req ),
.we_o ( ),
.addr_o ( rom_addr ),
.be_o ( ),
.data_o ( ),
.data_i ( rom_rdata )
);
bootrom i_bootrom (
.clk_i ( clk_i ),
.req_i ( rom_req ),
.addr_i ( rom_addr ),
.rdata_o ( rom_rdata )
);
// ------------------------------
// Memory + Exclusive Access
// ------------------------------
AXI_BUS #(
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
.AXI_ID_WIDTH ( ariane_soc::IdWidthSlave ),
.AXI_USER_WIDTH ( AXI_USER_WIDTH )
) dram();
logic req;
logic we;
logic [AXI_ADDRESS_WIDTH-1:0] addr;
logic [AXI_DATA_WIDTH/8-1:0] be;
logic [AXI_DATA_WIDTH-1:0] wdata;
logic [AXI_DATA_WIDTH-1:0] rdata;
axi_riscv_atomics_wrap #(
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
.AXI_ID_WIDTH ( ariane_soc::IdWidthSlave ),
.AXI_USER_WIDTH ( AXI_USER_WIDTH ),
.AXI_MAX_WRITE_TXNS ( 1 ),
.RISCV_WORD_WIDTH ( 64 )
) i_axi_riscv_atomics (
.clk_i,
.rst_ni ( ndmreset_n ),
.slv ( master[ariane_soc::DRAM] ),
.mst ( dram )
);
AXI_BUS #(
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
.AXI_ID_WIDTH ( ariane_soc::IdWidthSlave ),
.AXI_USER_WIDTH ( AXI_USER_WIDTH )
) dram_delayed();
ariane_axi::aw_chan_slv_t aw_chan_i;
ariane_axi::w_chan_t w_chan_i;
ariane_axi::b_chan_slv_t b_chan_o;
ariane_axi::ar_chan_slv_t ar_chan_i;
ariane_axi::r_chan_slv_t r_chan_o;
ariane_axi::aw_chan_slv_t aw_chan_o;
ariane_axi::w_chan_t w_chan_o;
ariane_axi::b_chan_slv_t b_chan_i;
ariane_axi::ar_chan_slv_t ar_chan_o;
ariane_axi::r_chan_slv_t r_chan_i;
axi_delayer #(
.aw_t ( ariane_axi::aw_chan_slv_t ),
.w_t ( ariane_axi::w_chan_t ),
.b_t ( ariane_axi::b_chan_slv_t ),
.ar_t ( ariane_axi::ar_chan_slv_t ),
.r_t ( ariane_axi::r_chan_slv_t ),
.StallRandomOutput ( StallRandomOutput ),
.StallRandomInput ( StallRandomInput ),
.FixedDelayInput ( 0 ),
.FixedDelayOutput ( 0 )
) i_axi_delayer (
.clk_i ( clk_i ),
.rst_ni ( ndmreset_n ),
.aw_valid_i ( dram.aw_valid ),
.aw_chan_i ( aw_chan_i ),
.aw_ready_o ( dram.aw_ready ),
.w_valid_i ( dram.w_valid ),
.w_chan_i ( w_chan_i ),
.w_ready_o ( dram.w_ready ),
.b_valid_o ( dram.b_valid ),
.b_chan_o ( b_chan_o ),
.b_ready_i ( dram.b_ready ),
.ar_valid_i ( dram.ar_valid ),
.ar_chan_i ( ar_chan_i ),
.ar_ready_o ( dram.ar_ready ),
.r_valid_o ( dram.r_valid ),
.r_chan_o ( r_chan_o ),
.r_ready_i ( dram.r_ready ),
.aw_valid_o ( dram_delayed.aw_valid ),
.aw_chan_o ( aw_chan_o ),
.aw_ready_i ( dram_delayed.aw_ready ),
.w_valid_o ( dram_delayed.w_valid ),
.w_chan_o ( w_chan_o ),
.w_ready_i ( dram_delayed.w_ready ),
.b_valid_i ( dram_delayed.b_valid ),
.b_chan_i ( b_chan_i ),
.b_ready_o ( dram_delayed.b_ready ),
.ar_valid_o ( dram_delayed.ar_valid ),
.ar_chan_o ( ar_chan_o ),
.ar_ready_i ( dram_delayed.ar_ready ),
.r_valid_i ( dram_delayed.r_valid ),
.r_chan_i ( r_chan_i ),
.r_ready_o ( dram_delayed.r_ready )
);
assign aw_chan_i.atop = dram.aw_atop;
assign aw_chan_i.id = dram.aw_id;
assign aw_chan_i.addr = dram.aw_addr;
assign aw_chan_i.len = dram.aw_len;
assign aw_chan_i.size = dram.aw_size;
assign aw_chan_i.burst = dram.aw_burst;
assign aw_chan_i.lock = dram.aw_lock;
assign aw_chan_i.cache = dram.aw_cache;
assign aw_chan_i.prot = dram.aw_prot;
assign aw_chan_i.qos = dram.aw_qos;
assign aw_chan_i.region = dram.aw_region;
assign ar_chan_i.id = dram.ar_id;
assign ar_chan_i.addr = dram.ar_addr;
assign ar_chan_i.len = dram.ar_len;
assign ar_chan_i.size = dram.ar_size;
assign ar_chan_i.burst = dram.ar_burst;
assign ar_chan_i.lock = dram.ar_lock;
assign ar_chan_i.cache = dram.ar_cache;
assign ar_chan_i.prot = dram.ar_prot;
assign ar_chan_i.qos = dram.ar_qos;
assign ar_chan_i.region = dram.ar_region;
assign w_chan_i.data = dram.w_data;
assign w_chan_i.strb = dram.w_strb;
assign w_chan_i.last = dram.w_last;
assign dram.r_id = r_chan_o.id;
assign dram.r_data = r_chan_o.data;
assign dram.r_resp = r_chan_o.resp;
assign dram.r_last = r_chan_o.last;
assign dram.b_id = b_chan_o.id;
assign dram.b_resp = b_chan_o.resp;
assign dram_delayed.aw_id = aw_chan_o.id;
assign dram_delayed.aw_addr = aw_chan_o.addr;
assign dram_delayed.aw_len = aw_chan_o.len;
assign dram_delayed.aw_size = aw_chan_o.size;
assign dram_delayed.aw_burst = aw_chan_o.burst;
assign dram_delayed.aw_lock = aw_chan_o.lock;
assign dram_delayed.aw_cache = aw_chan_o.cache;
assign dram_delayed.aw_prot = aw_chan_o.prot;
assign dram_delayed.aw_qos = aw_chan_o.qos;
assign dram_delayed.aw_atop = aw_chan_o.atop;
assign dram_delayed.aw_region = aw_chan_o.region;
assign dram_delayed.aw_user = '0;
assign dram_delayed.ar_id = ar_chan_o.id;
assign dram_delayed.ar_addr = ar_chan_o.addr;
assign dram_delayed.ar_len = ar_chan_o.len;
assign dram_delayed.ar_size = ar_chan_o.size;
assign dram_delayed.ar_burst = ar_chan_o.burst;
assign dram_delayed.ar_lock = ar_chan_o.lock;
assign dram_delayed.ar_cache = ar_chan_o.cache;
assign dram_delayed.ar_prot = ar_chan_o.prot;
assign dram_delayed.ar_qos = ar_chan_o.qos;
assign dram_delayed.ar_region = ar_chan_o.region;
assign dram_delayed.ar_user = '0;
assign dram_delayed.w_data = w_chan_o.data;
assign dram_delayed.w_strb = w_chan_o.strb;
assign dram_delayed.w_last = w_chan_o.last;
assign dram_delayed.w_user = '0;
assign r_chan_i.id = dram_delayed.r_id;
assign r_chan_i.data = dram_delayed.r_data;
assign r_chan_i.resp = dram_delayed.r_resp;
assign r_chan_i.last = dram_delayed.r_last;
assign dram.r_user = '0;
assign b_chan_i.id = dram_delayed.b_id;
assign b_chan_i.resp = dram_delayed.b_resp;
assign dram.b_user = '0;
axi2mem #(
.AXI_ID_WIDTH ( ariane_soc::IdWidthSlave ),
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
.AXI_USER_WIDTH ( AXI_USER_WIDTH )
) i_axi2mem (
.clk_i ( clk_i ),
.rst_ni ( ndmreset_n ),
.slave ( dram_delayed ),
.req_o ( req ),
.we_o ( we ),
.addr_o ( addr ),
.be_o ( be ),
.data_o ( wdata ),
.data_i ( rdata )
);
sram #(
.DATA_WIDTH ( AXI_DATA_WIDTH ),
.NUM_WORDS ( NUM_WORDS )
) i_sram (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.req_i ( req ),
.we_i ( we ),
.addr_i ( addr[$clog2(NUM_WORDS)-1+$clog2(AXI_DATA_WIDTH/8):$clog2(AXI_DATA_WIDTH/8)] ),
.wdata_i ( wdata ),
.be_i ( be ),
.rdata_o ( rdata )
);
// ---------------
// AXI Xbar
// ---------------
axi_node_intf_wrap #(
.NB_SLAVE ( ariane_soc::NrSlaves ),
.NB_MASTER ( ariane_soc::NB_PERIPHERALS ),
.NB_REGION ( ariane_soc::NrRegion ),
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
.AXI_USER_WIDTH ( AXI_USER_WIDTH ),
.AXI_ID_WIDTH ( ariane_soc::IdWidth )
// .MASTER_SLICE_DEPTH ( 0 ),
// .SLAVE_SLICE_DEPTH ( 0 )
) i_axi_xbar (
.clk ( clk_i ),
.rst_n ( ndmreset_n ),
.test_en_i ( test_en ),
.slave ( slave ),
.master ( master ),
.start_addr_i ({
ariane_soc::DebugBase,
ariane_soc::ROMBase,
ariane_soc::CLINTBase,
ariane_soc::PLICBase,
ariane_soc::UARTBase,
ariane_soc::SPIBase,
ariane_soc::EthernetBase,
ariane_soc::GPIOBase,
ariane_soc::DRAMBase
}),
.end_addr_i ({
ariane_soc::DebugBase + ariane_soc::DebugLength - 1,
ariane_soc::ROMBase + ariane_soc::ROMLength - 1,
ariane_soc::CLINTBase + ariane_soc::CLINTLength - 1,
ariane_soc::PLICBase + ariane_soc::PLICLength - 1,
ariane_soc::UARTBase + ariane_soc::UARTLength - 1,
ariane_soc::SPIBase + ariane_soc::SPILength - 1,
ariane_soc::EthernetBase + ariane_soc::EthernetLength -1,
ariane_soc::GPIOBase + ariane_soc::GPIOLength - 1,
ariane_soc::DRAMBase + ariane_soc::DRAMLength - 1
}),
.valid_rule_i (ariane_soc::ValidRule)
);
// ---------------
// CLINT
// ---------------
logic ipi;
logic timer_irq;
ariane_axi::req_t axi_clint_req;
ariane_axi::resp_t axi_clint_resp;
clint #(
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
.AXI_ID_WIDTH ( ariane_soc::IdWidthSlave ),
.NR_CORES ( 1 )
) i_clint (
.clk_i ( clk_i ),
.rst_ni ( ndmreset_n ),
.testmode_i ( test_en ),
.axi_req_i ( axi_clint_req ),
.axi_resp_o ( axi_clint_resp ),
.rtc_i ( rtc_i ),
.timer_irq_o ( timer_irq ),
.ipi_o ( ipi )
);
axi_slave_connect i_axi_slave_connect_clint (
.axi_req_o(axi_clint_req),
.axi_resp_i(axi_clint_resp),
.slave(master[ariane_soc::CLINT])
);
// ---------------
// Peripherals
// ---------------
logic tx, rx;
logic [1:0] irqs;
ariane_peripherals #(
.AxiAddrWidth ( AXI_ADDRESS_WIDTH ),
.AxiDataWidth ( AXI_DATA_WIDTH ),
.AxiIdWidth ( ariane_soc::IdWidthSlave ),
`ifndef VERILATOR
// disable UART when using Spike, as we need to rely on the mockuart
`ifdef SPIKE_TANDEM
.InclUART ( 1'b0 ),
`else
.InclUART ( 1'b1 ),
`endif
`else
.InclUART ( 1'b0 ),
`endif
.InclSPI ( 1'b0 ),
.InclEthernet ( 1'b0 )
) i_ariane_peripherals (
.clk_i ( clk_i ),
.rst_ni ( ndmreset_n ),
.plic ( master[ariane_soc::PLIC] ),
.uart ( master[ariane_soc::UART] ),
.spi ( master[ariane_soc::SPI] ),
.ethernet ( master[ariane_soc::Ethernet] ),
.irq_o ( irqs ),
.rx_i ( rx ),
.tx_o ( tx ),
.eth_txck ( ),
.eth_rxck ( ),
.eth_rxctl ( ),
.eth_rxd ( ),
.eth_rst_n ( ),
.eth_tx_en ( ),
.eth_txd ( ),
.phy_mdio ( ),
.eth_mdc ( ),
.mdio ( ),
.mdc ( ),
.spi_clk_o ( ),
.spi_mosi ( ),
.spi_miso ( ),
.spi_ss ( )
);
uart_bus #(.BAUD_RATE(115200), .PARITY_EN(0)) i_uart_bus (.rx(tx), .tx(rx), .rx_en(1'b1));
// ---------------
// Core
// ---------------
ariane_axi::req_t axi_ariane_req;
ariane_axi::resp_t axi_ariane_resp;
ariane #(
.ArianeCfg ( ariane_soc::ArianeSocCfg )
) i_ariane (
.clk_i ( clk_i ),
.rst_ni ( ndmreset_n ),
.boot_addr_i ( ariane_soc::ROMBase ), // start fetching from ROM
.hart_id_i ( '0 ),
.irq_i ( irqs ),
.ipi_i ( ipi ),
.time_irq_i ( timer_irq ),
// Disable Debug when simulating with Spike
`ifdef SPIKE_TANDEM
.debug_req_i ( 1'b0 ),
`else
.debug_req_i ( debug_req_core ),
`endif
.axi_req_o ( axi_ariane_req ),
.axi_resp_i ( axi_ariane_resp )
);
axi_master_connect i_axi_master_connect_ariane (
.axi_req_i(axi_ariane_req),
.axi_resp_o(axi_ariane_resp),
.master(slave[0])
);
// -------------
// Simulation Helper Functions
// -------------
// check for response errors
always_ff @(posedge clk_i) begin : p_assert
if (axi_ariane_req.r_ready &&
axi_ariane_resp.r_valid &&
axi_ariane_resp.r.resp inside {axi_pkg::RESP_DECERR, axi_pkg::RESP_SLVERR}) begin
$warning("R Response Errored");
end
if (axi_ariane_req.b_ready &&
axi_ariane_resp.b_valid &&
axi_ariane_resp.b.resp inside {axi_pkg::RESP_DECERR, axi_pkg::RESP_SLVERR}) begin
$warning("B Response Errored");
end
end
`ifdef AXI_SVA
// AXI 4 Assertion IP integration - You will need to get your own copy of this IP if you want
// to use it
Axi4PC #(
.DATA_WIDTH(ariane_axi::DataWidth),
.WID_WIDTH(ariane_soc::IdWidthSlave),
.RID_WIDTH(ariane_soc::IdWidthSlave),
.AWUSER_WIDTH(ariane_axi::UserWidth),
.WUSER_WIDTH(ariane_axi::UserWidth),
.BUSER_WIDTH(ariane_axi::UserWidth),
.ARUSER_WIDTH(ariane_axi::UserWidth),
.RUSER_WIDTH(ariane_axi::UserWidth),
.ADDR_WIDTH(ariane_axi::AddrWidth)
) i_Axi4PC (
.ACLK(clk_i),
.ARESETn(ndmreset_n),
.AWID(dram.aw_id),
.AWADDR(dram.aw_addr),
.AWLEN(dram.aw_len),
.AWSIZE(dram.aw_size),
.AWBURST(dram.aw_burst),
.AWLOCK(dram.aw_lock),
.AWCACHE(dram.aw_cache),
.AWPROT(dram.aw_prot),
.AWQOS(dram.aw_qos),
.AWREGION(dram.aw_region),
.AWUSER(dram.aw_user),
.AWVALID(dram.aw_valid),
.AWREADY(dram.aw_ready),
.WLAST(dram.w_last),
.WDATA(dram.w_data),
.WSTRB(dram.w_strb),
.WUSER(dram.w_user),
.WVALID(dram.w_valid),
.WREADY(dram.w_ready),
.BID(dram.b_id),
.BRESP(dram.b_resp),
.BUSER(dram.b_user),
.BVALID(dram.b_valid),
.BREADY(dram.b_ready),
.ARID(dram.ar_id),
.ARADDR(dram.ar_addr),
.ARLEN(dram.ar_len),
.ARSIZE(dram.ar_size),
.ARBURST(dram.ar_burst),
.ARLOCK(dram.ar_lock),
.ARCACHE(dram.ar_cache),
.ARPROT(dram.ar_prot),
.ARQOS(dram.ar_qos),
.ARREGION(dram.ar_region),
.ARUSER(dram.ar_user),
.ARVALID(dram.ar_valid),
.ARREADY(dram.ar_ready),
.RID(dram.r_id),
.RLAST(dram.r_last),
.RDATA(dram.r_data),
.RRESP(dram.r_resp),
.RUSER(dram.r_user),
.RVALID(dram.r_valid),
.RREADY(dram.r_ready),
.CACTIVE('0),
.CSYSREQ('0),
.CSYSACK('0)
);
`endif
endmodule