blob: cfae22c1a65bbdd150de46215f7284bbcc1431cd [file] [log] [blame]
// SPDX-FileCopyrightText: Copyright 2020 Jecel Mattos de Assumpcao Jr
//
// SPDX-License-Identifier: Apache-2.0
//
// 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
//
// https://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.
// This tests the user_proj_example in Caravel with the version that has
// a single 16x16 yblock attached to the logic analyzer pins.
// This reads a file with test vectors and it applies it to the device under
// test (DUT) and checks that the output is expected. Only the wires and
// outputs of the device are used, not the internal signals. This allows
// these to be regression tests that do not depend on internal changes to
// the DUT.
// this circuit was derived from the one described in
// https://syssec.ethz.ch/content/dam/ethz/special-interest/infk/inst-infsec/system-security-group-dam/education/Digitaltechnik_14/14_Verilog_Testbenches.pdf
`timescale 1ns/1ps
`include "../rtl/defines.v"
`include "../morphle/ycell.v"
`include "../morphle/yblock.v"
`include "../morphle/user_proj_block.v"
module test005upblock;
reg [51:0] tvout;
reg [47:0] xtvin;
integer r, c; // for printing rows and columns
reg[31:0] vectornum, errors; // bookkeeping variables
reg[99:0] testvectors[10000:0];// array of testvectors/
reg clk; // DUT is asynchronous, but the test circuit can't be
// generate clock
always // no sensitivity list, so it always executes
begin
clk= 0; #50; clk= 1; #50;// 100ns period
end
wire vdda1 = 1'b1; // User area 1 3.3V supply
wire vdda2 = 1'b1; // User area 2 3.3V supply
wire vssa1 = 1'b0; // User area 1 analog ground
wire vssa2 = 1'b0; // User area 2 analog ground
wire vccd1 = 1'b1; // User area 1 1.8V supply
wire vccd2 = 1'b1; // User area 2 1.8v supply
wire vssd1 = 1'b0; // User area 1 digital ground
wire vssd2 = 1'b0; // User area 2 digital ground
// Wishbone Slave ports (WB MI A)
wire wb_clk_i = clk;
wire wb_rst_i = tvout[97];
wire wbs_stb_i = 1'b0;
wire wbs_cyc_i = 1'b0;
wire wbs_we_i = 1'b0;
wire [3:0] wbs_sel_i = {4{1'b0}};
wire [31:0] wbs_dat_i = {32{1'b0}};
wire [31:0] wbs_adr_i = {32{1'b0}};
wire wbs_ack_o;
wire [31:0] wbs_dat_o;
// Logic Analyzer Signals
wire [127:0] la_data_in = {{12{1'b0}},tvout,{64{1'b0}}};
wire [127:0] la_data_out;
wire [127:0] la_oen;
// IOs
wire [37:0] io_in = {38{1'b0}};
wire [37:0] io_out;
wire [37:0] io_oeb;
user_proj_example DUT (
.vdda1(vdda1), // User area 1 3.3V supply
.vdda2(vdda2), // User area 2 3.3V supply
.vssa1(vssa1), // User area 1 analog ground
.vssa2(vssa2), // User area 2 analog ground
.vccd1(vccd1), // User area 1 1.8V supply
.vccd2(vccd2), // User area 2 1.8v supply
.vssd1(vssd1), // User area 1 digital ground
.vssd2(vssd2), // User area 2 digital ground
// Wishbone Slave ports (WB MI A)
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
.wbs_stb_i(wbs_stb_i),
.wbs_cyc_i(wbs_cyc_i),
.wbs_we_i(wbs_we_i),
.wbs_sel_i(wbs_sel_i),
.wbs_dat_i(wbs_dat_i),
.wbs_adr_i(wbs_adr_i),
.wbs_ack_o(wbs_ack_o),
.wbs_dat_o(wbs_dat_o),
// Logic Analyzer Signals
.la_data_in(la_data_in),
.la_data_out(la_data_out),
.la_oen(la_oen),
// IOs
.io_in(io_in),
.io_out(io_out),
.io_oeb(io_oeb)
);
wire reset = la_data_in[113];
wire [2:0] cfg [0:15][0:15];
initial
begin
$dumpfile("test005.vcd");
$dumpvars;
$readmemh("test005.tv", testvectors); // Read vectors
vectornum= 0; errors = 0; // Initialize
end
// apply test vectors on rising edge of clk
always @(posedge clk)
begin
#1; {tvout,xtvin} = testvectors[vectornum][99:0];
if (xtvin === 48'bx)
begin
$display("%d tests completed with %d errors", vectornum-1, errors);
$finish; // End simulation
end
end
//outside generate row and col must be constant, so this handles that limitation
genvar row, col;
generate
for (row = 0; row < 16; row = row + 1) begin : vertical
for (col = 0; col < 16; col = col + 1) begin : horizontal
assign cfg[row][col] = DUT.blk.column[col].row[row].yc.cfg.cnfg;
end
end
endgenerate
// check results on falling edge of clk
always @(negedge clk)
begin
$display("testing vector %d", vectornum);
if ((!tvout[51] & la_data_out[47:0] !== xtvin[47:0]))
begin
$display("Error: sent = %b %b %h %h",
la_data_in[113], la_data_in[112], la_data_in[111:96], la_data_in[95:64]);
$display(" outputs = %h %h (%h %h exp)",
la_data_out[47:32], la_data_out[31:0],
xtvin[47:32], xtvin[31:0]);
errors = errors + 1;
end
if (tvout[50]) // set this bit to pretty print cells
begin
for (r = 0; r < 8; r = r + 1) begin // top to bottom
for (c = 15; c >= 0; c = c - 1) begin // left to right
$write(" %b%b %b%b ", DUT.blk.vs[r][1+2*c], DUT.blk.vs[r][2*c],
DUT.blk.vb[r][1+2*c], DUT.blk.vb[r][2*c]);
end
$display(" ");
for (c = 15; c >= 0; c = c - 1) begin // left to right
$write(" +--%b--+", DUT.blk.ve2[r][c]);
end
$display(" ");
for (c = 15; c >= 0; c = c - 1) begin // left to right
$write("%b%b| |", DUT.blk.hb[c+1][1+2*r], DUT.blk.hb[c+1][2*r]);
end
$display(" ");
for (c = 15; c >= 0; c = c - 1) begin // left to right
$write(" %b ", DUT.blk.he[c][r]);
if (cfg[r][c] == 3'b000) $write(".");
else if (cfg[r][c] == 3'b001) $write("+");
else if (cfg[r][c] == 3'b010) $write("-");
else if (cfg[r][c] == 3'b011) $write("|");
else if (cfg[r][c] == 3'b100) $write("1");
else if (cfg[r][c] == 3'b101) $write("0");
else if (cfg[r][c] == 3'b110) $write("Y");
else if (cfg[r][c] == 3'b111) $write("N");
else $write("?");
$write(" %b", DUT.blk.he[c][r]);
end
$display(" ");
for (c = 15; c >= 0; c = c - 1) begin // left to right
$write("%b%b| |", DUT.blk.hs[c+1][1+2*r], DUT.blk.hs[c+1][2*r]);
end
$display(" ");
for (c = 15; c >= 0; c = c - 1) begin // left to right
$write(" +--%b--+", DUT.blk.ve[r+1][c]);
end
$display(" ");
end
end
// increment array index and read next testvector
vectornum= vectornum + 1;
end
endmodule