239 lines
7.4 KiB
Systemverilog
239 lines
7.4 KiB
Systemverilog
|
// SPDX-License-Identifier: Apache-2.0
|
||
|
// Copyright 2020 Western Digital Corporation or its affiliates.
|
||
|
//
|
||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
// you may not use this file except in compliance with the License.
|
||
|
// You may obtain a copy of the License at
|
||
|
//
|
||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
//
|
||
|
// Unless required by applicable law or agreed to in writing, software
|
||
|
// distributed under the 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.
|
||
|
//
|
||
|
|
||
|
module soc_sim (
|
||
|
input bit core_clk
|
||
|
);
|
||
|
|
||
|
logic rst_l;
|
||
|
logic dbg_rst_l;
|
||
|
|
||
|
wire jtag_tdo;
|
||
|
wire jtag_tck;
|
||
|
wire jtag_tms;
|
||
|
wire jtag_tdi;
|
||
|
wire jtag_trst_n;
|
||
|
|
||
|
bit [31:0] cycleCnt;
|
||
|
logic mailbox_data_val;
|
||
|
int commit_count;
|
||
|
|
||
|
logic wb_valid;
|
||
|
logic [4:0] wb_dest;
|
||
|
logic [31:0] wb_data;
|
||
|
|
||
|
wire [63:0] WriteData;
|
||
|
string abi_reg[32]; // ABI register names
|
||
|
|
||
|
assign WriteData = rvsoc.lsu_axi_wdata;
|
||
|
assign mailbox_data_val = WriteData[7:0] > 8'h5 && WriteData[7:0] < 8'h7f;
|
||
|
|
||
|
parameter MAILBOX_ADDR = 32'hD0580000;
|
||
|
logic write;
|
||
|
logic [31:0] laddr;
|
||
|
|
||
|
wire mailbox_write = rvsoc.lmem_axi_awvalid && rvsoc.lsu_axi_awaddr == MAILBOX_ADDR && rst_l;
|
||
|
always @(posedge core_clk or negedge rst_l) begin
|
||
|
if (~rst_l) begin
|
||
|
laddr <= 32'b0;
|
||
|
write <= 1'b0;
|
||
|
end else begin
|
||
|
if (rvsoc.lsu_hready) begin
|
||
|
laddr <= rvsoc.lsu_haddr;
|
||
|
write <= rvsoc.lsu_hwrite & |rvsoc.lsu_htrans;
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
parameter MAX_CYCLES = 10_000_000_0;
|
||
|
|
||
|
integer fd, tp, el;
|
||
|
|
||
|
/* verilator lint_off WIDTH */
|
||
|
/* verilator lint_off CASEINCOMPLETE */
|
||
|
`include "dasm.svi"
|
||
|
/* verilator lint_on CASEINCOMPLETE */
|
||
|
/* verilator lint_on WIDTH */
|
||
|
|
||
|
always @(posedge core_clk) begin
|
||
|
cycleCnt <= cycleCnt + 1;
|
||
|
|
||
|
if (cycleCnt == MAX_CYCLES) begin
|
||
|
$display("Hit max cycle count (%0d) .. stopping", cycleCnt);
|
||
|
$finish;
|
||
|
end
|
||
|
if (mailbox_data_val & mailbox_write) begin
|
||
|
$fwrite(fd, "%c", WriteData[7:0]);
|
||
|
$write("%c", WriteData[7:0]);
|
||
|
end
|
||
|
if (mailbox_write && WriteData[7:0] == 8'hff) begin
|
||
|
$display("\nFinished : minstret = %0d, mcycle = %0d",
|
||
|
rvsoc.rvtop.swerv.dec.tlu.minstretl[31:0],
|
||
|
rvsoc.rvtop.swerv.dec.tlu.mcyclel[31:0]);
|
||
|
$display(
|
||
|
"See \"exec.log\" for execution trace with register updates..\n");
|
||
|
$display("TEST_PASSED");
|
||
|
$finish;
|
||
|
end else if (mailbox_write && WriteData[7:0] == 8'h1) begin
|
||
|
$display("TEST_FAILED");
|
||
|
$finish;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
// trace monitor
|
||
|
always @(posedge core_clk) begin
|
||
|
wb_valid <= rvsoc.rvtop.swerv.dec.dec_i0_wen_r;
|
||
|
wb_dest <= rvsoc.rvtop.swerv.dec.dec_i0_waddr_r;
|
||
|
wb_data <= rvsoc.rvtop.swerv.dec.dec_i0_wdata_r;
|
||
|
if (rvsoc.trace_rv_i_valid_ip) begin
|
||
|
$fwrite(tp, "%b,%h,%h,%0h,%0h,3,%b,%h,%h,%b\n", rvsoc.trace_rv_i_valid_ip,
|
||
|
0, rvsoc.trace_rv_i_address_ip, 0, rvsoc.trace_rv_i_insn_ip,
|
||
|
rvsoc.trace_rv_i_exception_ip, rvsoc.trace_rv_i_ecause_ip,
|
||
|
rvsoc.trace_rv_i_tval_ip, rvsoc.trace_rv_i_interrupt_ip);
|
||
|
// Basic trace - no exception register updates
|
||
|
// #1 0 ee000000 b0201073 c 0b02 00000000
|
||
|
commit_count++;
|
||
|
$fwrite(el, "%10d : %8s 0 %h %h%13s ; %s\n", cycleCnt, $sformatf(
|
||
|
"#%0d", commit_count), rvsoc.trace_rv_i_address_ip,
|
||
|
rvsoc.trace_rv_i_insn_ip, (wb_dest != 0 && wb_valid) ? $sformatf(
|
||
|
"%s=%h", abi_reg[wb_dest], wb_data) : " ", dasm(
|
||
|
rvsoc.trace_rv_i_insn_ip,
|
||
|
rvsoc.trace_rv_i_address_ip,
|
||
|
wb_dest & {5{wb_valid}},
|
||
|
wb_data
|
||
|
));
|
||
|
end
|
||
|
if (rvsoc.rvtop.swerv.dec.dec_nonblock_load_wen) begin
|
||
|
$fwrite(el, "%10d : %32s=%h ; nbL\n", cycleCnt,
|
||
|
abi_reg[rvsoc.rvtop.swerv.dec.dec_nonblock_load_waddr],
|
||
|
rvsoc.rvtop.swerv.dec.lsu_nonblock_load_data);
|
||
|
soc_sim.gpr[0][rvsoc.rvtop.swerv.dec.dec_nonblock_load_waddr] = rvsoc.rvtop.swerv.dec.lsu_nonblock_load_data;
|
||
|
end
|
||
|
if (rvsoc.rvtop.swerv.dec.exu_div_wren) begin
|
||
|
$fwrite(el, "%10d : %32s=%h ; nbD\n", cycleCnt,
|
||
|
abi_reg[rvsoc.rvtop.swerv.dec.div_waddr_wb],
|
||
|
rvsoc.rvtop.swerv.dec.exu_div_result);
|
||
|
soc_sim.gpr[0][rvsoc.rvtop.swerv.dec.div_waddr_wb] = rvsoc.rvtop.swerv.dec.exu_div_result;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
reg [7:0] hex[(1<<rvsoc.imem.MEM_DEPTH)-1:0];
|
||
|
|
||
|
initial begin
|
||
|
abi_reg[0] = "zero";
|
||
|
abi_reg[1] = "ra";
|
||
|
abi_reg[2] = "sp";
|
||
|
abi_reg[3] = "gp";
|
||
|
abi_reg[4] = "tp";
|
||
|
abi_reg[5] = "t0";
|
||
|
abi_reg[6] = "t1";
|
||
|
abi_reg[7] = "t2";
|
||
|
abi_reg[8] = "s0";
|
||
|
abi_reg[9] = "s1";
|
||
|
abi_reg[10] = "a0";
|
||
|
abi_reg[11] = "a1";
|
||
|
abi_reg[12] = "a2";
|
||
|
abi_reg[13] = "a3";
|
||
|
abi_reg[14] = "a4";
|
||
|
abi_reg[15] = "a5";
|
||
|
abi_reg[16] = "a6";
|
||
|
abi_reg[17] = "a7";
|
||
|
abi_reg[18] = "s2";
|
||
|
abi_reg[19] = "s3";
|
||
|
abi_reg[20] = "s4";
|
||
|
abi_reg[21] = "s5";
|
||
|
abi_reg[22] = "s6";
|
||
|
abi_reg[23] = "s7";
|
||
|
abi_reg[24] = "s8";
|
||
|
abi_reg[25] = "s9";
|
||
|
abi_reg[26] = "s10";
|
||
|
abi_reg[27] = "s11";
|
||
|
abi_reg[28] = "t3";
|
||
|
abi_reg[29] = "t4";
|
||
|
abi_reg[30] = "t5";
|
||
|
abi_reg[31] = "t6";
|
||
|
|
||
|
tp = $fopen("trace_port.csv", "w");
|
||
|
el = $fopen("exec.log", "w");
|
||
|
$fwrite(el, "//Cycle : #inst 0 pc opcode reg regnum value\n");
|
||
|
fd = $fopen("console.log", "w");
|
||
|
commit_count = 0;
|
||
|
|
||
|
$readmemh("program.hex", hex);
|
||
|
for (
|
||
|
reg [rvsoc.imem.MEM_DEPTH-1:0] i = 0; i < (1 << (rvsoc.imem.MEM_DEPTH - 3)); i++
|
||
|
) begin
|
||
|
rvsoc.imem.mem0[i] = hex[(i << 3) + 0];
|
||
|
rvsoc.imem.mem1[i] = hex[(i << 3) + 1];
|
||
|
rvsoc.imem.mem2[i] = hex[(i << 3) + 2];
|
||
|
rvsoc.imem.mem3[i] = hex[(i << 3) + 3];
|
||
|
rvsoc.imem.mem4[i] = hex[(i << 3) + 4];
|
||
|
rvsoc.imem.mem5[i] = hex[(i << 3) + 5];
|
||
|
rvsoc.imem.mem6[i] = hex[(i << 3) + 6];
|
||
|
rvsoc.imem.mem7[i] = hex[(i << 3) + 7];
|
||
|
end
|
||
|
for (
|
||
|
reg [rvsoc.lmem.MEM_DEPTH-1:0] i = 0; i < (1 << (rvsoc.lmem.MEM_DEPTH - 3)); i++
|
||
|
) begin
|
||
|
rvsoc.lmem.mem0[i] = hex[(i << 3) + 0];
|
||
|
rvsoc.lmem.mem1[i] = hex[(i << 3) + 1];
|
||
|
rvsoc.lmem.mem2[i] = hex[(i << 3) + 2];
|
||
|
rvsoc.lmem.mem3[i] = hex[(i << 3) + 3];
|
||
|
rvsoc.lmem.mem4[i] = hex[(i << 3) + 4];
|
||
|
rvsoc.lmem.mem5[i] = hex[(i << 3) + 5];
|
||
|
rvsoc.lmem.mem6[i] = hex[(i << 3) + 6];
|
||
|
rvsoc.lmem.mem7[i] = hex[(i << 3) + 7];
|
||
|
end
|
||
|
end
|
||
|
|
||
|
assign rst_l = cycleCnt > 20;
|
||
|
assign dbg_rst_l = cycleCnt > 10;
|
||
|
|
||
|
soc_top rvsoc (
|
||
|
.clk (core_clk),
|
||
|
.rst (rst_l),
|
||
|
.dbg_rst(dbg_rst_l),
|
||
|
|
||
|
.jtag_tdo (jtag_tdo),
|
||
|
.jtag_tck (jtag_tck),
|
||
|
.jtag_tms (jtag_tms),
|
||
|
.jtag_tdi (jtag_tdi),
|
||
|
.jtag_trst_n(jtag_trst_n)
|
||
|
);
|
||
|
|
||
|
jtagdpi jtagdpi (
|
||
|
.clk_i (core_clk),
|
||
|
.rst_ni(rst_l),
|
||
|
|
||
|
.jtag_tck (jtag_tck),
|
||
|
.jtag_tms (jtag_tms),
|
||
|
.jtag_tdi (jtag_tdi),
|
||
|
.jtag_tdo (jtag_tdo),
|
||
|
.jtag_trst_n(jtag_trst_n),
|
||
|
.jtag_srst_n()
|
||
|
);
|
||
|
|
||
|
`define DRAM(bank) \
|
||
|
rvsoc.rvtop.mem.Gen_dccm_enable.dccm.mem_bank[bank].dccm_bank.ram_core
|
||
|
|
||
|
`define ICCM_PATH `RV_TOP.mem.iccm
|
||
|
`define IRAM0(bk) `ICCM_PATH.mem_bank[bk].iccm_bank_lo0.ram_core
|
||
|
`define IRAM1(bk) `ICCM_PATH.mem_bank[bk].iccm_bank_lo1.ram_core
|
||
|
`define IRAM2(bk) `ICCM_PATH.mem_bank[bk].iccm_bank_hi0.ram_core
|
||
|
`define IRAM3(bk) `ICCM_PATH.mem_bank[bk].iccm_bank_hi1.ram_core
|
||
|
|
||
|
endmodule
|