mirror of https://github.com/efabless/caravel.git
Add mem_dff2 test and update script to change the linker script
This commit is contained in:
parent
f5e1060c6d
commit
86f2c04d3e
|
@ -156,12 +156,18 @@
|
||||||
"GL":["r_gl","nightly","weekly","tape_out"],
|
"GL":["r_gl","nightly","weekly","tape_out"],
|
||||||
"GL_SDF":["r_sdf","weekly","tape_out"],
|
"GL_SDF":["r_sdf","weekly","tape_out"],
|
||||||
"description":"stress the cpu with heavy processing"}
|
"description":"stress the cpu with heavy processing"}
|
||||||
,"mem_stress" :{"level":2,
|
,"mem_dff2" :{"level":2,
|
||||||
"SW":true,
|
"SW":true,
|
||||||
"RTL":["r_rtl","nightly","weekly","tape_out"],
|
"RTL":["r_rtl","nightly","weekly","tape_out"],
|
||||||
"GL":["r_gl","nightly","weekly","tape_out"],
|
"GL":["r_gl","nightly","weekly","tape_out"],
|
||||||
"GL_SDF":["r_sdf","weekly","tape_out"],
|
"GL_SDF":["r_sdf","weekly","tape_out"],
|
||||||
"description":"Memory stress tests write and read from 800 bytes 200 words and 400 half words"}
|
"description":"Memory stress for all space of dff2"}
|
||||||
|
,"mem_dff" :{"level":2,
|
||||||
|
"SW":true,
|
||||||
|
"RTL":["r_rtl","nightly","weekly","tape_out"],
|
||||||
|
"GL":["r_gl","nightly","weekly","tape_out"],
|
||||||
|
"GL_SDF":["r_sdf","weekly","tape_out"],
|
||||||
|
"description":"Memory stress for all space of dff"}
|
||||||
,"IRQ_external" :{"level":2,
|
,"IRQ_external" :{"level":2,
|
||||||
"SW":true,
|
"SW":true,
|
||||||
"RTL":["r_rtl","setup","nightly","weekly","tape_out"],
|
"RTL":["r_rtl","setup","nightly","weekly","tape_out"],
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
#include <defs.h>
|
||||||
|
|
||||||
|
#define BYTE_SIZE 800
|
||||||
|
#define SHORT_SIZE BYTE_SIZE/2
|
||||||
|
#define INT_SIZE BYTE_SIZE/4
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
reg_wb_enable =1; // for enable writing to reg_debug_1 and reg_debug_2
|
||||||
|
reg_debug_1 = 0x0;
|
||||||
|
reg_debug_2 = 0x0;
|
||||||
|
|
||||||
|
unsigned int *dff_start_address = (unsigned int *) 0x00000000;
|
||||||
|
unsigned int dff_size = 0x400/4;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < dff_size; i++){
|
||||||
|
unsigned int data = (i + 7)*13;
|
||||||
|
*(dff_start_address+i) = data;
|
||||||
|
}
|
||||||
|
bool is_fail = false;
|
||||||
|
for (unsigned int i = 0; i < dff_size; i++){
|
||||||
|
unsigned int data = (i + 7)*13;
|
||||||
|
if (data != *(dff_start_address+i)){
|
||||||
|
reg_debug_2 = i;
|
||||||
|
reg_debug_1 = 0x1E;
|
||||||
|
is_fail = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_fail)
|
||||||
|
reg_debug_1 = 0x1B;
|
||||||
|
|
||||||
|
|
||||||
|
// test finish
|
||||||
|
reg_debug_1 = 0xFF;
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
#include <defs.h>
|
||||||
|
|
||||||
|
#define BYTE_SIZE 800
|
||||||
|
#define SHORT_SIZE BYTE_SIZE/2
|
||||||
|
#define INT_SIZE BYTE_SIZE/4
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
reg_wb_enable =1; // for enable writing to reg_debug_1 and reg_debug_2
|
||||||
|
reg_debug_1 = 0x0;
|
||||||
|
reg_debug_2 = 0x0;
|
||||||
|
|
||||||
|
unsigned int *dff2_start_address = (unsigned int *) 0x00000400;
|
||||||
|
unsigned int dff2_size = 0x200 / 4;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < dff2_size; i++){
|
||||||
|
unsigned int data = (i + 7)*13;
|
||||||
|
*(dff2_start_address+i) = data;
|
||||||
|
}
|
||||||
|
bool is_fail = false;
|
||||||
|
for (unsigned int i = 0; i < dff2_size; i++){
|
||||||
|
unsigned int data = (i + 7)*13;
|
||||||
|
if (data != *(dff2_start_address+i)){
|
||||||
|
reg_debug_2 = i;
|
||||||
|
reg_debug_1 = 0x1E;
|
||||||
|
is_fail = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_fail)
|
||||||
|
reg_debug_1 = 0x1B;
|
||||||
|
|
||||||
|
|
||||||
|
// test finish
|
||||||
|
reg_debug_1 = 0xFF;
|
||||||
|
}
|
|
@ -1,102 +0,0 @@
|
||||||
#include <defs.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
@ start of test
|
|
||||||
send packet with size = 1
|
|
||||||
@ pass bytes
|
|
||||||
send packet with size = 2
|
|
||||||
@ pass int
|
|
||||||
send packet with size = 3
|
|
||||||
@ pass short
|
|
||||||
send packet with size = 4
|
|
||||||
@ error reading
|
|
||||||
send packet with size = 9
|
|
||||||
@ test finish
|
|
||||||
send packet with size = 7
|
|
||||||
send packet with size = 7
|
|
||||||
send packet with size = 7
|
|
||||||
|
|
||||||
*/
|
|
||||||
#define BYTE_SIZE 800
|
|
||||||
#define SHORT_SIZE BYTE_SIZE/2
|
|
||||||
#define INT_SIZE BYTE_SIZE/4
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
reg_wb_enable =1; // for enable writing to reg_debug_1 and reg_debug_2
|
|
||||||
reg_debug_1 = 0x0;
|
|
||||||
reg_debug_2 = 0x0;
|
|
||||||
unsigned char dff_bytes[BYTE_SIZE];
|
|
||||||
unsigned short *dff_shorts=(unsigned short *) dff_bytes;
|
|
||||||
unsigned int *dff_ints=(unsigned int *) dff_bytes;
|
|
||||||
unsigned char magic = 0x79;
|
|
||||||
unsigned int magic_int = 0x79797979;
|
|
||||||
unsigned short magic_short = 0x7979;
|
|
||||||
unsigned char magic1;
|
|
||||||
unsigned int magic1_int;
|
|
||||||
unsigned short magic1_short;
|
|
||||||
int i;
|
|
||||||
magic1 = magic;
|
|
||||||
for ( i=0; i<BYTE_SIZE; i++){
|
|
||||||
dff_bytes[i] = (magic1*3+5)|magic;
|
|
||||||
magic1 += 11;
|
|
||||||
}
|
|
||||||
magic1 = magic;
|
|
||||||
bool is_fail = false;
|
|
||||||
for ( i=0; i<BYTE_SIZE; i++){
|
|
||||||
unsigned char t = (magic1*3+5)|magic;
|
|
||||||
if (t != dff_bytes[i]){
|
|
||||||
reg_debug_1 = 0x1E; // fail reading bytes expected value
|
|
||||||
is_fail = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
magic1 += 11;
|
|
||||||
}
|
|
||||||
if (!is_fail)
|
|
||||||
reg_debug_1 = 0x1B; // pass reading bytes expected value
|
|
||||||
|
|
||||||
is_fail = false;
|
|
||||||
// int
|
|
||||||
magic1_int = magic_int;
|
|
||||||
for ( i=0; i<INT_SIZE; i++){
|
|
||||||
dff_ints[i] = (magic1_int*3+5)|magic_int;
|
|
||||||
magic1_int += 11;
|
|
||||||
}
|
|
||||||
magic1_int = magic_int;
|
|
||||||
|
|
||||||
for ( i=0; i<INT_SIZE; i++){
|
|
||||||
unsigned int t = (magic1_int*3+5)|magic_int;
|
|
||||||
if (t != dff_ints[i]){
|
|
||||||
reg_debug_1 = 0x2E; // fail reading ints expected value
|
|
||||||
is_fail = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
magic1_int += 11;
|
|
||||||
}
|
|
||||||
if (!is_fail)
|
|
||||||
reg_debug_1 = 0x2B; // pass reading ints expected value
|
|
||||||
|
|
||||||
is_fail = false;
|
|
||||||
|
|
||||||
// short
|
|
||||||
magic1_short = magic_short;
|
|
||||||
for ( i=0; i<SHORT_SIZE; i++){
|
|
||||||
dff_shorts[i] = (magic1_short*3+5)|magic_short;
|
|
||||||
magic1_short += 11;
|
|
||||||
}
|
|
||||||
magic1_short = magic_short;
|
|
||||||
|
|
||||||
for ( i=0; i<SHORT_SIZE; i++){
|
|
||||||
unsigned short t = (magic1_short*3+5)|magic_short;
|
|
||||||
if (t != dff_shorts[i]){
|
|
||||||
reg_debug_1 = 0x3E; // fail reading shorts expected value
|
|
||||||
is_fail = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
magic1_short += 11;
|
|
||||||
}
|
|
||||||
if (!is_fail)
|
|
||||||
reg_debug_1 = 0x3B; // pass reading ints expected value
|
|
||||||
|
|
||||||
// test finish
|
|
||||||
reg_debug_2 = 0xFF;
|
|
||||||
}
|
|
|
@ -10,42 +10,64 @@ from tests.bitbang.bitbang_functions import *
|
||||||
from interfaces.caravel import GPIO_MODE
|
from interfaces.caravel import GPIO_MODE
|
||||||
|
|
||||||
reg = Regs()
|
reg = Regs()
|
||||||
"""Testbench of GPIO configuration through bit-bang method using the StriVe housekeeping SPI."""
|
|
||||||
@cocotb.test()
|
@cocotb.test()
|
||||||
@repot_test
|
@repot_test
|
||||||
async def mem_stress(dut):
|
async def mem_dff2(dut):
|
||||||
caravelEnv,clock = await test_configure(dut,timeout_cycles=18164004)
|
caravelEnv,clock = await test_configure(dut,timeout_cycles=18164004)
|
||||||
cpu = RiskV(dut)
|
cpu = RiskV(dut)
|
||||||
cpu.cpu_force_reset()
|
cpu.cpu_force_reset()
|
||||||
cpu.cpu_release_reset()
|
cpu.cpu_release_reset()
|
||||||
cocotb.log.info(f"[TEST] Start mem stress test")
|
cocotb.log.info(f"[TEST] Start mem stress test")
|
||||||
pass_list = (0x1B,0x2B,0x3B)
|
pass_list = (0x1B)
|
||||||
fail_list = (0x1E,0x2E,0x3E)
|
fail_list = (0x1E)
|
||||||
phases_fails = 3
|
phases_fails = 1
|
||||||
phases_passes = 0
|
phases_passes = 0
|
||||||
reg1 =0 # buffer
|
reg1 =0 # buffer
|
||||||
while True:
|
while True:
|
||||||
if cpu.read_debug_reg2() == 0xFF: # test finish
|
if cpu.read_debug_reg1() == 0xFF: # test finish
|
||||||
break
|
break
|
||||||
if reg1 != cpu.read_debug_reg1():
|
if reg1 != cpu.read_debug_reg1():
|
||||||
reg1 = cpu.read_debug_reg1()
|
reg1 = cpu.read_debug_reg1()
|
||||||
if reg1 in pass_list: # pass phase
|
if reg1 in pass_list: # pass phase
|
||||||
phases_passes +=1
|
phases_passes +=1
|
||||||
phases_fails -=1
|
phases_fails -=1
|
||||||
cocotb.log.info(f"[TEST] pass writing and reading from {phase_to_type(hex(reg1)[2])}")
|
cocotb.log.info(f"[TEST] pass writing and reading all dff2 memory ")
|
||||||
elif reg1 in fail_list: # pass phase
|
elif reg1 in fail_list: # pass phase
|
||||||
cocotb.log.error(f"[TEST] failed phase {phase_to_type(hex(reg1)[2])}")
|
cocotb.log.error(f"[TEST] failed access address {hex(0x00000400 + cpu.read_debug_reg2())}")
|
||||||
await ClockCycles(caravelEnv.clk,1)
|
await ClockCycles(caravelEnv.clk,100)
|
||||||
|
|
||||||
if phases_fails > 0:
|
if phases_fails > 0:
|
||||||
cocotb.log.error(f"[TEST] finish with {phases_passes} phases passes and {phases_fails} phases fails")
|
cocotb.log.error(f"[TEST] finish with {phases_passes} phases passes and {phases_fails} phases fails")
|
||||||
else:
|
else:
|
||||||
cocotb.log.info(f"[TEST] finish with {phases_passes} phases passes and {phases_fails} phases fails")
|
cocotb.log.info(f"[TEST] finish with {phases_passes} phases passes and {phases_fails} phases fails")
|
||||||
|
|
||||||
def phase_to_type(phase):
|
@cocotb.test()
|
||||||
if phase == "1":
|
@repot_test
|
||||||
return "800 Bytes"
|
async def mem_dff(dut):
|
||||||
elif phase == "2":
|
caravelEnv,clock = await test_configure(dut,timeout_cycles=18164004)
|
||||||
return "200 Words"
|
cpu = RiskV(dut)
|
||||||
elif phase == "3":
|
cpu.cpu_force_reset()
|
||||||
return "400 Halfwords"
|
cpu.cpu_release_reset()
|
||||||
|
cocotb.log.info(f"[TEST] Start mem stress test")
|
||||||
|
pass_list = (0x1B)
|
||||||
|
fail_list = (0x1E)
|
||||||
|
phases_fails = 1
|
||||||
|
phases_passes = 0
|
||||||
|
reg1 =0 # buffer
|
||||||
|
while True:
|
||||||
|
if cpu.read_debug_reg1() == 0xFF: # test finish
|
||||||
|
break
|
||||||
|
if reg1 != cpu.read_debug_reg1():
|
||||||
|
reg1 = cpu.read_debug_reg1()
|
||||||
|
if reg1 in pass_list: # pass phase
|
||||||
|
phases_passes +=1
|
||||||
|
phases_fails -=1
|
||||||
|
cocotb.log.info(f"[TEST] pass writing and reading all dff memory ")
|
||||||
|
elif reg1 in fail_list: # pass phase
|
||||||
|
cocotb.log.error(f"[TEST] failed access address {hex(0x00000400 + cpu.read_debug_reg2())}")
|
||||||
|
await ClockCycles(caravelEnv.clk,100)
|
||||||
|
|
||||||
|
if phases_fails > 0:
|
||||||
|
cocotb.log.error(f"[TEST] finish with {phases_passes} phases passes and {phases_fails} phases fails")
|
||||||
|
else:
|
||||||
|
cocotb.log.info(f"[TEST] finish with {phases_passes} phases passes and {phases_fails} phases fails")
|
||||||
|
|
|
@ -30,6 +30,20 @@ def search_str(file_path, word):
|
||||||
else:
|
else:
|
||||||
return "failed"
|
return "failed"
|
||||||
|
|
||||||
|
def change_dff(str,new_str,file_path):
|
||||||
|
# Read in the file
|
||||||
|
with open(file_path, 'r') as file :
|
||||||
|
filedata = file.read()
|
||||||
|
|
||||||
|
if new_str == "> dff2":
|
||||||
|
if new_str in filedata: # to avoid type dff22 types
|
||||||
|
return
|
||||||
|
# Replace the target string
|
||||||
|
filedata = filedata.replace(str, new_str)
|
||||||
|
|
||||||
|
# Write the file out again
|
||||||
|
with open(file_path, 'w') as file:
|
||||||
|
file.write(filedata)
|
||||||
|
|
||||||
class RunTest:
|
class RunTest:
|
||||||
def __init__(self,test_name,sim,corner) -> None:
|
def __init__(self,test_name,sim,corner) -> None:
|
||||||
|
@ -137,6 +151,7 @@ class RunTest:
|
||||||
return (test_path)
|
return (test_path)
|
||||||
|
|
||||||
def hex_generate(self):
|
def hex_generate(self):
|
||||||
|
tests_use_dff2 = ["mem_dff"]
|
||||||
#open docker
|
#open docker
|
||||||
test_path =self.test_path()
|
test_path =self.test_path()
|
||||||
self.cd_make()
|
self.cd_make()
|
||||||
|
@ -158,6 +173,10 @@ class RunTest:
|
||||||
f"--strip-debug -ffreestanding -nostdlib -o {elf_out} {SOURCE_FILES} {c_file}")
|
f"--strip-debug -ffreestanding -nostdlib -o {elf_out} {SOURCE_FILES} {c_file}")
|
||||||
hex_command = f"{GCC_PATH}/{GCC_PREFIX}-objcopy -O verilog {elf_out} {hex_file} "
|
hex_command = f"{GCC_PATH}/{GCC_PREFIX}-objcopy -O verilog {elf_out} {hex_file} "
|
||||||
sed_command = f"sed -ie 's/@10/@00/g' {hex_file}"
|
sed_command = f"sed -ie 's/@10/@00/g' {hex_file}"
|
||||||
|
#change linker script to dff2
|
||||||
|
if self.test_name in tests_use_dff2:
|
||||||
|
change_dff(str="> dff",new_str="> dff2",file_path=LINKER_SCRIPT)
|
||||||
|
# sys.exit()
|
||||||
hex_gen_state = os.system(f"docker run -it -v {go_up(self.cocotb_path,4)}:{go_up(self.cocotb_path,4)} efabless/dv:latest sh -c 'cd {test_dir} && {elf_command} && {hex_command} && {sed_command} '")
|
hex_gen_state = os.system(f"docker run -it -v {go_up(self.cocotb_path,4)}:{go_up(self.cocotb_path,4)} efabless/dv:latest sh -c 'cd {test_dir} && {elf_command} && {hex_command} && {sed_command} '")
|
||||||
self.full_terminal.write(os.path.expandvars(elf_command)+"\n"+"\n")
|
self.full_terminal.write(os.path.expandvars(elf_command)+"\n"+"\n")
|
||||||
self.full_terminal.write(os.path.expandvars(hex_command)+"\n"+"\n")
|
self.full_terminal.write(os.path.expandvars(hex_command)+"\n"+"\n")
|
||||||
|
@ -167,6 +186,9 @@ class RunTest:
|
||||||
if hex_gen_state != 0 :
|
if hex_gen_state != 0 :
|
||||||
print(f"fatal: Error when generating hex")
|
print(f"fatal: Error when generating hex")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
if self.test_name in tests_use_dff2:
|
||||||
|
change_dff(str="> dff2",new_str="> dff",file_path=LINKER_SCRIPT)
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
def cd_make(self):
|
def cd_make(self):
|
||||||
os.chdir(f"{os.getenv('VERILOG_PATH')}/dv/make")
|
os.chdir(f"{os.getenv('VERILOG_PATH')}/dv/make")
|
||||||
|
|
Loading…
Reference in New Issue