abstractaccelerator/opene906/smart_run/logical/tb/tb.v

447 lines
11 KiB
Verilog

/*Copyright 2020-2021 T-Head Semiconductor Co., Ltd.
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.
*/
`define E906
`define SOC_TOP tb.x_soc
`define RTL_MEM tb.x_soc.x_smem_ctrl
`define ISA_MEM tb.x_pa_isa
`define JTAG_5
`define IAHB_LITE
`ifdef IAHB_LITE
`define RTL_IAHBL_MEM tb.x_soc.x_cpu_sub_system_ahb.x_iahb_mem_ctrl
`else
`define RTL_IAHBL_MEM tb.x_soc.x_imem_ctrl
`endif
`define DAHB_LITE
`ifdef DAHB_LITE
`define RTL_DAHBL_MEM tb.x_soc.x_cpu_sub_system_ahb.x_dahb_mem_ctrl
`else
`define RTL_DAHBL_MEM tb.x_soc.x_dmem_ctrl
`endif
//clock period
`define CLK_PERIOD 10
`define TCLK_PERIOD 33
`define MAX_RUN_TIME 700000000
`define clk tb.clk
`define rst_b tb.rst_b
// `include "../cpu/environment.h"
`timescale 1ns/100ps
module tb();
reg clk;
reg jclk;
reg rst_b;
reg jrst_b;
reg nrst_b;
reg jtap_en;
//wire jtag2_sel;
wire jtg_tms;
wire jtg_tdi;
wire jtg_tdo;
wire uart0_sin;
wire [7:0]b_pad_gpio_porta;
static integer FILE;
//Clock Generator
initial
begin
clk =0;
forever begin
#(`CLK_PERIOD/2) clk = ~clk;
end
end
initial
begin
jclk = 0;
forever begin
#(`TCLK_PERIOD/2) jclk = ~jclk;
end
end
//Reset Generater
initial
begin
rst_b = 1;
#100;
rst_b = 0;
#100;
rst_b = 1;
end
initial
begin
jrst_b = 1;
#100;
jrst_b = 0;
#100;
jrst_b = 1;
end
initial
begin
nrst_b = 1;
#100;
nrst_b = 0;
#100;
nrst_b = 1;
end
///////////////////////////////////////
// Memory Initialization
///////////////////////////////////////
integer i;
reg [31:0] mem_data_size;
reg [31:0] mem_inst_size;
reg [31:0] mem_inst_temp [65536];
reg [31:0] mem_data_temp [65536];
initial
begin
$display("\t******START TO LOAD PROGRAM******\n");
$readmemh("./case.pat", mem_inst_temp);
$readmemh("./data.pat", mem_data_temp);
for(i=0;i<65536;i=i+1)
begin
`RTL_IAHBL_MEM.ram0.mem[i][7:0] = ((^mem_inst_temp[i][31:24]) === 1'bx ) ? 8'b0:mem_inst_temp[i][31:24];
`RTL_IAHBL_MEM.ram1.mem[i][7:0] = ((^mem_inst_temp[i][23:16]) === 1'bx ) ? 8'b0:mem_inst_temp[i][23:16];
`RTL_IAHBL_MEM.ram2.mem[i][7:0] = ((^mem_inst_temp[i][15: 8]) === 1'bx ) ? 8'b0:mem_inst_temp[i][15: 8];
`RTL_IAHBL_MEM.ram3.mem[i][7:0] = ((^mem_inst_temp[i][ 7: 0]) === 1'bx ) ? 8'b0:mem_inst_temp[i][ 7: 0];
end
for(i=0;i<=65536;i=i+1)
begin
`RTL_DAHBL_MEM.ram0.mem[i][7:0] = 8'b0;
`RTL_DAHBL_MEM.ram1.mem[i][7:0] = 8'b0;
`RTL_DAHBL_MEM.ram2.mem[i][7:0] = 8'b0;
`RTL_DAHBL_MEM.ram3.mem[i][7:0] = 8'b0;
end
for(i=0;i<=65536;i=i+1)
begin
`RTL_DAHBL_MEM.ram4.mem[i][7:0] = 8'b0;
`RTL_DAHBL_MEM.ram5.mem[i][7:0] = 8'b0;
`RTL_DAHBL_MEM.ram6.mem[i][7:0] = 8'b0;
`RTL_DAHBL_MEM.ram7.mem[i][7:0] = 8'b0;
end
end
///////////////////////////////////////
// Finish Condition Control
///////////////////////////////////////
// Reaching the max simulation time.
reg [31:0] ins_counter;
initial
begin
#`MAX_RUN_TIME;
$display("**********************************************");
$display("* meeting max simulation time, stop! *");
$display("**********************************************");
FILE = $fopen("run_case.report","w");
$fdisplay(FILE,"TEST FAIL");
$finish;
end
// No instrunction retired in the last `LAST_CYCLE cycles
reg [31:0] retire_inst_in_period;
reg [31:0] cycle_count;
`define LAST_CYCLE 5000
always @(posedge clk or negedge rst_b)
begin
if(!rst_b)
cycle_count[31:0] <= 32'b1;
else
cycle_count[31:0] <= cycle_count[31:0] + 1'b1;
end
always @(posedge clk or negedge rst_b)
begin
if(!rst_b) //reset to zero
retire_inst_in_period[31:0] <= 32'b0;
else if( (cycle_count[31:0] % `LAST_CYCLE) == 0)//check and reset retire_inst_in_period every 50000 cycles
begin
if(retire_inst_in_period[31:0] == 0)begin
$display("*************************************************************");
$display("* Error: There is no instructions retired in the last %d cycles! *", `LAST_CYCLE);
$display("* Simulation Fail and Finished! *");
$display("*************************************************************");
#10;
FILE = $fopen("run_case.report","w");
$fdisplay(FILE,"TEST FAIL");
$finish;
end
retire_inst_in_period[31:0] <= 32'b0;
end
else if(tb.x_soc.x_cpu_sub_system_ahb.biu_pad_retire)
retire_inst_in_period[31:0] <= retire_inst_in_period[31:0] + 1'b1;
end
//Finish control with address 32'h0
reg [31:0] cpu_addr;
reg [1:0] cpu_trans;
reg cpu_write;
wire [31:0] cpu_wdata;
always @(posedge clk)
begin
cpu_trans[1:0] <= `SOC_TOP.biu_pad_htrans[1:0];
cpu_addr[31:0] <= `SOC_TOP.biu_pad_haddr[31:0];
cpu_write <= `SOC_TOP.biu_pad_hwrite;
end
assign cpu_wdata[31:0] = `SOC_TOP.biu_pad_hwdata[31:0];
always @(posedge clk)
begin
if((cpu_trans[1:0] == 2'b10) &&
(cpu_addr[31:0] == 32'h6000fff8) &&
cpu_write &&
(cpu_wdata[31:0] == 12'hfff || cpu_wdata[31:0] == 32'hffff0000))
begin
$display("\n**********************************************");
$display("* simulation finished successfully *");
$display("**********************************************");
#10;
FILE = $fopen("run_case.report","w");
$fdisplay(FILE,"TEST PASS");
$finish;
end
else if((cpu_trans[1:0] == 2'b10) &&
(cpu_addr[31:0] == 32'h6000fff8) &&
cpu_write &&
(cpu_wdata[31:0] == 12'heee || cpu_wdata[31:0] == 32'heeee0000))
begin
$display("**********************************************");
$display("* simulation finished with error *");
$display("**********************************************");
#10;
FILE = $fopen("run_case.report","w");
$fdisplay(FILE,"TEST FAIL");
$finish;
end
else if((cpu_trans[1:0] == 2'b10) &&
(cpu_addr[31:0] == 32'h6000fff8) &&
cpu_write)
begin
// $write("begin to display:");
$write("%c", cpu_wdata[7:0]);
end
end
//Dumping Control
`ifndef NO_DUMP
initial
begin
`ifdef NC_SIM
$dumpfile("test.vcd");
$dumpvars;
`else
`ifdef IVERILOG_SIM
$dumpfile("test.vcd");
$dumpvars;
`else
$fsdbDumpvars();
`endif
`endif
end
`endif
//Monitor
`ifndef NO_MONITOR
mnt x_mnt();
`endif
uart_mnt x_uart_mnt();
assign jtg_tdi = 1'b0;
assign uart0_sin = 1'b1;
//instantiate soc
soc x_soc(
.i_pad_clk ( clk ),
.i_pad_uart0_sin ( uart0_sin ),
.o_pad_uart0_sout ( uart0_sout ),
.i_pad_jtg_tclk ( jclk ),
.i_pad_jtg_trst_b ( jrst_b ),
.i_pad_jtg_nrst_b ( nrst_b ),
.b_pad_gpio_porta ( b_pad_gpio_porta ),
`ifdef JTAG_5
.i_pad_jtg_tdi ( jtg_tdi ),
.o_pad_jtg_tdo ( jtg_tdo ),
`endif
.i_pad_jtg_tms ( jtg_tms ),
`ifdef RST_ACTIVE_HIGH
.i_pad_rst ( !rst_b )
`else
.i_pad_rst_b ( rst_b )
`endif
);
`ifdef PG_SIM
`define MAX_ARCH_STRLEN 100
function supply_on;
//input string pad_name;
input [8*`MAX_ARCH_STRLEN : 1] pad_name;
input real value;
begin
supply_on = $mvsim_supply_on(pad_name, value);
end
endfunction
function supply_off;
//input string pad_name;
input [8*`MAX_ARCH_STRLEN : 1] pad_name;
begin
supply_off = $mvsim_supply_off(pad_name);
end
endfunction
real sp_on_vdd;
real sp_on_vss;
initial
begin
sp_on_vdd = supply_on("VDD", 1.2);
sp_on_vss = supply_on("VSS", 0);
// #1000
// force tb.x_soc.pad_cpu_rst_b = 1'b0;
// #20
// force tb.x_soc.x_cpu_sub_system_ahb.x_ck803s.pmu_corec_isolation = 1'b1;
// #20
// force tb.x_soc.x_cpu_sub_system_ahb.x_ck803s.pmu_corec_sleep_in = 1'b1;
//
// #500
//
// release tb.x_soc.x_cpu_sub_system_ahb.x_ck803s.pmu_corec_sleep_in ;
// #20
// release tb.x_soc.x_cpu_sub_system_ahb.x_ck803s.pmu_corec_isolation;
// #20
// release tb.x_soc.pad_cpu_rst_b ;
end
initial
begin
$deposit(tb.x_soc.x_cpu_sub_system_ahb.pmu_corec_sleep_in, 1'b0);
$deposit(tb.x_soc.x_cpu_sub_system_ahb.pmu_corec_isolation, 1'b0);
$deposit(tb.x_soc.x_cpu_sub_system_ahb.corec_pmu_sleep_out, 1'b0);
end
`endif
`ifdef E902
`define CPU_TOP tb.x_soc.x_cpu_sub_system_ahb.x_e902
`elsif E906
`define CPU_TOP tb.x_soc.x_cpu_sub_system_ahb.x_e906_top
`else
`define CPU_TOP tb.x_soc.x_cpu_sub_system_ahb.x_ck803s
`endif
`define CPU_CLK `CPU_TOP.pll_core_cpuclk
`define CPU_RST `CPU_TOP.pad_cpu_rst_b
`ifdef E902
`define VIRTUAL_READ `CPU_TOP.x_cr_tcipif_top.x_cr_tcipif_dbus.dummy_addr_cmplt
`elsif E906
`define VIRTUAL_READ `CPU_TOP.x_pa_tcipif_top.x_pa_tcipif_dbus.dummy_addr_cmplt
`else
`define VIRTUAL_READ `CPU_TOP.x_vg_tcip_top.x_nm_tcipif_dbus.dummy_addr_cmplt
`endif
`ifdef E902
`define VIRTUAL_TIME `CPU_TOP.x_cr_tcipif_top.x_cr_tcipif_dbus.tcipif_rd_data[31:0]
`elsif E906
`define VIRTUAL_TIME `CPU_TOP.x_pa_tcipif_top.x_pa_tcipif_dbus.tcipif_bmu_dbus_data[31:0]
`else
`define VIRTUAL_TIME `CPU_TOP.x_vg_tcip_top.x_nm_tcipif_dbus.tcipif_dbus_rd_data[31:0]
`endif
reg [31:0] virtual_counter;
always @(posedge `CPU_CLK or negedge `CPU_RST)
begin
if(!`CPU_RST)
virtual_counter[31:0] <= 32'b0;
else if(virtual_counter[31:0]==32'hffffffff)
virtual_counter[31:0] <= virtual_counter[31:0];
else
virtual_counter[31:0] <= virtual_counter[31:0] +1'b1;
end
initial
begin
#1;
wait (`VIRTUAL_READ==1'b1);
force `VIRTUAL_TIME = virtual_counter[31:0];
@(posedge `CPU_CLK);
release `VIRTUAL_TIME;
#1;
wait (`VIRTUAL_READ==1'b1);
force `VIRTUAL_TIME = virtual_counter[31:0];
@(posedge `CPU_CLK);
release `VIRTUAL_TIME;
#1;
wait (`VIRTUAL_READ==1'b1);
force `VIRTUAL_TIME = virtual_counter[31:0];
@(posedge `CPU_CLK);
release `VIRTUAL_TIME;
#1;
wait (`VIRTUAL_READ==1'b1);
force `VIRTUAL_TIME = virtual_counter[31:0];
@(posedge `CPU_CLK);
release `VIRTUAL_TIME;
#1;
wait (`VIRTUAL_READ==1'b1);
force `VIRTUAL_TIME = virtual_counter[31:0];
@(posedge `CPU_CLK);
release `VIRTUAL_TIME;
#1;
wait (`VIRTUAL_READ==1'b1);
force `VIRTUAL_TIME = virtual_counter[31:0];
@(posedge `CPU_CLK);
release `VIRTUAL_TIME;
#1;
end
// count instruction number
always @(posedge `CPU_CLK or negedge `CPU_RST)
begin
if(!`CPU_RST)
ins_counter[31:0] <= 32'b0;
else if(`SOC_TOP.x_cpu_sub_system_ahb.biu_pad_retire &&
(`SOC_TOP.x_cpu_sub_system_ahb.biu_pad_retire_pc[31:0] > 32'had4))
ins_counter[31:0] <= ins_counter[31:0] + 1'b1;
else
ins_counter[31:0] <= ins_counter[31:0];
end
endmodule