Folder rename

This commit is contained in:
Mikhail Yenuchenko
2026-01-20 17:48:32 +03:00
parent 306061a76d
commit 23e0e58f8b
57 changed files with 37 additions and 37 deletions

View File

@@ -0,0 +1,601 @@
/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
/// @file <scr1_memory_tb_ahb.sv>
/// @brief AHB memory testbench
///
`include "scr1_arch_description.svh"
`include "scr1_ahb.svh"
`include "scr1_ipic.svh"
module scr1_memory_tb_ahb #(
parameter SCR1_MEM_POWER_SIZE = 16
)
(
// Control
input logic rst_n,
input logic clk,
`ifdef SCR1_IPIC_EN
output logic [SCR1_IRQ_LINES_NUM-1:0] irq_lines,
`else // SCR1_IPIC_EN
output logic ext_irq,
`endif // SCR1_IPIC_EN
output logic soft_irq,
input integer imem_req_ack_stall_in,
input integer dmem_req_ack_stall_in,
// Instruction Memory Interface
// input logic [3:0] imem_hprot,
// input logic [2:0] imem_hburst,
input logic [2:0] imem_hsize,
input logic [1:0] imem_htrans,
input logic [SCR1_AHB_WIDTH-1:0] imem_haddr,
output logic imem_hready,
output logic [SCR1_AHB_WIDTH-1:0] imem_hrdata,
output logic imem_hresp,
// Memory Interface
// input logic [3:0] dmem_hprot,
// input logic [2:0] dmem_hburst,
input logic [2:0] dmem_hsize,
input logic [1:0] dmem_htrans,
input logic [SCR1_AHB_WIDTH-1:0] dmem_haddr,
input logic dmem_hwrite,
input logic [SCR1_AHB_WIDTH-1:0] dmem_hwdata,
output logic dmem_hready,
output logic [SCR1_AHB_WIDTH-1:0] dmem_hrdata,
output logic dmem_hresp
);
//-------------------------------------------------------------------------------
// Local Types
//-------------------------------------------------------------------------------
typedef enum logic {
SCR1_AHB_STATE_IDLE = 1'b0,
SCR1_AHB_STATE_DATA = 1'b1,
SCR1_AHB_STATE_ERR = 1'bx
} type_scr1_ahb_state_e;
//-------------------------------------------------------------------------------
// Memory definition
//-------------------------------------------------------------------------------
logic [7:0] memory [0:2**SCR1_MEM_POWER_SIZE-1];
`ifdef SCR1_IPIC_EN
logic [SCR1_IRQ_LINES_NUM-1:0] irq_lines_reg;
`else // SCR1_IPIC_EN
logic ext_irq_reg;
`endif // SCR1_IPIC_EN
logic soft_irq_reg;
logic [7:0] mirage [0:2**SCR1_MEM_POWER_SIZE-1];
bit mirage_en;
bit mirage_rangeen;
bit [SCR1_AHB_WIDTH-1:0] mirage_adrlo = '1;
bit [SCR1_AHB_WIDTH-1:0] mirage_adrhi = '1;
`ifdef VERILATOR
logic [255:0] test_file;
`else // VERILATOR
string test_file;
`endif // VERILATOR
bit test_file_init;
//-------------------------------------------------------------------------------
// Local functions
//-------------------------------------------------------------------------------
function logic [SCR1_AHB_WIDTH-1:0] scr1_read_mem(
logic [SCR1_AHB_WIDTH-1:0] addr,
logic [3:0] r_be,
logic [3:0] w_hazard,
logic [SCR1_AHB_WIDTH-1:0] w_data,
bit mirage_en
);
logic [SCR1_AHB_WIDTH-1:0] tmp;
logic [SCR1_MEM_POWER_SIZE-1:0] addr_mirage;
begin
scr1_read_mem = 'x;
if(~mirage_en) begin
for (int unsigned i=0; i<4; ++i) begin
tmp[(8*(i+1)-1)-:8] = (r_be[i])
? (w_hazard[i])
? w_data[(8*(i+1)-1)-:8]
: memory[addr+i]
: 'x;
end
end
else begin
addr_mirage = addr;
for (int i = 0; i < 4; ++i) begin
tmp[ (i*8)+:8 ] = (r_be[i])
? (w_hazard[i])
? w_data[(i*8)+:8]
: mirage[addr_mirage+i]
: 'x;
end
end
return tmp;
end
endfunction : scr1_read_mem
function void scr1_write_mem(
logic [SCR1_AHB_WIDTH-1:0] addr,
logic [3:0] w_be,
logic [SCR1_AHB_WIDTH-1:0] data,
bit mirage_en
);
logic [SCR1_MEM_POWER_SIZE-1:0] addr_mirage;
begin
for (int unsigned i=0; i<4; ++i) begin
if (w_be[i]) begin
if(~mirage_en)
memory[addr+i] <= data[(8*(i+1)-1)-:8];
else begin
addr_mirage = addr;
mirage[addr_mirage+i] <= data[(8*(i+1)-1)-:8];
end
end
end
end
endfunction : scr1_write_mem
function logic [3:0] scr1_be_form(
input logic [1:0] offset,
input logic [1:0] hsize
);
logic [3:0] tmp;
begin
case (hsize)
SCR1_HSIZE_8B : begin
tmp = 4'b0001 << offset;
end
SCR1_HSIZE_16B : begin
tmp = 4'b0011 << offset;
end
SCR1_HSIZE_32B : begin
tmp = 4'b1111;
end
endcase
return tmp;
end
endfunction : scr1_be_form
//-------------------------------------------------------------------------------
// Local signal declaration
//-------------------------------------------------------------------------------
// IMEM access
type_scr1_ahb_state_e imem_ahb_state;
logic [SCR1_AHB_WIDTH-1:0] imem_ahb_addr;
logic [SCR1_AHB_WIDTH-1:0] imem_req_ack_stall;
bit imem_req_ack_rnd;
logic imem_req_ack;
logic imem_req_ack_nc;
logic [3:0] imem_be;
logic [SCR1_AHB_WIDTH-1:0] imem_hrdata_l;
logic [3:0] imem_wr_hazard;
// DMEM access
logic [SCR1_AHB_WIDTH-1:0] dmem_req_ack_stall;
bit dmem_req_ack_rnd;
logic dmem_req_ack;
logic dmem_req_ack_nc;
logic [3:0] dmem_be;
type_scr1_ahb_state_e dmem_ahb_state;
logic [SCR1_AHB_WIDTH-1:0] dmem_ahb_addr;
logic dmem_ahb_wr;
logic [2:0] dmem_ahb_size;
logic [3:0] dmem_ahb_be;
logic [SCR1_AHB_WIDTH-1:0] dmem_hrdata_l;
logic [3:0] dmem_wr_hazard;
//-------------------------------------------------------------------------------
// Instruction memory ready
//-------------------------------------------------------------------------------
always_ff @(negedge rst_n, posedge clk) begin
if (~rst_n) begin
imem_req_ack_stall <= imem_req_ack_stall_in;
imem_req_ack_rnd <= 1'b0;
end else begin
if (imem_req_ack_stall == '0) begin
imem_req_ack_rnd <= $random;
end else begin
imem_req_ack_stall <= ((imem_ahb_state == SCR1_AHB_STATE_DATA) | ~imem_req_ack_stall[0]) ? {imem_req_ack_stall[0], imem_req_ack_stall[31:1]} : imem_req_ack_stall;
end
end
end
assign imem_req_ack = (imem_req_ack_stall == 32'd0) ? imem_req_ack_rnd : imem_req_ack_stall[0];
//-------------------------------------------------------------------------------
// Instruction memory AHB FSM
//-------------------------------------------------------------------------------
always_ff @(negedge rst_n, posedge clk) begin
if (~rst_n) begin
imem_ahb_state <= SCR1_AHB_STATE_IDLE;
end else begin
case (imem_ahb_state)
SCR1_AHB_STATE_IDLE : begin
// if (imem_req_ack) begin
case (imem_htrans)
SCR1_HTRANS_IDLE : begin
imem_ahb_state <= SCR1_AHB_STATE_IDLE;
end
SCR1_HTRANS_NONSEQ : begin
imem_ahb_state <= SCR1_AHB_STATE_DATA;
end
default : begin
imem_ahb_state <= SCR1_AHB_STATE_ERR;
end
endcase
// end
end
SCR1_AHB_STATE_DATA : begin
if (imem_req_ack) begin
case (imem_htrans)
SCR1_HTRANS_IDLE : begin
imem_ahb_state <= SCR1_AHB_STATE_IDLE;
end
SCR1_HTRANS_NONSEQ : begin
imem_ahb_state <= SCR1_AHB_STATE_DATA;
end
default : begin
imem_ahb_state <= SCR1_AHB_STATE_ERR;
end
endcase
end
end
default : begin
imem_ahb_state <= SCR1_AHB_STATE_ERR;
end
endcase
end
end
//-------------------------------------------------------------------------------
// Address data generation
//-------------------------------------------------------------------------------
assign imem_be = scr1_be_form(2'b00, imem_hsize);
assign imem_wr_hazard = (dmem_ahb_wr & (imem_haddr[SCR1_AHB_WIDTH-1:2] == dmem_ahb_addr[SCR1_AHB_WIDTH-1:2])) ? imem_be & dmem_ahb_be : '0;
always_ff @(negedge rst_n, posedge clk) begin
if (~rst_n) begin
imem_ahb_addr <= 'x;
imem_hrdata_l <= 'x;
end else begin
case (imem_ahb_state)
SCR1_AHB_STATE_IDLE : begin
// if (imem_req_ack) begin
case (imem_htrans)
SCR1_HTRANS_IDLE : begin
end
SCR1_HTRANS_NONSEQ : begin
imem_ahb_addr <= imem_haddr;
if(mirage_rangeen & imem_haddr>=mirage_adrlo & imem_haddr<mirage_adrhi)
imem_hrdata_l <= scr1_read_mem({imem_haddr[SCR1_AHB_WIDTH-1:2], 2'b00}, imem_be, imem_wr_hazard, dmem_hwdata, 1'b1);
else
imem_hrdata_l <= scr1_read_mem({imem_haddr[SCR1_AHB_WIDTH-1:2], 2'b00}, imem_be, imem_wr_hazard, dmem_hwdata, 1'b0);
end
default : begin
imem_ahb_addr <= 'x;
imem_hrdata_l <= 'x;
end
endcase
// end
end
SCR1_AHB_STATE_DATA : begin
if (imem_req_ack) begin
case (imem_htrans)
SCR1_HTRANS_IDLE : begin
imem_ahb_addr <= 'x;
imem_hrdata_l <= 'x;
end
SCR1_HTRANS_NONSEQ : begin
imem_ahb_addr <= imem_haddr;
if(mirage_rangeen & imem_haddr>=mirage_adrlo & imem_haddr<mirage_adrhi)
imem_hrdata_l <= scr1_read_mem({imem_haddr[SCR1_AHB_WIDTH-1:2], 2'b00}, imem_be, imem_wr_hazard, dmem_hwdata, 1'b1);
else
imem_hrdata_l <= scr1_read_mem({imem_haddr[SCR1_AHB_WIDTH-1:2], 2'b00}, imem_be, imem_wr_hazard, dmem_hwdata, 1'b0);
end
default : begin
imem_ahb_addr <= 'x;
imem_hrdata_l <= 'x;
end
endcase
end
end
default : begin
imem_ahb_addr <= 'x;
imem_hrdata_l <= 'x;
end
endcase
end
end
//-------------------------------------------------------------------------------
// Instruction Memory response
//-------------------------------------------------------------------------------
always_comb begin
imem_hready = 1'b1;
imem_hresp = SCR1_HRESP_OKAY;
imem_hrdata = 'x;
case (imem_ahb_state)
SCR1_AHB_STATE_IDLE : begin
end
SCR1_AHB_STATE_DATA : begin
if (imem_req_ack) begin
imem_hready = 1'b1;
imem_hresp = SCR1_HRESP_OKAY;
imem_hrdata = imem_hrdata_l;
end
end
default : begin
end
endcase
end
//-------------------------------------------------------------------------------
// Data memory ready
//-------------------------------------------------------------------------------
always_ff @(negedge rst_n, posedge clk) begin
if (~rst_n) begin
dmem_req_ack_stall <= dmem_req_ack_stall_in;
dmem_req_ack_rnd <= 1'b0;
end else begin
if (dmem_req_ack_stall == 32'd0) begin
dmem_req_ack_rnd <= $random;
end else begin
dmem_req_ack_stall <= ((dmem_ahb_state == SCR1_AHB_STATE_DATA) | ~dmem_req_ack_stall[0]) ? {dmem_req_ack_stall[0], dmem_req_ack_stall[31:1]} : dmem_req_ack_stall;
end
end
end
assign dmem_req_ack = (dmem_req_ack_stall == 32'd0) ? dmem_req_ack_rnd : dmem_req_ack_stall[0];
//-------------------------------------------------------------------------------
// Data memory AHB FSM
//-------------------------------------------------------------------------------
always_ff @(negedge rst_n, posedge clk) begin
if (~rst_n) begin
dmem_ahb_state <= SCR1_AHB_STATE_IDLE;
end else begin
case (dmem_ahb_state)
SCR1_AHB_STATE_IDLE : begin
// if (dmem_req_ack) begin
case (dmem_htrans)
SCR1_HTRANS_IDLE : begin
dmem_ahb_state <= SCR1_AHB_STATE_IDLE;
end
SCR1_HTRANS_NONSEQ : begin
dmem_ahb_state <= SCR1_AHB_STATE_DATA;
end
default : begin
dmem_ahb_state <= SCR1_AHB_STATE_ERR;
end
endcase
// end
end
SCR1_AHB_STATE_DATA : begin
if (dmem_req_ack) begin
case (dmem_htrans)
SCR1_HTRANS_IDLE : begin
dmem_ahb_state <= SCR1_AHB_STATE_IDLE;
end
SCR1_HTRANS_NONSEQ : begin
if (~dmem_hwrite) begin
case (dmem_haddr)
SCR1_SIM_SOFT_IRQ_ADDR,
SCR1_SIM_EXT_IRQ_ADDR
: begin
// Skip access, switch to SCR1_AHB_STATE_IDLE
dmem_ahb_state <= SCR1_AHB_STATE_IDLE;
end
default : begin
dmem_ahb_state <= SCR1_AHB_STATE_DATA;
end
endcase
end
end
default : begin
dmem_ahb_state <= SCR1_AHB_STATE_ERR;
end
endcase
end
end
default : begin
dmem_ahb_state <= SCR1_AHB_STATE_ERR;
end
endcase
end
end
//-------------------------------------------------------------------------------
// Address command latch
//-------------------------------------------------------------------------------
assign dmem_be = scr1_be_form(dmem_haddr[1:0], dmem_hsize);
assign dmem_wr_hazard = (dmem_ahb_wr & (dmem_haddr[SCR1_AHB_WIDTH-1:2] == dmem_ahb_addr[SCR1_AHB_WIDTH-1:2])) ? dmem_be & dmem_ahb_be : '0;
always_ff @(negedge rst_n, posedge clk) begin
if (~rst_n) begin
dmem_ahb_addr <= 'x;
dmem_ahb_wr <= 1'b0;
dmem_ahb_size <= SCR1_HSIZE_ERR;
dmem_ahb_be <= '0;
end else begin
case (dmem_ahb_state)
SCR1_AHB_STATE_IDLE : begin
// if (dmem_req_ack) begin
case (dmem_htrans)
SCR1_HTRANS_IDLE : begin
end
SCR1_HTRANS_NONSEQ : begin
dmem_ahb_addr <= dmem_haddr;
dmem_ahb_wr <= dmem_hwrite;
dmem_ahb_size <= dmem_hsize;
dmem_ahb_be <= dmem_be;
if (~dmem_hwrite) begin
case (dmem_haddr)
// Reading Soft IRQ value
SCR1_SIM_SOFT_IRQ_ADDR : begin
dmem_hrdata_l <= '0;
dmem_hrdata_l[0] <= soft_irq_reg;
end
`ifdef SCR1_IPIC_EN
// Reading IRQ Lines values
SCR1_SIM_EXT_IRQ_ADDR : begin
dmem_hrdata_l <= '0;
dmem_hrdata_l[SCR1_IRQ_LINES_NUM-1:0] <= irq_lines_reg;
end
`else // SCR1_IPIC_EN
// Reading External IRQ value
SCR1_SIM_EXT_IRQ_ADDR : begin
dmem_hrdata_l <= '0;
dmem_hrdata_l[0] <= ext_irq_reg;
end
`endif // SCR1_IPIC_EN
// Regular read operation
default : begin
if(mirage_rangeen & dmem_haddr>=mirage_adrlo & dmem_haddr<mirage_adrhi)
dmem_hrdata_l <= scr1_read_mem({dmem_haddr[SCR1_AHB_WIDTH-1:2], 2'b00}, dmem_be, dmem_wr_hazard, dmem_hwdata, 1'b1);
else
dmem_hrdata_l <= scr1_read_mem({dmem_haddr[SCR1_AHB_WIDTH-1:2], 2'b00}, dmem_be, dmem_wr_hazard, dmem_hwdata, 1'b0);
end
endcase
end
end
default : begin
dmem_ahb_addr <= 'x;
dmem_ahb_wr <= 'x;
dmem_ahb_size <= SCR1_HSIZE_ERR;
dmem_hrdata_l <= 'x;
end
endcase
// end
end
SCR1_AHB_STATE_DATA : begin
if (dmem_req_ack) begin
case (dmem_htrans)
SCR1_HTRANS_IDLE : begin
dmem_ahb_addr <= 'x;
dmem_ahb_wr <= 1'b0;
dmem_ahb_size <= SCR1_HSIZE_ERR;
end
SCR1_HTRANS_NONSEQ : begin
dmem_ahb_addr <= dmem_haddr;
dmem_ahb_wr <= dmem_hwrite;
dmem_ahb_size <= dmem_hsize;
dmem_ahb_be <= dmem_be;
if (~dmem_hwrite) begin
case (dmem_haddr)
SCR1_SIM_SOFT_IRQ_ADDR,
SCR1_SIM_EXT_IRQ_ADDR
: begin
// Skip access, switch to SCR1_AHB_STATE_IDLE
end
default : begin
if(mirage_rangeen & dmem_haddr>=mirage_adrlo & dmem_haddr<mirage_adrhi)
dmem_hrdata_l <= scr1_read_mem({dmem_haddr[SCR1_AHB_WIDTH-1:2], 2'b00}, dmem_be, dmem_wr_hazard, dmem_hwdata, 1'b1);
else
dmem_hrdata_l <= scr1_read_mem({dmem_haddr[SCR1_AHB_WIDTH-1:2], 2'b00}, dmem_be, dmem_wr_hazard, dmem_hwdata, 1'b0);
end
endcase
end
end
default : begin
dmem_ahb_addr <= 'x;
dmem_ahb_wr <= 'x;
dmem_ahb_size <= SCR1_HSIZE_ERR;
dmem_ahb_be <= 'x;
dmem_hrdata_l <= 'x;
end
endcase
end
end
default : begin
dmem_ahb_addr <= 'x;
dmem_ahb_wr <= 'x;
dmem_ahb_size <= SCR1_HSIZE_ERR;
dmem_hrdata_l <= 'x;
end
endcase
end
end
//-------------------------------------------------------------------------------
// Data Memory response
//-------------------------------------------------------------------------------
always_comb begin
dmem_hready = 1'b0;
dmem_hresp = SCR1_HRESP_ERROR;
dmem_hrdata = 'x;
case (dmem_ahb_state)
SCR1_AHB_STATE_IDLE : begin
if (dmem_req_ack) begin
dmem_hready = 1'b1;
end
end
SCR1_AHB_STATE_DATA : begin
if (dmem_req_ack) begin
dmem_hready = 1'b1;
dmem_hresp = SCR1_HRESP_OKAY;
if (~dmem_ahb_wr) begin
dmem_hrdata = dmem_hrdata_l;
end
end
end
default : begin
end
endcase
end
//-------------------------------------------------------------------------------
// Data Memory write
//-------------------------------------------------------------------------------
always @(negedge rst_n, posedge clk) begin
if (~rst_n) begin
soft_irq_reg <= '0;
`ifdef SCR1_IPIC_EN
irq_lines_reg <= '0;
`else // SCR1_IPIC_EN
ext_irq_reg <= '0;
`endif // SCR1_IPIC_EN
if (test_file_init) $readmemh(test_file, memory);
end else begin
if ((dmem_ahb_state == SCR1_AHB_STATE_DATA) & dmem_req_ack & dmem_ahb_wr) begin
case (dmem_ahb_addr)
// Printing character in the simulation console
SCR1_SIM_PRINT_ADDR : begin
$write("%c", dmem_hwdata[7:0]);
end
// Writing Soft IRQ value
SCR1_SIM_SOFT_IRQ_ADDR : begin
soft_irq_reg <= dmem_hwdata[0];
end
`ifdef SCR1_IPIC_EN
// Writing IRQ Lines values
SCR1_SIM_EXT_IRQ_ADDR : begin
irq_lines_reg <= dmem_hwdata[SCR1_IRQ_LINES_NUM-1:0];
end
`else // SCR1_IPIC_EN
// Writing External IRQ value
SCR1_SIM_EXT_IRQ_ADDR : begin
ext_irq_reg <= dmem_hwdata[0];
end
`endif // SCR1_IPIC_EN
// Regular write operation
default : begin
if(mirage_rangeen & dmem_ahb_addr>=mirage_adrlo & dmem_ahb_addr<mirage_adrhi)
scr1_write_mem({dmem_ahb_addr[SCR1_AHB_WIDTH-1:2], 2'b00}, dmem_ahb_be, dmem_hwdata, 1'b1);
else
scr1_write_mem({dmem_ahb_addr[SCR1_AHB_WIDTH-1:2], 2'b00}, dmem_ahb_be, dmem_hwdata, 1'b0);
end
endcase
end
end
end
`ifdef SCR1_IPIC_EN
assign irq_lines = irq_lines_reg;
`else // SCR1_IPIC_EN
assign ext_irq = ext_irq_reg;
`endif // SCR1_IPIC_EN
assign soft_irq = soft_irq_reg;
endmodule : scr1_memory_tb_ahb

View File

@@ -0,0 +1,393 @@
/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
/// @file <scr1_memory_tb_axi.sv>
/// @brief AXI memory testbench
///
`include "scr1_arch_description.svh"
`include "scr1_ipic.svh"
module scr1_memory_tb_axi #(
parameter SIZE = 1*1024*1024,
parameter N_IF = 2,
parameter W_ID = 4,
parameter W_ADR = 32,
parameter W_DATA = 32
)
(
// System
input logic rst_n,
input logic clk,
`ifdef SCR1_IPIC_EN
output logic [SCR1_IRQ_LINES_NUM-1:0] irq_lines,
`else // SCR1_IPIC_EN
output logic ext_irq,
`endif // SCR1_IPIC_EN
output logic soft_irq,
// Write address channel
input logic [N_IF-1:0] awvalid,
input logic [N_IF-1:0] [W_ID-1:0] awid,
input logic [N_IF-1:0] [W_ADR-1:0] awaddr,
input logic [N_IF-1:0] [2:0] awsize,
input logic [N_IF-1:0] [7:0] awlen,
output logic [N_IF-1:0] awready,
// Write data channel
input logic [N_IF-1:0] wvalid,
input logic [N_IF-1:0] [W_DATA-1:0] wdata,
input logic [N_IF-1:0] [W_DATA/8-1:0] wstrb,
input logic [N_IF-1:0] wlast,
output logic [N_IF-1:0] wready,
// Write response channel
input logic [N_IF-1:0] bready,
output logic [N_IF-1:0] bvalid,
output logic [N_IF-1:0] [W_ID-1:0] bid,
output logic [N_IF-1:0] [1:0] bresp,
// Read address channel
input logic [N_IF-1:0] arvalid,
input logic [N_IF-1:0] [W_ID-1:0] arid,
input logic [N_IF-1:0] [W_ADR-1:0] araddr,
input logic [N_IF-1:0] [1:0] arburst,
input logic [N_IF-1:0] [2:0] arsize,
input logic [N_IF-1:0] [7:0] arlen,
output logic [N_IF-1:0] arready,
// Read data channel
input logic [N_IF-1:0] rready,
output logic [N_IF-1:0] rvalid,
output logic [N_IF-1:0] [W_ID-1:0] rid,
output logic [N_IF-1:0] [W_DATA-1:0] rdata,
output logic [N_IF-1:0] rlast,
output logic [N_IF-1:0] [1:0] rresp
);
//-------------------------------------------------------------------------------
// Local signal declaration
//-------------------------------------------------------------------------------
logic [7:0] memory [0:SIZE-1];
logic [N_IF-1:0] [W_ADR-1:0] awaddr_hold;
logic [N_IF-1:0] [2:0] awsize_hold;
genvar gi;
genvar gj;
`ifdef SCR1_IPIC_EN
logic [SCR1_IRQ_LINES_NUM-1:0] irq_lines_reg;
`else // SCR1_IPIC_EN
logic ext_irq_reg;
`endif // SCR1_IPIC_EN
logic soft_irq_reg;
`ifdef VERILATOR
logic [255:0] test_file;
`else // VERILATOR
string test_file;
`endif // VERILATOR
bit test_file_init;
//-------------------------------------------------------------------------------
// Local functions
//-------------------------------------------------------------------------------
function automatic logic [W_DATA-1:0] mem_read (
logic [W_ADR:0] adr, // starting address of READ burst operation
int bytes_num, // number of bytes to read
int bytes_max // number of bytes in data width
);
logic [W_ADR:0] byte_lane; // positional number of byte to read
mem_read = 'x;
byte_lane = 0;
// Storing the positional number of byte to read
for(int i=0; i<$clog2(bytes_max); ++i) begin
byte_lane[i] = adr[i];
end
// READ burst operation
for(int i=byte_lane; i<bytes_max & bytes_num!=0; ++i) begin
// Reading Soft IRQ value
if (adr[W_ADR-1:1] == SCR1_SIM_SOFT_IRQ_ADDR[W_ADR-1:1]) begin
mem_read[0] = soft_irq_reg;
`ifdef SCR1_IPIC_EN
// Reading IRQ Lines values
end else if (adr[W_ADR-1:1] == SCR1_SIM_EXT_IRQ_ADDR[W_ADR-1:1]) begin
if (i*8 < SCR1_IRQ_LINES_NUM) begin
if (SCR1_IRQ_LINES_NUM < 8) begin
mem_read[(i*8)+:8] = irq_lines_reg;
end else begin
mem_read[(i*8)+:8] = irq_lines_reg[(i*8)+:8];
end
end
`else // SCR1_IPIC_EN
// Reading External IRQ value
end else if (adr[W_ADR-1:1] == SCR1_SIM_EXT_IRQ_ADDR[W_ADR-1:1]) begin
mem_read[0] = ext_irq_reg;
`endif // SCR1_IPIC_EN
// Regular read operation
end else begin
mem_read[(i*8)+:8] = memory[adr];
end
adr = adr+1'b1;
bytes_num = bytes_num - 1'b1;
end
endfunction : mem_read
function automatic void mem_write (
logic [W_ADR-1:0] adr, // starting address of WRITE burst operation
logic [W_DATA-1:0] data, // data to write
logic [(W_DATA/8)-1:0] bytes_en, // bytes write strobes
int bytes_num, // number of bytes to write
int bytes_max // number of bytes in data width
);
logic[W_ADR:0] byte_lane; // positional number of byte to write
byte_lane = 0;
// Storing the positional number of byte to write
for(int i=0; i<$clog2(bytes_max); ++i) begin
byte_lane[i] = adr[i];
end
// WRITE burst operation
for(int i=byte_lane; i<bytes_max & bytes_num!=0; ++i) begin
// Printing character in the simulation console
if(bytes_en[i] & adr == SCR1_SIM_PRINT_ADDR) begin
$write("%c",data[(i*8)+:8]);
// Writing Soft IRQ value
end else if(bytes_en[0] & adr[W_ADR-1:1] == SCR1_SIM_SOFT_IRQ_ADDR[W_ADR-1:1]) begin
soft_irq_reg <= data[0];
`ifdef SCR1_IPIC_EN
// Writing IRQ Lines values
end else if(bytes_en[i] & adr[W_ADR-1:1] == SCR1_SIM_EXT_IRQ_ADDR[W_ADR-1:1]) begin
if( i*8 < SCR1_IRQ_LINES_NUM ) begin
if( SCR1_IRQ_LINES_NUM < 8 ) begin
irq_lines_reg <= data[SCR1_IRQ_LINES_NUM-1:0];
end else begin
irq_lines_reg[(i*8)+:8] <= data[(i*8)+:8];
end
end
`else
// Writing External IRQ value
end else if(bytes_en[0] & adr[W_ADR-1:1] == SCR1_SIM_EXT_IRQ_ADDR[W_ADR-1:1]) begin
ext_irq_reg <= data[0];
`endif // SCR1_IPIC_EN
// Regular write operation
end else if (bytes_en[i]) begin
memory[adr] = data[(i*8)+:8];
end
adr = adr+1'b1;
bytes_num = bytes_num-1'b1;
end
endfunction : mem_write
`ifdef SCR1_IPIC_EN
assign irq_lines = irq_lines_reg;
`else // SCR1_IPIC_EN
assign ext_irq = ext_irq_reg;
`endif // SCR1_IPIC_EN
assign soft_irq = soft_irq_reg;
generate for(gi=0; gi<N_IF; ++gi) begin : rw_if
//-------------------------------------------------------------------------------
// Read operation
//-------------------------------------------------------------------------------
always @(posedge clk, negedge rst_n) begin
if(~rst_n) begin
arready[gi] <= 1'b1;
rvalid[gi] <= 1'b0;
rresp[gi] <= 2'd3;
rdata[gi] <= 'x;
rlast[gi] <= 1'b0;
rid[gi] <= '0;
end else begin
// Read data: acked
if( rvalid[gi] & rready[gi] ) begin
arready[gi] <= 1'b1;
rvalid[gi] <= 1'b0;
end else if( rvalid[gi] & !rready[gi] ) begin
arready[gi] <= 1'b0;
end
// Read data: valid
if( arvalid[gi] & arready[gi] & ~(rvalid[gi] & !rready[gi]) ) begin
rvalid[gi] <= 1'b1;
rresp[gi] <= '0;
rlast[gi] <= 1'b1;
rid[gi] <= arid[gi];
rdata[gi] <= mem_read( araddr[gi],
2**arsize[gi],
W_DATA/8 );
end
end
end
//-------------------------------------------------------------------------------
// Write operation
//-------------------------------------------------------------------------------
always @(posedge clk, negedge rst_n) begin
if (~rst_n) begin
bvalid[gi] <= '0;
bresp[gi] <= 2'd3;
awready[gi] <= 1'b1;
wready[gi] <= 1'b1;
soft_irq_reg <= '0;
`ifdef SCR1_IPIC_EN
irq_lines_reg <= '0;
`else // SCR1_IPIC_EN
ext_irq_reg <= '0;
`endif // SCR1_IPIC_EN
if (test_file_init) $readmemh(test_file, memory);
end else begin
// Write data: response
if( bvalid[gi] & bready[gi] ) begin
bvalid[gi] <= 1'b0;
awready[gi] <= 1'b1;
wready[gi] <= 1'b1;
end else if( bvalid[gi] & !bready[gi] ) begin
awready[gi] <= 1'b0;
wready[gi] <= 1'b0;
end
// Write data: get address
if( awvalid[gi] & awready[gi] & ~(bvalid[gi] & !bready[gi]) ) begin
bid <= awid[gi];
if( ~wvalid[gi] ) begin
awaddr_hold[gi] <= awaddr[gi];
awsize_hold[gi] <= awsize[gi];
awready[gi] <= 1'b0;
end
end
// Write data: get data
if( wvalid[gi] & wready[gi] & wlast[gi] ) begin
bvalid[gi] <= 1'b1;
bresp[gi] <= '0;
mem_write( awready[gi] ? awaddr[gi] : awaddr_hold[gi],
wdata[gi],
wstrb[gi],
2**(awready[gi] ? awsize[gi] : awsize_hold[gi]),
W_DATA/8 );
end
end
end
//`ifndef VERILATOR
//-------------------------------------------------------------------------------
// Assertions
//-------------------------------------------------------------------------------
SVA_TBMEM_AWADDR_404 :
assert property (
@(negedge clk) disable iff (~rst_n)
awvalid[gi] |-> awaddr[gi]<SIZE | awaddr[gi]==SCR1_SIM_PRINT_ADDR
| awaddr[gi]==SCR1_SIM_SOFT_IRQ_ADDR
| awaddr[gi]==SCR1_SIM_EXT_IRQ_ADDR
)
else $error("TBMEM: awaddr[%0d] >= SIZE",gi);
SVA_TBMEM_X_AWVALID :
assert property (
@(negedge clk) disable iff (~rst_n)
!$isunknown(awvalid[gi])
)
else $error("TBMEM: X state on awvalid[%0d]",gi);
SVA_TBMEM_X_AWCHANNEL :
assert property (
@(negedge clk) disable iff (~rst_n)
awvalid[gi] |-> !$isunknown({awid[gi],awaddr[gi],awsize[gi],awlen[gi]})
)
else $error("TBMEM: X state on aw channel[%0d]",gi);
SVA_TBMEM_AWLEN :
assert property (
@(negedge clk) disable iff (~rst_n)
awvalid[gi] |-> awlen[gi]==0
)
else $error("TBMEM: awlen[%0d] = %0d is not supported",gi,awlen[gi]);
SVA_TBMEM_X_WVALID :
assert property (
@(negedge clk) disable iff (~rst_n)
!$isunknown(wvalid[gi])
)
else $error("TBMEM: X state on wvalid[%0d]",gi);
SVA_TBMEM_X_WCHANNEL :
assert property (
@(negedge clk) disable iff (~rst_n)
wvalid[gi] |-> !$isunknown({wstrb[gi],wlast[gi]})
)
else $error("TBMEM: X state on w channel[%0d]",gi);
for(gj=0; gj<W_DATA/8; ++gj) begin : SVA_TBMEM_X_WSTRB
WDATA :
assert property (
@(negedge clk) disable iff (~rst_n)
(wvalid[gi] & wstrb[gi][gj]) |-> !$isunknown(wdata[gi][(gj*8)+:8])
)
else $error("TBMEM: X state on wdata with wstrb[%0d][%0d]",gi,gj);
end
SVA_TBMEM_X_BREADY :
assert property (
@(negedge clk) disable iff (~rst_n)
bvalid[gi] |-> !$isunknown(bready[gi])
)
else $error("TBMEM: X state on bready[%0d]",gi);
SVA_TBMEM_ARADDR_404 :
assert property (
@(negedge clk) disable iff (~rst_n)
arvalid[gi] |-> araddr[gi]<SIZE | araddr[gi]==SCR1_SIM_PRINT_ADDR
| awaddr[gi]==SCR1_SIM_SOFT_IRQ_ADDR
| awaddr[gi]==SCR1_SIM_EXT_IRQ_ADDR
)
else $error("TBMEM: awaddr[%0d] >= SIZE",gi);
SVA_TBMEM_X_ARVALID :
assert property (
@(negedge clk) disable iff (~rst_n)
!$isunknown(arvalid[gi])
)
else $error("TBMEM: X state on arvalid[%0d]",gi);
SVA_TBMEM_X_ARCHANNEL :
assert property (
@(negedge clk) disable iff (~rst_n)
arvalid[gi] |-> !$isunknown({arid[gi],araddr[gi],arsize[gi],arlen[gi]})
)
else $error("TBMEM: X state on ar channel[%0d]",gi);
SVA_TBMEM_ARLEN :
assert property (
@(negedge clk) disable iff (~rst_n)
arvalid[gi] |-> arlen[gi]==0
)
else $error("TBMEM: arlen[%0d] = %0d is not supported",gi,arlen[gi]);
SVA_TBMEM_X_RREADY :
assert property (
@(negedge clk) disable iff (~rst_n)
rvalid[gi] |-> !$isunknown(rready[gi])
)
else $error("TBMEM: X state on rready[%0d]",gi);
//`endif // VERILATOR
end endgenerate
endmodule : scr1_memory_tb_axi

View File

@@ -0,0 +1,393 @@
/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
/// @file <scr1_top_tb_ahb.sv>
/// @brief SCR1 top testbench AHB
///
`include "scr1_arch_description.svh"
`include "scr1_ahb.svh"
`ifdef SCR1_IPIC_EN
`include "scr1_ipic.svh"
`endif // SCR1_IPIC_EN
module scr1_top_tb_ahb (
`ifdef VERILATOR
input logic clk
`endif // VERILATOR
);
//-------------------------------------------------------------------------------
// Local parameters
//-------------------------------------------------------------------------------
localparam SCR1_MEM_SIZE = 1024*1024;
localparam TIMEOUT = 'd2000_000;//20ms;
localparam ARCH = 'h1;
localparam COMPLIANCE = 'h2;
localparam ADDR_START = 'h200;
localparam ADDR_TRAP_VECTOR = 'h240;
localparam ADDR_TRAP_DEFAULT = 'h1C0;
//-------------------------------------------------------------------------------
// Local signal declaration
//-------------------------------------------------------------------------------
logic rst_n;
`ifndef VERILATOR
logic clk = 1'b0;
`endif // VERILATOR
logic rtc_clk = 1'b0;
`ifdef SCR1_IPIC_EN
logic [SCR1_IRQ_LINES_NUM-1:0] irq_lines;
`else // SCR1_IPIC_EN
logic ext_irq;
`endif // SCR1_IPIC_EN
logic soft_irq;
logic [31:0] fuse_mhartid;
integer imem_req_ack_stall;
integer dmem_req_ack_stall;
logic test_mode = 1'b0;
`ifdef SCR1_DBG_EN
logic trst_n;
logic tck;
logic tms;
logic tdi;
logic tdo;
logic tdo_en;
`endif // SCR1_DBG_EN
// Instruction Memory Interface
logic [3:0] imem_hprot;
logic [2:0] imem_hburst;
logic [2:0] imem_hsize;
logic [1:0] imem_htrans;
logic [SCR1_AHB_WIDTH-1:0] imem_haddr;
logic imem_hready;
logic [SCR1_AHB_WIDTH-1:0] imem_hrdata;
logic imem_hresp;
// Memory Interface
logic [3:0] dmem_hprot;
logic [2:0] dmem_hburst;
logic [2:0] dmem_hsize;
logic [1:0] dmem_htrans;
logic [SCR1_AHB_WIDTH-1:0] dmem_haddr;
logic dmem_hwrite;
logic [SCR1_AHB_WIDTH-1:0] dmem_hwdata;
logic dmem_hready;
logic [SCR1_AHB_WIDTH-1:0] dmem_hrdata;
logic dmem_hresp;
// Wathdogs
int unsigned watchdogs_cnt;
int unsigned f_results;
int unsigned f_info;
string s_results;
string s_info;
`ifdef SIGNATURE_OUT
string s_testname;
bit b_single_run_flag;
`endif // SIGNATURE_OUT
`ifdef VERILATOR
logic [255:0] test_file;
`else // VERILATOR
string test_file;
`endif // VERILATOR
bit test_running;
int unsigned tests_passed;
int unsigned tests_total;
bit [1:0] rst_cnt;
bit rst_init;
`ifdef VERILATOR
function int identify_test (logic [255:0] testname);
bit res;
logic [79:0] pattern_compliance;
logic [22:0] pattern_arch;
begin
pattern_compliance = 80'h636f6d706c69616e6365; // compliance
pattern_arch = 'h61726368; // arch
res = 0;
for (int i = 0; i<= 176; i++) begin
if(testname[i+:80] == pattern_compliance) begin
return COMPLIANCE;
end
end
for (int i = 0; i<= 233; i++) begin
if(testname[i+:23] == pattern_arch) begin
return ARCH;
end
end
`ifdef SIGNATURE_OUT
return ~res;
`else
return res;
`endif
end
endfunction : identify_test
function logic [255:0] get_filename (logic [255:0] testname);
logic [255:0] res;
int i, j;
begin
testname[7:0] = 8'h66;
testname[15:8] = 8'h6C;
testname[23:16] = 8'h65;
for (i = 0; i <= 248; i += 8) begin
if (testname[i+:8] == 0) begin
break;
end
end
i -= 8;
for (j = 255; i >= 0;i -= 8) begin
res[j-:8] = testname[i+:8];
j -= 8;
end
for (; j >= 0;j -= 8) begin
res[j-:8] = 0;
end
return res;
end
endfunction : get_filename
function logic [255:0] get_ref_filename (logic [255:0] testname);
logic [255:0] res;
int i, j;
logic [79:0] pattern_compliance;
logic [22:0] pattern_arch;
begin
pattern_compliance = 80'h636f6d706c69616e6365; // compliance
pattern_arch = 'h61726368; // arch
for(int i = 0; i <= 176; i++) begin
if(testname[i+:80] == pattern_compliance) begin
testname[(i-8)+:88] = 0;
break;
end
end
for(int i = 0; i <= 233; i++) begin
if(testname[i+:23] == pattern_arch) begin
testname[(i-8)+:31] = 0;
break;
end
end
for(i = 32; i <= 248; i += 8) begin
if(testname[i+:8] == 0) break;
end
i -= 8;
for(j = 255; i > 24; i -= 8) begin
res[j-:8] = testname[i+:8];
j -= 8;
end
for(; j >=0;j -= 8) begin
res[j-:8] = 0;
end
return res;
end
endfunction : get_ref_filename
function logic [2047:0] remove_trailing_whitespaces (logic [2047:0] str);
int i;
begin
for (i = 0; i <= 2040; i += 8) begin
if (str[i+:8] != 8'h20) begin
break;
end
end
str = str >> i;
return str;
end
endfunction: remove_trailing_whitespaces
`else // VERILATOR
function int identify_test (string testname);
begin
if (testname.substr(0, 3) == "arch") begin
return ARCH;
end else if (testname.substr(0, 9) == "compliance") begin
return COMPLIANCE;
end else begin
return 0;
end
end
endfunction : identify_test
function string get_filename (string testname);
int length;
begin
length = testname.len();
testname[length-1] = "f";
testname[length-2] = "l";
testname[length-3] = "e";
return testname;
end
endfunction : get_filename
function string get_ref_filename (string testname);
begin
if (identify_test(test_file) == COMPLIANCE) begin
return testname.substr(11, testname.len() - 5);
end else if (identify_test(test_file) == ARCH) begin
return testname.substr(5, testname.len() - 5);
end
end
endfunction : get_ref_filename
`endif // VERILATOR
`ifndef VERILATOR
always #5 clk = ~clk; // 100 MHz
always #500 rtc_clk = ~rtc_clk; // 1 MHz
`endif // VERILATOR
// Reset logic
assign rst_n = &rst_cnt;
always_ff @(posedge clk) begin
if (rst_init) rst_cnt <= '0;
else if (~&rst_cnt) rst_cnt <= rst_cnt + 1'b1;
end
`ifdef SCR1_DBG_EN
initial begin
trst_n = 1'b0;
tck = 1'b0;
tdi = 1'b0;
#900ns trst_n = 1'b1;
#500ns tms = 1'b1;
#800ns tms = 1'b0;
#500ns trst_n = 1'b0;
#100ns tms = 1'b1;
end
`endif // SCR1_DBG_EN
//-------------------------------------------------------------------------------
// Run tests
//-------------------------------------------------------------------------------
`include "scr1_top_tb_runtests.sv"
//-------------------------------------------------------------------------------
// Core instance
//-------------------------------------------------------------------------------
scr1_top_ahb i_top (
// Reset
.pwrup_rst_n (rst_n ),
.rst_n (rst_n ),
.cpu_rst_n (rst_n ),
`ifdef SCR1_DBG_EN
.sys_rst_n_o ( ),
.sys_rdc_qlfy_o ( ),
`endif // SCR1_DBG_EN
// Clock
.clk (clk ),
.rtc_clk (rtc_clk ),
// Fuses
.fuse_mhartid (fuse_mhartid ),
`ifdef SCR1_DBG_EN
.fuse_idcode (`SCR1_TAP_IDCODE ),
`endif // SCR1_DBG_EN
// IRQ
`ifdef SCR1_IPIC_EN
.irq_lines (irq_lines ),
`else // SCR1_IPIC_EN
.ext_irq (ext_irq ),
`endif // SCR1_IPIC_EN
.soft_irq (soft_irq ),
// DFT
.test_mode (1'b0 ),
.test_rst_n (1'b1 ),
`ifdef SCR1_DBG_EN
// JTAG
.trst_n (trst_n ),
.tck (tck ),
.tms (tms ),
.tdi (tdi ),
.tdo (tdo ),
.tdo_en (tdo_en ),
`endif // SCR1_DBG_EN
// Instruction Memory Interface
.imem_hprot (imem_hprot ),
.imem_hburst (imem_hburst ),
.imem_hsize (imem_hsize ),
.imem_htrans (imem_htrans ),
.imem_hmastlock (),
.imem_haddr (imem_haddr ),
.imem_hready (imem_hready ),
.imem_hrdata (imem_hrdata ),
.imem_hresp (imem_hresp ),
// Data Memory Interface
.dmem_hprot (dmem_hprot ),
.dmem_hburst (dmem_hburst ),
.dmem_hsize (dmem_hsize ),
.dmem_htrans (dmem_htrans ),
.dmem_hmastlock (),
.dmem_haddr (dmem_haddr ),
.dmem_hwrite (dmem_hwrite ),
.dmem_hwdata (dmem_hwdata ),
.dmem_hready (dmem_hready ),
.dmem_hrdata (dmem_hrdata ),
.dmem_hresp (dmem_hresp )
);
//-------------------------------------------------------------------------------
// Memory instance
//-------------------------------------------------------------------------------
scr1_memory_tb_ahb #(
.SCR1_MEM_POWER_SIZE ($clog2(SCR1_MEM_SIZE))
) i_memory_tb (
// Control
.rst_n (rst_n),
.clk (clk),
`ifdef SCR1_IPIC_EN
.irq_lines (irq_lines),
`else // SCR1_IPIC_EN
.ext_irq (ext_irq),
`endif // SCR1_IPIC_EN
.soft_irq (soft_irq),
.imem_req_ack_stall_in (imem_req_ack_stall),
.dmem_req_ack_stall_in (dmem_req_ack_stall),
// Instruction Memory Interface
// .imem_hprot (imem_hprot ),
// .imem_hburst (imem_hburst),
.imem_hsize (imem_hsize ),
.imem_htrans (imem_htrans),
.imem_haddr (imem_haddr ),
.imem_hready (imem_hready),
.imem_hrdata (imem_hrdata),
.imem_hresp (imem_hresp ),
// Data Memory Interface
// .dmem_hprot (dmem_hprot ),
// .dmem_hburst (dmem_hburst),
.dmem_hsize (dmem_hsize ),
.dmem_htrans (dmem_htrans),
.dmem_haddr (dmem_haddr ),
.dmem_hwrite (dmem_hwrite),
.dmem_hwdata (dmem_hwdata),
.dmem_hready (dmem_hready),
.dmem_hrdata (dmem_hrdata),
.dmem_hresp (dmem_hresp )
);
endmodule : scr1_top_tb_ahb

View File

@@ -0,0 +1,544 @@
/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
/// @file <scr1_top_tb_axi.sv>
/// @brief SCR1 top testbench AXI
///
`include "scr1_arch_description.svh"
`ifdef SCR1_IPIC_EN
`include "scr1_ipic.svh"
`endif // SCR1_IPIC_EN
module scr1_top_tb_axi (
`ifdef VERILATOR
input logic clk
`endif // VERILATOR
);
//------------------------------------------------------------------------------
// Local parameters
//------------------------------------------------------------------------------
localparam SCR1_MEM_SIZE = 1024*1024;
localparam TIMEOUT = 'd2000_000;//20ms;
localparam ARCH = 'h1;
localparam COMPLIANCE = 'h2;
localparam ADDR_START = 'h200;
localparam ADDR_TRAP_VECTOR = 'h240;
localparam ADDR_TRAP_DEFAULT = 'h1C0;
//------------------------------------------------------------------------------
// Local signal declaration
//------------------------------------------------------------------------------
logic rst_n;
`ifndef VERILATOR
logic clk = 1'b0;
`endif // VERILATOR
logic rtc_clk = 1'b0;
logic [31:0] fuse_mhartid;
integer imem_req_ack_stall;
integer dmem_req_ack_stall;
`ifdef SCR1_IPIC_EN
logic [SCR1_IRQ_LINES_NUM-1:0] irq_lines;
`else // SCR1_IPIC_EN
logic ext_irq;
`endif // SCR1_IPIC_EN
logic soft_irq;
`ifdef SCR1_DBG_EN
logic trst_n;
logic tck;
logic tms;
logic tdi;
logic tdo;
logic tdo_en;
`endif // SCR1_DBG_EN
// Instruction Memory
logic [3:0] io_axi_imem_awid;
logic [31:0] io_axi_imem_awaddr;
logic [7:0] io_axi_imem_awlen;
logic [2:0] io_axi_imem_awsize;
logic [1:0] io_axi_imem_awburst;
logic io_axi_imem_awlock;
logic [3:0] io_axi_imem_awcache;
logic [2:0] io_axi_imem_awprot;
logic [3:0] io_axi_imem_awregion;
logic [3:0] io_axi_imem_awuser;
logic [3:0] io_axi_imem_awqos;
logic io_axi_imem_awvalid;
logic io_axi_imem_awready;
logic [31:0] io_axi_imem_wdata;
logic [3:0] io_axi_imem_wstrb;
logic io_axi_imem_wlast;
logic [3:0] io_axi_imem_wuser;
logic io_axi_imem_wvalid;
logic io_axi_imem_wready;
logic [3:0] io_axi_imem_bid;
logic [1:0] io_axi_imem_bresp;
logic io_axi_imem_bvalid;
logic [3:0] io_axi_imem_buser;
logic io_axi_imem_bready;
logic [3:0] io_axi_imem_arid;
logic [31:0] io_axi_imem_araddr;
logic [7:0] io_axi_imem_arlen;
logic [2:0] io_axi_imem_arsize;
logic [1:0] io_axi_imem_arburst;
logic io_axi_imem_arlock;
logic [3:0] io_axi_imem_arcache;
logic [2:0] io_axi_imem_arprot;
logic [3:0] io_axi_imem_arregion;
logic [3:0] io_axi_imem_aruser;
logic [3:0] io_axi_imem_arqos;
logic io_axi_imem_arvalid;
logic io_axi_imem_arready;
logic [3:0] io_axi_imem_rid;
logic [31:0] io_axi_imem_rdata;
logic [1:0] io_axi_imem_rresp;
logic io_axi_imem_rlast;
logic [3:0] io_axi_imem_ruser;
logic io_axi_imem_rvalid;
logic io_axi_imem_rready;
// Data Memory
logic [3:0] io_axi_dmem_awid;
logic [31:0] io_axi_dmem_awaddr;
logic [7:0] io_axi_dmem_awlen;
logic [2:0] io_axi_dmem_awsize;
logic [1:0] io_axi_dmem_awburst;
logic io_axi_dmem_awlock;
logic [3:0] io_axi_dmem_awcache;
logic [2:0] io_axi_dmem_awprot;
logic [3:0] io_axi_dmem_awregion;
logic [3:0] io_axi_dmem_awuser;
logic [3:0] io_axi_dmem_awqos;
logic io_axi_dmem_awvalid;
logic io_axi_dmem_awready;
logic [31:0] io_axi_dmem_wdata;
logic [3:0] io_axi_dmem_wstrb;
logic io_axi_dmem_wlast;
logic [3:0] io_axi_dmem_wuser;
logic io_axi_dmem_wvalid;
logic io_axi_dmem_wready;
logic [3:0] io_axi_dmem_bid;
logic [1:0] io_axi_dmem_bresp;
logic io_axi_dmem_bvalid;
logic [3:0] io_axi_dmem_buser;
logic io_axi_dmem_bready;
logic [3:0] io_axi_dmem_arid;
logic [31:0] io_axi_dmem_araddr;
logic [7:0] io_axi_dmem_arlen;
logic [2:0] io_axi_dmem_arsize;
logic [1:0] io_axi_dmem_arburst;
logic io_axi_dmem_arlock;
logic [3:0] io_axi_dmem_arcache;
logic [2:0] io_axi_dmem_arprot;
logic [3:0] io_axi_dmem_arregion;
logic [3:0] io_axi_dmem_aruser;
logic [3:0] io_axi_dmem_arqos;
logic io_axi_dmem_arvalid;
logic io_axi_dmem_arready;
logic [3:0] io_axi_dmem_rid;
logic [31:0] io_axi_dmem_rdata;
logic [1:0] io_axi_dmem_rresp;
logic io_axi_dmem_rlast;
logic [3:0] io_axi_dmem_ruser;
logic io_axi_dmem_rvalid;
logic io_axi_dmem_rready;
// Wathdogs
int unsigned watchdogs_cnt;
int unsigned f_results;
int unsigned f_info;
string s_results;
string s_info;
`ifdef SIGNATURE_OUT
string s_testname;
bit b_single_run_flag;
`endif // SIGNATURE_OUT
`ifdef VERILATOR
logic [255:0] test_file;
`else // VERILATOR
string test_file;
`endif // VERILATOR
bit test_running;
int unsigned tests_passed;
int unsigned tests_total;
bit [1:0] rst_cnt;
bit rst_init;
`ifdef VERILATOR
function int identify_test (logic [255:0] testname);
bit res;
logic [79:0] pattern_compliance;
logic [22:0] pattern_arch;
begin
pattern_compliance = 80'h636f6d706c69616e6365; // compliance
pattern_arch = 'h61726368; // arch
res = 0;
for (int i = 0; i<= 176; i++) begin
if(testname[i+:80] == pattern_compliance) begin
return COMPLIANCE;
end
end
for (int i = 0; i<= 233; i++) begin
if(testname[i+:23] == pattern_arch) begin
return ARCH;
end
end
`ifdef SIGNATURE_OUT
return ~res;
`else
return res;
`endif
end
endfunction : identify_test
function logic [255:0] get_filename (logic [255:0] testname);
logic [255:0] res;
int i, j;
begin
testname[7:0] = 8'h66;
testname[15:8] = 8'h6C;
testname[23:16] = 8'h65;
for (i = 0; i <= 248; i += 8) begin
if (testname[i+:8] == 0) begin
break;
end
end
i -= 8;
for (j = 255; i >= 0;i -= 8) begin
res[j-:8] = testname[i+:8];
j -= 8;
end
for (; j >= 0;j -= 8) begin
res[j-:8] = 0;
end
return res;
end
endfunction : get_filename
function logic [255:0] get_ref_filename (logic [255:0] testname);
logic [255:0] res;
int i, j;
logic [79:0] pattern_compliance;
logic [22:0] pattern_arch;
begin
pattern_compliance = 80'h636f6d706c69616e6365; // compliance
pattern_arch = 'h61726368; // arch
for(int i = 0; i <= 176; i++) begin
if(testname[i+:80] == pattern_compliance) begin
testname[(i-8)+:88] = 0;
break;
end
end
for(int i = 0; i <= 233; i++) begin
if(testname[i+:23] == pattern_arch) begin
testname[(i-8)+:31] = 0;
break;
end
end
for(i = 32; i <= 248; i += 8) begin
if(testname[i+:8] == 0) break;
end
i -= 8;
for(j = 255; i > 24; i -= 8) begin
res[j-:8] = testname[i+:8];
j -= 8;
end
for(; j >=0;j -= 8) begin
res[j-:8] = 0;
end
return res;
end
endfunction : get_ref_filename
function logic [2047:0] remove_trailing_whitespaces (logic [2047:0] str);
int i;
begin
for (i = 0; i <= 2040; i += 8) begin
if (str[i+:8] != 8'h20) begin
break;
end
end
str = str >> i;
return str;
end
endfunction: remove_trailing_whitespaces
`else // VERILATOR
function int identify_test (string testname);
begin
if (testname.substr(0, 3) == "arch") begin
return ARCH;
end else if (testname.substr(0, 9) == "compliance") begin
return COMPLIANCE;
end else begin
return 0;
end
end
endfunction : identify_test
function string get_filename (string testname);
int length;
begin
length = testname.len();
testname[length-1] = "f";
testname[length-2] = "l";
testname[length-3] = "e";
return testname;
end
endfunction : get_filename
function string get_ref_filename (string testname);
begin
if (identify_test(test_file) == COMPLIANCE) begin
return testname.substr(11, testname.len() - 5);
end else if (identify_test(test_file) == ARCH) begin
return testname.substr(5, testname.len() - 5);
end
end
endfunction : get_ref_filename
`endif // VERILATOR
`ifndef VERILATOR
always #5 clk = ~clk; // 100 MHz
always #500 rtc_clk = ~rtc_clk; // 1 MHz
`endif // VERILATOR
// Reset logic
assign rst_n = &rst_cnt;
always_ff @(posedge clk) begin
if (rst_init) rst_cnt <= '0;
else if (~&rst_cnt) rst_cnt <= rst_cnt + 1'b1;
end
`ifdef SCR1_DBG_EN
initial begin
trst_n = 1'b0;
tck = 1'b0;
tdi = 1'b0;
#900ns trst_n = 1'b1;
#500ns tms = 1'b1;
#800ns tms = 1'b0;
#500ns trst_n = 1'b0;
#100ns tms = 1'b1;
end
`endif // SCR1_DBG_EN
//-------------------------------------------------------------------------------
// Run tests
//-------------------------------------------------------------------------------
`include "scr1_top_tb_runtests.sv"
//------------------------------------------------------------------------------
// Core instance
//------------------------------------------------------------------------------
scr1_top_axi i_top (
// Reset
.pwrup_rst_n (rst_n ),
.rst_n (rst_n ),
.cpu_rst_n (rst_n ),
`ifdef SCR1_DBG_EN
.sys_rst_n_o ( ),
.sys_rdc_qlfy_o ( ),
`endif // SCR1_DBG_EN
// Clock
.clk (clk ),
.rtc_clk (rtc_clk ),
// Fuses
.fuse_mhartid (fuse_mhartid ),
`ifdef SCR1_DBG_EN
.fuse_idcode (`SCR1_TAP_IDCODE ),
`endif // SCR1_DBG_EN
// IRQ
`ifdef SCR1_IPIC_EN
.irq_lines (irq_lines ),
`else // SCR1_IPIC_EN
.ext_irq (ext_irq ),
`endif // SCR1_IPIC_EN
.soft_irq (soft_irq ),
// DFT
.test_mode (1'b0 ),
.test_rst_n (1'b1 ),
`ifdef SCR1_DBG_EN
// JTAG
.trst_n (trst_n ),
.tck (tck ),
.tms (tms ),
.tdi (tdi ),
.tdo (tdo ),
.tdo_en (tdo_en ),
`endif // SCR1_DBG_EN
// Instruction memory interface
.io_axi_imem_awid (io_axi_imem_awid ),
.io_axi_imem_awaddr (io_axi_imem_awaddr ),
.io_axi_imem_awlen (io_axi_imem_awlen ),
.io_axi_imem_awsize (io_axi_imem_awsize ),
.io_axi_imem_awburst (),
.io_axi_imem_awlock (),
.io_axi_imem_awcache (),
.io_axi_imem_awprot (),
.io_axi_imem_awregion (),
.io_axi_imem_awuser (),
.io_axi_imem_awqos (),
.io_axi_imem_awvalid (io_axi_imem_awvalid ),
.io_axi_imem_awready (io_axi_imem_awready ),
.io_axi_imem_wdata (io_axi_imem_wdata ),
.io_axi_imem_wstrb (io_axi_imem_wstrb ),
.io_axi_imem_wlast (io_axi_imem_wlast ),
.io_axi_imem_wuser (),
.io_axi_imem_wvalid (io_axi_imem_wvalid ),
.io_axi_imem_wready (io_axi_imem_wready ),
.io_axi_imem_bid (io_axi_imem_bid ),
.io_axi_imem_bresp (io_axi_imem_bresp ),
.io_axi_imem_bvalid (io_axi_imem_bvalid ),
.io_axi_imem_buser (4'd0 ),
.io_axi_imem_bready (io_axi_imem_bready ),
.io_axi_imem_arid (io_axi_imem_arid ),
.io_axi_imem_araddr (io_axi_imem_araddr ),
.io_axi_imem_arlen (io_axi_imem_arlen ),
.io_axi_imem_arsize (io_axi_imem_arsize ),
.io_axi_imem_arburst (io_axi_imem_arburst ),
.io_axi_imem_arlock (),
.io_axi_imem_arcache (),
.io_axi_imem_arprot (),
.io_axi_imem_arregion (),
.io_axi_imem_aruser (),
.io_axi_imem_arqos (),
.io_axi_imem_arvalid (io_axi_imem_arvalid ),
.io_axi_imem_arready (io_axi_imem_arready ),
.io_axi_imem_rid (io_axi_imem_rid ),
.io_axi_imem_rdata (io_axi_imem_rdata ),
.io_axi_imem_rresp (io_axi_imem_rresp ),
.io_axi_imem_rlast (io_axi_imem_rlast ),
.io_axi_imem_ruser (4'd0 ),
.io_axi_imem_rvalid (io_axi_imem_rvalid ),
.io_axi_imem_rready (io_axi_imem_rready ),
// Data memory interface
.io_axi_dmem_awid (io_axi_dmem_awid ),
.io_axi_dmem_awaddr (io_axi_dmem_awaddr ),
.io_axi_dmem_awlen (io_axi_dmem_awlen ),
.io_axi_dmem_awsize (io_axi_dmem_awsize ),
.io_axi_dmem_awburst (),
.io_axi_dmem_awlock (),
.io_axi_dmem_awcache (),
.io_axi_dmem_awprot (),
.io_axi_dmem_awregion (),
.io_axi_dmem_awuser (),
.io_axi_dmem_awqos (),
.io_axi_dmem_awvalid (io_axi_dmem_awvalid ),
.io_axi_dmem_awready (io_axi_dmem_awready ),
.io_axi_dmem_wdata (io_axi_dmem_wdata ),
.io_axi_dmem_wstrb (io_axi_dmem_wstrb ),
.io_axi_dmem_wlast (io_axi_dmem_wlast ),
.io_axi_dmem_wuser (),
.io_axi_dmem_wvalid (io_axi_dmem_wvalid ),
.io_axi_dmem_wready (io_axi_dmem_wready ),
.io_axi_dmem_bid (io_axi_dmem_bid ),
.io_axi_dmem_bresp (io_axi_dmem_bresp ),
.io_axi_dmem_bvalid (io_axi_dmem_bvalid ),
.io_axi_dmem_buser (4'd0 ),
.io_axi_dmem_bready (io_axi_dmem_bready ),
.io_axi_dmem_arid (io_axi_dmem_arid ),
.io_axi_dmem_araddr (io_axi_dmem_araddr ),
.io_axi_dmem_arlen (io_axi_dmem_arlen ),
.io_axi_dmem_arsize (io_axi_dmem_arsize ),
.io_axi_dmem_arburst (io_axi_dmem_arburst ),
.io_axi_dmem_arlock (),
.io_axi_dmem_arcache (),
.io_axi_dmem_arprot (),
.io_axi_dmem_arregion (),
.io_axi_dmem_aruser (),
.io_axi_dmem_arqos (),
.io_axi_dmem_arvalid (io_axi_dmem_arvalid ),
.io_axi_dmem_arready (io_axi_dmem_arready ),
.io_axi_dmem_rid (io_axi_dmem_rid ),
.io_axi_dmem_rdata (io_axi_dmem_rdata ),
.io_axi_dmem_rresp (io_axi_dmem_rresp ),
.io_axi_dmem_rlast (io_axi_dmem_rlast ),
.io_axi_dmem_ruser (4'd0 ),
.io_axi_dmem_rvalid (io_axi_dmem_rvalid ),
.io_axi_dmem_rready (io_axi_dmem_rready )
);
//-------------------------------------------------------------------------------
// Memory instance
//-------------------------------------------------------------------------------
scr1_memory_tb_axi #(
.SIZE (SCR1_MEM_SIZE),
.N_IF (2 ),
.W_ADR (32 ),
.W_DATA (32 )
) i_memory_tb (
// Common
.rst_n (rst_n),
.clk (clk),
`ifdef SCR1_IPIC_EN
.irq_lines (irq_lines),
`else // SCR1_IPIC_EN
.ext_irq (ext_irq),
`endif // SCR1_IPIC_EN
.soft_irq (soft_irq),
// Write address channel
.awid ( {io_axi_imem_awid, io_axi_dmem_awid} ),
.awaddr ( {io_axi_imem_awaddr, io_axi_dmem_awaddr} ),
.awsize ( {io_axi_imem_awsize, io_axi_dmem_awsize} ),
.awlen ( {io_axi_imem_awlen, io_axi_dmem_awlen} ),
.awvalid ( {io_axi_imem_awvalid,io_axi_dmem_awvalid} ),
.awready ( {io_axi_imem_awready,io_axi_dmem_awready} ),
// Write data channel
.wdata ( {io_axi_imem_wdata, io_axi_dmem_wdata} ),
.wstrb ( {io_axi_imem_wstrb, io_axi_dmem_wstrb} ),
.wvalid ( {io_axi_imem_wvalid, io_axi_dmem_wvalid} ),
.wlast ( {io_axi_imem_wlast, io_axi_dmem_wlast} ),
.wready ( {io_axi_imem_wready, io_axi_dmem_wready} ),
// Write response channel
.bready ( {io_axi_imem_bready, io_axi_dmem_bready} ),
.bvalid ( {io_axi_imem_bvalid, io_axi_dmem_bvalid} ),
.bid ( {io_axi_imem_bid, io_axi_dmem_bid} ),
.bresp ( {io_axi_imem_bresp, io_axi_dmem_bresp} ),
// Read address channel
.arid ( {io_axi_imem_arid, io_axi_dmem_arid} ),
.araddr ( {io_axi_imem_araddr, io_axi_dmem_araddr} ),
.arburst ( {io_axi_imem_arburst,io_axi_dmem_arburst} ),
.arsize ( {io_axi_imem_arsize, io_axi_dmem_arsize} ),
.arlen ( {io_axi_imem_arlen, io_axi_dmem_arlen} ),
.arvalid ( {io_axi_imem_arvalid,io_axi_dmem_arvalid} ),
.arready ( {io_axi_imem_arready,io_axi_dmem_arready} ),
// Read data channel
.rvalid ( {io_axi_imem_rvalid, io_axi_dmem_rvalid} ),
.rready ( {io_axi_imem_rready, io_axi_dmem_rready} ),
.rid ( {io_axi_imem_rid, io_axi_dmem_rid} ),
.rdata ( {io_axi_imem_rdata, io_axi_dmem_rdata} ),
.rlast ( {io_axi_imem_rlast, io_axi_dmem_rlast} ),
.rresp ( {io_axi_imem_rresp, io_axi_dmem_rresp} )
);
endmodule : scr1_top_tb_axi

View File

@@ -0,0 +1,224 @@
/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
/// @file <scr1_top_tb_runtests.sv>
/// @brief SCR1 testbench run tests
///
//-------------------------------------------------------------------------------
// Run tests
//-------------------------------------------------------------------------------
initial begin
$value$plusargs("imem_pattern=%h", imem_req_ack_stall);
$value$plusargs("dmem_pattern=%h", dmem_req_ack_stall);
`ifdef SIGNATURE_OUT
$value$plusargs("test_name=%s", s_testname);
b_single_run_flag = 1;
`else // SIGNATURE_OUT
$value$plusargs("test_info=%s", s_info);
$value$plusargs("test_results=%s", s_results);
f_info = $fopen(s_info, "r");
f_results = $fopen(s_results, "a");
`endif // SIGNATURE_OUT
fuse_mhartid = 0;
end
always_ff @(posedge clk) begin
bit test_pass;
bit test_error;
int unsigned f_test;
watchdogs_cnt <= watchdogs_cnt + 'b1;
if (test_running) begin
test_pass = 1;
rst_init <= 1'b0;
if ((i_top.i_core_top.i_pipe_top.curr_pc == SCR1_SIM_EXIT_ADDR) & ~rst_init & &rst_cnt) begin
`ifdef VERILATOR
logic [255:0] full_filename;
full_filename = test_file;
`else // VERILATOR
string full_filename;
full_filename = test_file;
`endif // VERILATOR
if (identify_test(test_file)) begin
logic [31:0] tmpv, start, stop, ref_data, test_data, start_addr, trap_addr;
integer fd;
logic [31:0] code;
`ifdef VERILATOR
logic [2047:0] tmpstr;
`else // VERILATOR
string tmpstr;
`endif // VERILATOR
test_running <= 1'b0;
test_pass = 1;
test_error = 0;
$sformat(tmpstr, "riscv64-unknown-elf-readelf -s %s | grep 'begin_signature\\|end_signature\\| _start\\|trap_vector' | awk '{print $2}' > elfinfo", get_filename(test_file));
fd = $fopen("script.sh", "w");
if (fd == 0) begin
$write("Can't open script.sh\n");
test_error = 1;
end
$fwrite(fd, "%s", tmpstr);
$fclose(fd);
$system("sh script.sh");
fd = $fopen("elfinfo", "r");
if (fd == 0) begin
$write("Can't open elfinfo\n");
test_error = 1;
end
if ($fscanf(fd,"%h\n%h\n%h\n%h", trap_addr, start, stop, start_addr) != 4) begin
$write("Wrong elfinfo data\n");
test_error = 1;
end
if ((trap_addr != ADDR_TRAP_VECTOR & trap_addr != ADDR_TRAP_DEFAULT) | start_addr != ADDR_START) begin
$write("\nError trap_vector %h or/and _start %h are incorrectly aligned and are not at their address\n", trap_addr, start_addr);
test_error = 1;
end
if (start > stop) begin
tmpv = start;
start = stop;
stop = tmpv;
end
$fclose(fd);
`ifdef SIGNATURE_OUT
$sformat(tmpstr, "%s.signature.output", s_testname);
`ifdef VERILATOR
tmpstr = remove_trailing_whitespaces(tmpstr);
`endif
fd = $fopen(tmpstr, "w");
while ((start != stop)) begin
test_data = {i_memory_tb.memory[start+3], i_memory_tb.memory[start+2], i_memory_tb.memory[start+1], i_memory_tb.memory[start]};
$fwrite(fd, "%x", test_data);
$fwrite(fd, "%s", "\n");
start += 4;
end
$fclose(fd);
`else //SIGNATURE_OUT
if (identify_test(test_file) == COMPLIANCE) begin
$sformat(tmpstr, "riscv_compliance/ref_data/%s", get_ref_filename(test_file));
end else if (identify_test(test_file) == ARCH) begin
$sformat(tmpstr, "riscv_arch/ref_data/%s", get_ref_filename(test_file));
end
`ifdef VERILATOR
tmpstr = remove_trailing_whitespaces(tmpstr);
`endif
fd = $fopen(tmpstr,"r");
if (fd == 0) begin
$write("Can't open reference_data file: %s\n", tmpstr);
test_error = 1;
end
while (!$feof(fd) && (start != stop)) begin
if (($fscanf(fd, "%h", ref_data)=='h1)) begin
test_data = {i_memory_tb.memory[start+3], i_memory_tb.memory[start+2], i_memory_tb.memory[start+1], i_memory_tb.memory[start]};
test_pass &= (ref_data == test_data);
start += 4;
end else begin
$write("Wrong $fscanf\n");
test_pass = 0;
end
end
$fclose(fd);
tests_total += 1;
tests_passed += (test_pass & !test_error);
watchdogs_cnt <= '0;
if ((test_pass & !test_error)) begin
$write("\033[0;32mTest passed\033[0m\n");
end else begin
$write("\033[0;31mTest failed\033[0m\n");
end
`endif // SIGNATURE_OUT
end else begin
test_running <= 1'b0;
test_pass = (i_top.i_core_top.i_pipe_top.i_pipe_mprf.mprf_int[10] == 0);
tests_total += 1;
tests_passed += (test_pass & !test_error);
watchdogs_cnt <= '0;
`ifndef SIGNATURE_OUT
if ((test_pass & !test_error)) begin
$write("\033[0;32mTest passed\033[0m\n");
end else begin
$write("\033[0;31mTest failed\033[0m\n");
end
`endif //SIGNATURE_OUT
end
$fwrite(f_results, "%s\t\t%s\t%s\n", test_file, "OK" , ((test_pass & !test_error) ? "PASS" : "__FAIL"));
end
end else begin
`ifdef SIGNATURE_OUT
if ((s_testname.len() != 0) && (b_single_run_flag)) begin
$sformat(test_file, "%s.bin", s_testname);
`else // SIGNATURE_OUT
if (f_info) begin
`ifdef VERILATOR
if ($fgets(test_file,f_info)) begin
test_file = test_file >> 8; // < Removing trailing LF symbol ('\n')
`else // VERILATOR
if (!$feof(f_info)) begin
void'($fscanf(f_info, "%s\n", test_file));
`endif // VERILATOR
`endif // SIGNATURE_OUT
f_test = $fopen(test_file,"r");
if (f_test != 0) begin
// Launch new test
`ifdef SCR1_TRACE_LOG_EN
i_top.i_core_top.i_pipe_top.i_tracelog.test_name = test_file;
`endif // SCR1_TRACE_LOG_EN
i_memory_tb.test_file = test_file;
i_memory_tb.test_file_init = 1'b1;
`ifndef SIGNATURE_OUT
$write("\033[0;34m---Test: %s\033[0m\n", test_file);
`endif //SIGNATURE_OUT
test_running <= 1'b1;
rst_init <= 1'b1;
`ifdef SIGNATURE_OUT
b_single_run_flag = 0;
`endif
end else begin
$fwrite(f_results, "%s\t\t%s\t%s\n", test_file, "__FAIL", "--------");
end
end else begin
// Exit
`ifndef SIGNATURE_OUT
$display("\n#--------------------------------------");
$display("# Summary: %0d/%0d tests passed", tests_passed, tests_total);
$display("#--------------------------------------\n");
$fclose(f_info);
$fclose(f_results);
`endif
$finish();
end
`ifndef SIGNATURE_OUT
end else begin
$write("\033[0;31mError: could not open file %s\033[0m\n", s_info);
$finish();
end
`endif // SIGNATURE_OUT
end
if (watchdogs_cnt == TIMEOUT) begin
if (test_file == "watchdog.hex") begin
tests_total += 'b1;
tests_passed += 'b1;
$fwrite(f_results, "%s\t\t%s\t%s\n", test_file, "OK" , "PASS");
test_running <= '0;
watchdogs_cnt <= '0;
end else begin
tests_total += 'b1;
tests_passed += 'b0;
$write("\033[0;31mError: TIMEOUT %s\033[0m\n", test_file);
$fwrite(f_results, "%s\t\t%s\t%s\n", test_file, "OK" , "__FAIL");
test_running <= '0;
watchdogs_cnt <= '0;
end
end
end