273 lines
9.1 KiB
Verilog
273 lines
9.1 KiB
Verilog
/*------------------------------------------------------------------------------
|
|
--------------------------------------------------------------------------------
|
|
Copyright (c) 2016, Loongson Technology Corporation Limited.
|
|
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without modification,
|
|
are permitted provided that the following conditions are met:
|
|
|
|
1. Redistributions of source code must retain the above copyright notice, this
|
|
list of conditions and the following disclaimer.
|
|
|
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
this list of conditions and the following disclaimer in the documentation and/or
|
|
other materials provided with the distribution.
|
|
|
|
3. Neither the name of Loongson Technology Corporation Limited nor the names of
|
|
its contributors may be used to endorse or promote products derived from this
|
|
software without specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
DISCLAIMED. IN NO EVENT SHALL LOONGSON TECHNOLOGY CORPORATION LIMITED BE LIABLE
|
|
TO ANY PARTY FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
|
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
--------------------------------------------------------------------------------
|
|
------------------------------------------------------------------------------*/
|
|
`timescale 1ns / 1ps
|
|
|
|
`define TRACE_REF_FILE "../../../../../../../cpu132_gettrace/golden_trace.txt"
|
|
`define CONFREG_NUM_REG soc_lite.u_confreg.num_data
|
|
`define CONFREG_OPEN_TRACE soc_lite.u_confreg.open_trace
|
|
`define CONFREG_NUM_MONITOR soc_lite.u_confreg.num_monitor
|
|
`define CONFREG_UART_DISPLAY soc_lite.u_confreg.write_uart_valid
|
|
`define CONFREG_UART_DATA soc_lite.u_confreg.write_uart_data
|
|
`define END_PC 32'hbfc00100
|
|
|
|
module tb_top( );
|
|
reg resetn;
|
|
reg clk;
|
|
|
|
//goio
|
|
wire [15:0] led;
|
|
wire [1 :0] led_rg0;
|
|
wire [1 :0] led_rg1;
|
|
wire [7 :0] num_csn;
|
|
wire [6 :0] num_a_g;
|
|
wire [7 :0] switch;
|
|
wire [3 :0] btn_key_col;
|
|
wire [3 :0] btn_key_row;
|
|
wire [1 :0] btn_step;
|
|
assign switch = 8'hff;
|
|
assign btn_key_row = 4'd0;
|
|
assign btn_step = 2'd3;
|
|
|
|
initial
|
|
begin
|
|
clk = 1'b0;
|
|
resetn = 1'b0;
|
|
#2000;
|
|
resetn = 1'b1;
|
|
end
|
|
always #5 clk=~clk;
|
|
soc_axi_lite_top #(.SIMULATION(1'b1)) soc_lite
|
|
(
|
|
.resetn (resetn ),
|
|
.clk (clk ),
|
|
|
|
//------gpio-------
|
|
.num_csn (num_csn ),
|
|
.num_a_g (num_a_g ),
|
|
.led (led ),
|
|
.led_rg0 (led_rg0 ),
|
|
.led_rg1 (led_rg1 ),
|
|
.switch (switch ),
|
|
.btn_key_col(btn_key_col),
|
|
.btn_key_row(btn_key_row),
|
|
.btn_step (btn_step )
|
|
);
|
|
|
|
//"cpu_clk" means cpu core clk
|
|
//"sys_clk" means system clk
|
|
//"wb" means write-back stage in pipeline
|
|
//"rf" means regfiles in cpu
|
|
//"w" in "wen/wnum/wdata" means writing
|
|
wire cpu_clk;
|
|
wire sys_clk;
|
|
wire [31:0] debug_wb_pc;
|
|
wire [3 :0] debug_wb_rf_wen;
|
|
wire [4 :0] debug_wb_rf_wnum;
|
|
wire [31:0] debug_wb_rf_wdata;
|
|
assign cpu_clk = soc_lite.cpu_clk;
|
|
assign sys_clk = soc_lite.sys_clk;
|
|
assign debug_wb_pc = soc_lite.debug_wb_pc;
|
|
assign debug_wb_rf_wen = soc_lite.debug_wb_rf_wen;
|
|
assign debug_wb_rf_wnum = soc_lite.debug_wb_rf_wnum;
|
|
assign debug_wb_rf_wdata = soc_lite.debug_wb_rf_wdata;
|
|
|
|
// open the trace file;
|
|
integer trace_ref;
|
|
initial begin
|
|
trace_ref = $fopen(`TRACE_REF_FILE, "r");
|
|
end
|
|
|
|
//get reference result in falling edge
|
|
reg trace_cmp_flag;
|
|
reg debug_end;
|
|
|
|
reg [31:0] ref_wb_pc;
|
|
reg [4 :0] ref_wb_rf_wnum;
|
|
reg [31:0] ref_wb_rf_wdata;
|
|
|
|
always @(posedge cpu_clk)
|
|
begin
|
|
#1;
|
|
if(|debug_wb_rf_wen && debug_wb_rf_wnum!=5'd0 && !debug_end && `CONFREG_OPEN_TRACE)
|
|
begin
|
|
trace_cmp_flag=1'b0;
|
|
while (!trace_cmp_flag && !($feof(trace_ref)))
|
|
begin
|
|
$fscanf(trace_ref, "%h %h %h %h", trace_cmp_flag,
|
|
ref_wb_pc, ref_wb_rf_wnum, ref_wb_rf_wdata);
|
|
end
|
|
end
|
|
end
|
|
|
|
//wdata[i*8+7 : i*8] is valid, only wehile wen[i] is valid
|
|
wire [31:0] debug_wb_rf_wdata_v;
|
|
wire [31:0] ref_wb_rf_wdata_v;
|
|
assign debug_wb_rf_wdata_v[31:24] = debug_wb_rf_wdata[31:24] & {8{debug_wb_rf_wen[3]}};
|
|
assign debug_wb_rf_wdata_v[23:16] = debug_wb_rf_wdata[23:16] & {8{debug_wb_rf_wen[2]}};
|
|
assign debug_wb_rf_wdata_v[15: 8] = debug_wb_rf_wdata[15: 8] & {8{debug_wb_rf_wen[1]}};
|
|
assign debug_wb_rf_wdata_v[7 : 0] = debug_wb_rf_wdata[7 : 0] & {8{debug_wb_rf_wen[0]}};
|
|
assign ref_wb_rf_wdata_v[31:24] = ref_wb_rf_wdata[31:24] & {8{debug_wb_rf_wen[3]}};
|
|
assign ref_wb_rf_wdata_v[23:16] = ref_wb_rf_wdata[23:16] & {8{debug_wb_rf_wen[2]}};
|
|
assign ref_wb_rf_wdata_v[15: 8] = ref_wb_rf_wdata[15: 8] & {8{debug_wb_rf_wen[1]}};
|
|
assign ref_wb_rf_wdata_v[7 : 0] = ref_wb_rf_wdata[7 : 0] & {8{debug_wb_rf_wen[0]}};
|
|
|
|
|
|
//compare result in rsing edge
|
|
reg debug_wb_err;
|
|
always @(posedge cpu_clk)
|
|
begin
|
|
#2;
|
|
if(!resetn)
|
|
begin
|
|
debug_wb_err <= 1'b0;
|
|
end
|
|
else if(|debug_wb_rf_wen && debug_wb_rf_wnum!=5'd0 && !debug_end && `CONFREG_OPEN_TRACE)
|
|
begin
|
|
if ( (debug_wb_pc!==ref_wb_pc) || (debug_wb_rf_wnum!==ref_wb_rf_wnum)
|
|
||(debug_wb_rf_wdata_v!==ref_wb_rf_wdata_v) )
|
|
begin
|
|
$display("--------------------------------------------------------------");
|
|
$display("[%t] Error!!!",$time);
|
|
$display(" reference: PC = 0x%8h, wb_rf_wnum = 0x%2h, wb_rf_wdata = 0x%8h",
|
|
ref_wb_pc, ref_wb_rf_wnum, ref_wb_rf_wdata_v);
|
|
$display(" mycpu : PC = 0x%8h, wb_rf_wnum = 0x%2h, wb_rf_wdata = 0x%8h",
|
|
debug_wb_pc, debug_wb_rf_wnum, debug_wb_rf_wdata_v);
|
|
$display("--------------------------------------------------------------");
|
|
debug_wb_err <= 1'b1;
|
|
#40;
|
|
$finish;
|
|
end
|
|
end
|
|
end
|
|
|
|
//monitor numeric display
|
|
reg [7:0] err_count;
|
|
wire [31:0] confreg_num_reg = `CONFREG_NUM_REG;
|
|
reg [31:0] confreg_num_reg_r;
|
|
always @(posedge sys_clk)
|
|
begin
|
|
confreg_num_reg_r <= confreg_num_reg;
|
|
if (!resetn)
|
|
begin
|
|
err_count <= 8'd0;
|
|
end
|
|
else if (confreg_num_reg_r != confreg_num_reg && `CONFREG_NUM_MONITOR)
|
|
begin
|
|
if(confreg_num_reg[7:0]!=confreg_num_reg_r[7:0]+1'b1)
|
|
begin
|
|
$display("--------------------------------------------------------------");
|
|
$display("[%t] Error(%d)!!! Occurred in number 8'd%02d Functional Test Point!",$time, err_count, confreg_num_reg[31:24]);
|
|
$display("--------------------------------------------------------------");
|
|
err_count <= err_count + 1'b1;
|
|
end
|
|
else if(confreg_num_reg[31:24]!=confreg_num_reg_r[31:24]+1'b1)
|
|
begin
|
|
$display("--------------------------------------------------------------");
|
|
$display("[%t] Error(%d)!!! Unknown, Functional Test Point numbers are unequal!",$time,err_count);
|
|
$display("--------------------------------------------------------------");
|
|
$display("==============================================================");
|
|
err_count <= err_count + 1'b1;
|
|
end
|
|
else
|
|
begin
|
|
$display("----[%t] Number 8'd%02d Functional Test Point PASS!!!", $time, confreg_num_reg[31:24]);
|
|
end
|
|
end
|
|
end
|
|
|
|
//monitor test
|
|
initial
|
|
begin
|
|
$timeformat(-9,0," ns",10);
|
|
while(!resetn) #5;
|
|
$display("==============================================================");
|
|
$display("Test begin!");
|
|
|
|
#10000;
|
|
while(`CONFREG_NUM_MONITOR)
|
|
begin
|
|
#10000;
|
|
$display (" [%t] Test is running, debug_wb_pc = 0x%8h",$time, debug_wb_pc);
|
|
end
|
|
end
|
|
|
|
//模拟串口打印
|
|
wire uart_display;
|
|
wire [7:0] uart_data;
|
|
assign uart_display = `CONFREG_UART_DISPLAY;
|
|
assign uart_data = `CONFREG_UART_DATA;
|
|
|
|
always @(posedge sys_clk)
|
|
begin
|
|
if(uart_display)
|
|
begin
|
|
if(uart_data==8'hff)
|
|
begin
|
|
;//$finish;
|
|
end
|
|
else
|
|
begin
|
|
$write("%c",uart_data);
|
|
end
|
|
end
|
|
end
|
|
|
|
//test end
|
|
wire global_err = debug_wb_err || (err_count!=8'd0);
|
|
wire test_end = (debug_wb_pc==`END_PC) || (uart_display && uart_data==8'hff);
|
|
always @(posedge cpu_clk)
|
|
begin
|
|
if (!resetn)
|
|
begin
|
|
debug_end <= 1'b0;
|
|
end
|
|
else if(test_end && !debug_end)
|
|
begin
|
|
debug_end <= 1'b1;
|
|
$display("==============================================================");
|
|
$display("Test end!");
|
|
#40;
|
|
$fclose(trace_ref);
|
|
if (global_err)
|
|
begin
|
|
$display("Fail!!!Total %d errors!",err_count);
|
|
end
|
|
else
|
|
begin
|
|
$display("----PASS!!!");
|
|
end
|
|
$finish;
|
|
end
|
|
end
|
|
endmodule
|