MIPS/resources/2021/soc_axi_func/testbench/mycpu_tb.v

273 lines
9.1 KiB
Coq
Raw Normal View History

2021-05-22 19:41:47 +08:00
/*------------------------------------------------------------------------------
--------------------------------------------------------------------------------
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