blob: 4b300ca62bcba0ac34227b77b1259e94ce1e0d54 [file] [log] [blame]
// Copyright 2020 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.
// Wrapper for a RI5CY testbench, containing RI5CY, Memory and stdout peripheral
// Contributor: Robert Balas <balasr@iis.ee.ethz.ch>
module tb_test_env #(
parameter int unsigned INSTR_RDATA_WIDTH = 32,
parameter int unsigned RAM_ADDR_WIDTH = 20,
parameter logic [31:0] BOOT_ADDR = 'h80,
parameter bit JTAG_BOOT = 1,
parameter int unsigned OPENOCD_PORT = 0,
parameter bit A_EXTENSION = 0
) (
input logic clk_i,
input logic rst_ni,
// currently we are not making use of those signals
input logic fetch_enable_i,
output logic tests_passed_o,
output logic tests_failed_o);
// defs from pulpissimo
// localparam CLUSTER_ID = 6'd31;
// localparam CORE_ID = 4'd0;
// test defs
localparam CLUSTER_ID = 6'd0;
localparam CORE_ID = 4'd0;
localparam CORE_MHARTID = {21'b0, CLUSTER_ID, 1'b0, CORE_ID};
localparam NrHarts = 1;
localparam logic [NrHarts-1:0] SELECTABLE_HARTS = 1 << CORE_MHARTID;
localparam HARTINFO = {8'h0, 4'h2, 3'b0, 1'b1, dm::DataCount, dm::DataAddr};
// signals connecting core to memory
logic instr_req;
logic instr_gnt;
logic instr_rvalid;
logic [31:0] instr_addr;
logic [INSTR_RDATA_WIDTH-1:0] instr_rdata;
logic data_req;
logic data_gnt;
logic data_rvalid;
logic [31:0] data_addr;
logic data_we;
logic [3:0] data_be;
logic [31:0] data_rdata;
logic [31:0] data_wdata;
// jtag openocd bridge signals
logic sim_jtag_tck;
logic sim_jtag_tms;
logic sim_jtag_tdi;
logic sim_jtag_trstn;
logic sim_jtag_tdo;
logic [31:0] sim_jtag_exit;
logic sim_jtag_enable;
// signals for debug unit
logic debug_req_ready;
dm::dmi_resp_t debug_resp;
logic jtag_req_valid;
dm::dmi_req_t jtag_dmi_req;
logic jtag_resp_ready;
logic jtag_resp_valid;
logic [NrHarts-1:0] dm_debug_req;
logic ndmreset, ndmreset_n;
// debug unit slave interface
logic dm_grant;
logic dm_rvalid;
logic dm_req;
logic dm_we;
logic [31:0] dm_addr;
logic [31:0] dm_wdata;
logic [31:0] dm_rdata;
logic [3:0] dm_be;
// debug unit master interface (system bus access)
logic sb_req;
logic [31:0] sb_addr;
logic sb_we;
logic [31:0] sb_wdata;
logic [3:0] sb_be;
logic sb_gnt;
logic sb_rvalid;
logic [31:0] sb_rdata;
// irq signals (not used)
logic irq;
logic [0:4] irq_id_in;
logic irq_ack;
logic [0:4] irq_id_out;
// make jtag bridge work
assign sim_jtag_enable = JTAG_BOOT;
// instantiate the core
cv32e40p_core #(
.PULP_XPULP ( 0 ),
.PULP_CLUSTER ( 0 ),
.FPU ( 0 ),
.PULP_ZFINX ( 0 ),
.NUM_MHPMCOUNTERS ( 1 )
) riscv_core_i (
.clk_i ( clk_i ),
.rst_ni ( ndmreset_n ),
.pulp_clock_en_i ( '1 ),
.scan_cg_en_i ( '0 ),
.boot_addr_i ( BOOT_ADDR ),
.mtvec_addr_i ( 32'h00000000 ),
.dm_halt_addr_i ( 32'h1A110800 ),
.hart_id_i ( CORE_MHARTID ),
.dm_exception_addr_i ( 32'h00000000 ),
.instr_addr_o ( instr_addr ),
.instr_req_o ( instr_req ),
.instr_rdata_i ( instr_rdata ),
.instr_gnt_i ( instr_gnt ),
.instr_rvalid_i ( instr_rvalid ),
.data_addr_o ( data_addr ),
.data_wdata_o ( data_wdata ),
.data_we_o ( data_we ),
.data_req_o ( data_req ),
.data_be_o ( data_be ),
.data_rdata_i ( data_rdata ),
.data_gnt_i ( data_gnt ),
.data_rvalid_i ( data_rvalid ),
.apu_master_req_o ( ),
.apu_master_ready_o ( ),
.apu_master_gnt_i ( ),
.apu_master_operands_o ( ),
.apu_master_op_o ( ),
.apu_master_type_o ( ),
.apu_master_flags_o ( ),
.apu_master_valid_i ( ),
.apu_master_result_i ( ),
.apu_master_flags_i ( ),
.irq_i ( 32'b0 ),
.irq_ack_o ( irq_ack ),
.irq_id_o ( irq_id_out ),
.debug_req_i ( dm_debug_req[CORE_MHARTID] ),
.fetch_enable_i ( fetch_enable_i ),
.core_sleep_o ( core_sleep_o )
);
// this handles read to RAM and memory mapped pseudo peripherals
mm_ram #(
.RAM_ADDR_WIDTH (RAM_ADDR_WIDTH),
.INSTR_RDATA_WIDTH (INSTR_RDATA_WIDTH),
.JTAG_BOOT(JTAG_BOOT)
) mm_ram_i (
.clk_i ( clk_i ),
.rst_ni ( ndmreset_n ),
// core instruction access
.instr_req_i ( instr_req ),
.instr_addr_i ( instr_addr ),
.instr_rdata_o ( instr_rdata ),
.instr_rvalid_o ( instr_rvalid ),
.instr_gnt_o ( instr_gnt ),
// core data access
.data_req_i ( data_req ),
.data_addr_i ( data_addr ),
.data_we_i ( data_we ),
.data_be_i ( data_be ),
.data_wdata_i ( data_wdata ),
.data_rdata_o ( data_rdata ),
.data_rvalid_o ( data_rvalid ),
.data_gnt_o ( data_gnt ),
// system bus access from debug unit
.sb_req_i ( sb_req ),
.sb_addr_i ( sb_addr ),
.sb_we_i ( sb_we ),
.sb_be_i ( sb_be ),
.sb_wdata_i ( sb_wdata ),
.sb_rdata_o ( sb_rdata ),
.sb_rvalid_o ( sb_rvalid ),
.sb_gnt_o ( sb_gnt ),
// access to debug unit
.dm_req_o ( dm_req ),
.dm_addr_o ( dm_addr ),
.dm_we_o ( dm_we ),
.dm_be_o ( dm_be ),
.dm_wdata_o ( dm_wdata ),
.dm_rdata_i ( dm_rdata ),
.dm_rvalid_i ( dm_rvalid ),
.dm_gnt_i ( dm_gnt ),
.irq_id_i ( irq_id_out ),
.irq_ack_i ( irq_ack ),
.irq_id_o ( irq_id_in ),
.irq_o ( irq ),
.tests_passed_o ( tests_passed_o ),
.tests_failed_o ( tests_failed_o )
);
// debug subsystem
dmi_jtag #(
.IdcodeValue ( 32'h249511C3 )
) i_dmi_jtag (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.testmode_i ( 1'b0 ),
.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 ( sim_jtag_tck ),
.tms_i ( sim_jtag_tms ),
.trst_ni ( sim_jtag_trstn ),
.td_i ( sim_jtag_tdi ),
.td_o ( sim_jtag_tdo ),
.tdo_oe_o ( )
);
dm_top #(
.NrHarts ( NrHarts ),
.BusWidth ( 32 ),
.SelectableHarts ( SELECTABLE_HARTS )
) i_dm_top (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.testmode_i ( 1'b0 ),
.ndmreset_o ( ndmreset ),
.dmactive_o ( ), // active debug session TODO
.debug_req_o ( dm_debug_req ),
.unavailable_i ( ~SELECTABLE_HARTS ),
.hartinfo_i ( HARTINFO ),
.slave_req_i ( dm_req ),
.slave_we_i ( dm_we ),
.slave_addr_i ( dm_addr ),
.slave_be_i ( dm_be ),
.slave_wdata_i ( dm_wdata ),
.slave_rdata_o ( dm_rdata ),
.master_req_o ( sb_req ),
.master_add_o ( sb_addr ),
.master_we_o ( sb_we ),
.master_wdata_o ( sb_wdata ),
.master_be_o ( sb_be ),
.master_gnt_i ( sb_gnt ),
.master_r_valid_i ( sb_rvalid ),
.master_r_err_i ( 1'b0 ),
.master_r_other_err_i ( 1'b0 ),
.master_r_rdata_i ( sb_rdata ),
.dmi_rst_ni ( rst_ni ),
.dmi_req_valid_i ( jtag_req_valid ),
.dmi_req_ready_o ( debug_req_ready ),
.dmi_req_i ( jtag_dmi_req ),
.dmi_resp_valid_o ( jtag_resp_valid ),
.dmi_resp_ready_i ( jtag_resp_ready ),
.dmi_resp_o ( debug_resp )
);
///////////////////////////////////////////////////////
// Bind RTL assertions to Debug Module
///////////////////////////////////////////////////////
bind dm_top
dm_top_sva
#(
.NrHarts ( NrHarts ),
.BusWidth ( BusWidth ),
.SelectableHarts ( SelectableHarts ))
i_dm_top_sva (.*);
bind dm_csrs
dm_csrs_sva
#(
.NrHarts ( NrHarts ),
.BusWidth ( BusWidth ),
.SelectableHarts ( SelectableHarts ))
i_dm_csrs_sva (.*);
bind dm_sba
dm_sba_sva
#(
.BusWidth ( BusWidth ),
.ReadByteEnable ( ReadByteEnable ))
i_dm_sba_sva (.*);
// grant in the same cycle
assign dm_gnt = dm_req;
// valid read/write in the next cycle
always_ff @(posedge clk_i or negedge rst_ni) begin : dm_valid_handler
if(~rst_ni) begin
dm_rvalid <= '0;
end else begin
dm_rvalid <= dm_gnt;
end
end
// reset handling with ndmreset
rstgen i_rstgen_main (
.clk_i ( clk_i ),
.rst_ni ( rst_ni & (~ndmreset) ),
.test_mode_i ( '0 ),
.rst_no ( ndmreset_n ),
.init_no ( ) // keep open
);
// jtag calls from dpi
SimJTAG #(
.TICK_DELAY (1),
.PORT(OPENOCD_PORT)
) i_sim_jtag (
.clock ( clk_i ),
.reset ( ~rst_ni ),
.enable ( sim_jtag_enable ),
.init_done ( rst_ni ),
.jtag_TCK ( sim_jtag_tck ),
.jtag_TMS ( sim_jtag_tms ),
.jtag_TDI ( sim_jtag_tdi ),
.jtag_TRSTn ( sim_jtag_trstn ),
.jtag_TDO_data ( sim_jtag_tdo ),
.jtag_TDO_driven ( 1'b1 ),
.exit ( sim_jtag_exit )
);
always_comb begin : jtag_exit_handler
if (sim_jtag_exit)
$finish(2); // print stats too
end
endmodule // tb_test_env