Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions CMake/add_test.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ macro(add_unit_test TEST_NAME)

#Add Test
add_test(NAME ${TEST_NAME}
COMMAND ${MODEL_DIR}/verilated_model ${BUILD_DIR}/vector-tests/prog_${TEST_NAME}.txt 32 4194304 ${MEM_LATENCY} 1 ${TEST_NAME} ${VREG_W} ${TEST_CASE_NUM} ${VCD_TRACE_ARGS}
COMMAND ${MODEL_DIR}/verilated_model ${BUILD_DIR}/vector-tests/prog_${TEST_NAME}.txt ${MEM_PORTS} ${MEM_W} 4194304 ${MEM_LATENCY} 1 ${TEST_NAME} ${VREG_W} ${TEST_CASE_NUM} ${VCD_TRACE_ARGS}
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})

message(STATUS "Successfully added ${TEST_NAME}")
Expand Down Expand Up @@ -142,7 +142,8 @@ macro(add_legacy_test TEST_NAME)
COMMAND echo -n "${TEST_BUILD_PATH}/${TEST_NAME}_result.txt " >> prog_${TEST_NAME}.txt
COMMAND readelf -s ${folder}-${TEST_NAME}.elf | sed '2,13 s/ //1' | grep vdata_start | cut -d " " -f 6 | tr [=["\n"]=] " " >> prog_${TEST_NAME}.txt
COMMAND readelf -s ${folder}-${TEST_NAME}.elf | sed '2,13 s/ //1' | grep vdata_end | cut -d " " -f 6 | tr [=["\n"]=] " " >> prog_${TEST_NAME}.txt
COMMAND ${CMAKE_OBJDUMP} -D ${folder}-${TEST_NAME}.elf > ${TEST_NAME}_dump.txt)
COMMAND ${CMAKE_OBJDUMP} -D ${folder}-${TEST_NAME}.elf > ${TEST_NAME}_dump.txt
)


#If trace option is selected, provide the paths for the .csv and .vcd trace files. Due to argument parsing in verilator_main.cpp, both must be provided
Expand Down
2 changes: 1 addition & 1 deletion CMake/run_legacy_test.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#For reuse, provide the direct path to the files for VERILATED_DIR and BUILD_DIR
#Provide the paths for the mem_trace .csv and signal trace .vcd as XXX_TRACE_ARGS to get those outputs.
#For test case counting, set argument to 1 for compliance with chipsalliance
execute_process(COMMAND ${VERILATED_DIR}/verilated_model ${BUILD_DIR}/prog_${TEST_NAME}.txt ${MEM_W} 4194304 ${MEM_LATENCY} 1 ${TEST_NAME} ${VREG_W} 1 ${VCD_TRACE_ARGS}
execute_process(COMMAND ${VERILATED_DIR}/verilated_model ${BUILD_DIR}/prog_${TEST_NAME}.txt ${MEM_PORTS} ${MEM_W} 4194304 ${MEM_LATENCY} 1 ${TEST_NAME} ${VREG_W} 1 ${VCD_TRACE_ARGS}
RESULT_VARIABLE RETURN_SIM)
execute_process(COMMAND diff ${BUILD_DIR}/${TEST_NAME}_result.txt ${BUILD_DIR}/${TEST_NAME}_reference.txt
RESULT_VARIABLE RETURN_DIFF)
Expand Down
2 changes: 1 addition & 1 deletion CMake/run_test.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#All variables must be passed in from the Add_Tests COMMAND argument
#For reuse, provide the direct path to the files for VERILATED_DIR and BUILD_DIR
#Provide the paths for the mem_trace .csv and signal trace .vcd as XXX_TRACE_ARGS to get those outputs.
execute_process(COMMAND ${VERILATED_DIR}/verilated_model ${BUILD_DIR}/prog_${TEST_NAME}.txt ${MEM_W} 4194304 ${MEM_LATENCY} 1 ${TEST_NAME} ${VREG_W} ${VCD_TRACE_ARGS}
execute_process(COMMAND ${VERILATED_DIR}/verilated_model ${BUILD_DIR}/prog_${TEST_NAME}.txt ${MEM_PORTS} ${MEM_W} 4194304 ${MEM_LATENCY} 1 ${TEST_NAME} ${VREG_W} ${VCD_TRACE_ARGS}
RESULT_VARIABLE RETURN_SIM)

if(RETURN_SIM)
Expand Down
10 changes: 8 additions & 2 deletions build_model/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ set(CMAKE_CXX_STANDARD 14)

option(TRACE "Enable minimal VCD trace outputs" OFF)
option(TRACE_FULL "Enable FULL VCD trace outputs" OFF) #TODO: prevent this option from being cached, force user to always manually enable it
option(OLD_VICUNA "Old vicuna without vl abort" ON)
option(FORCE_ALIGNED_READS "Forces aligned reads for cv32 and vproc" ON)

########
## Import RTL configuration from here instead of command line.
Expand All @@ -37,9 +39,13 @@ message("Selected SCALAR_CORE = ${SCALAR_CORE}")
set(ENV{VPROC_PIPELINES} ${VPROC_PIPELINES})
message("Selected VPROC_PIPELINES = ${VPROC_PIPELINES}")
message("Selected RISCV_ARCH = ${RISCV_ARCH}")
set(ENV{VREG_W} ${VREG_W})
message("Selected VREG_W = ${VREG_W}")
set(MEM_W ${VMEM_W})
set(ENV{MEM_W} ${VMEM_W})
message("Selected MEM_W = ${MEM_W}")
set(MEM_PORTS ${VMEM_PORTS})
message("Selected MEM_PORTS = ${MEM_PORTS}")

set(MEM_SZ 4194304)

Expand Down Expand Up @@ -401,7 +407,7 @@ if(TRACE)
set(TRACE TRACE)

if(TRACE_FULL)
set(TRACE_FLAG ) #no --trace-depth flag defaults to entire model
set(TRACE_FLAG --trace-structs) #no --trace-depth flag defaults to entire model
else()
set(TRACE_FLAG --trace-depth 2)
endif()
Expand Down Expand Up @@ -446,7 +452,7 @@ if ( ${SCALAR_CORE} STREQUAL "cv32e40x" )
#+define+COREV_ASSERT_OFF #Fixes UVM error with CV32E40X (Needed when not using -DVPROC_SVA)
${TRACE_FLAG}
--assert -DVPROC_SVA
-GMEM_W=${MEM_W} -GVMEM_W=${VMEM_W}
-GMEM_W=${MEM_W} -GVMEM_W=${VMEM_W} -GMEM_PORTS=${MEM_PORTS}
${VICUNA_MODE}
${READ_MODE}
${XIF_FLAG}
Expand Down
96 changes: 58 additions & 38 deletions build_model/cv32e40x/verilator_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,35 +20,40 @@ int main(int argc, char **argv) {
//////////////////////////
//Check validity and parse input arguments
//////////////////////////
if (argc != 9 && argc != 10) {
fprintf(stderr, "ERROR: Correct Usage: %s PROG_PATHS_LIST MEM_W MEM_SZ MEM_LATENCY EXTRA_CYCLES TEST_NAME VREG_W NUM_TEST_CASES [WAVEFORM_FILE]\n", argv[0]);
if (argc != 10 && argc != 11) {
fprintf(stderr, "ERROR: Correct Usage: %s PROG_PATHS_LIST MEM_PORTS MEM_W MEM_SZ MEM_LATENCY EXTRA_CYCLES TEST_NAME VREG_W NUM_TEST_CASES [WAVEFORM_FILE]\n", argv[0]);
return 1;
}

int mem_w, mem_sz, mem_latency, extra_cycles, num_cases;
int mem_ports, mem_w, mem_sz, mem_latency, extra_cycles, num_cases;
{
char *endptr;
mem_w = strtol(argv[2], &endptr, 10);
mem_ports = strtol(argv[2], &endptr, 10);
if (mem_ports == 0 || *endptr != 0) {
fprintf(stderr, "ERROR: invalid MEM_PORTS argument\n");
return 1;
}
mem_w = strtol(argv[3], &endptr, 10);
if (mem_w == 0 || *endptr != 0) {
fprintf(stderr, "ERROR: invalid MEM_W argument\n");
return 1;
}
mem_sz = strtol(argv[3], &endptr, 10);
mem_sz = strtol(argv[4], &endptr, 10);
if (mem_sz == 0 || *endptr != 0) {
fprintf(stderr, "ERROR: invalid MEM_SZ argument\n");
return 1;
}
mem_latency = strtol(argv[4], &endptr, 10);
mem_latency = strtol(argv[5], &endptr, 10);
if (*endptr != 0) {
fprintf(stderr, "ERROR: invalid MEM_LATENCY argument\n");
return 1;
}
extra_cycles = strtol(argv[5], &endptr, 10);
extra_cycles = strtol(argv[6], &endptr, 10);
if (*endptr != 0) {
fprintf(stderr, "ERROR: invalid EXTRA_CYCLES argument\n");
return 1;
}
num_cases = strtol(argv[8], &endptr, 10);
num_cases = strtol(argv[9], &endptr, 10);
if (*endptr != 0) {
fprintf(stderr, "ERROR: invalid NUM_TEST_CASES argument\n");
return 1;
Expand All @@ -70,37 +75,43 @@ int main(int argc, char **argv) {
//////////////////////////

/*Log File for Scalar Registers*/
std::string filename=(std::string(argv[6])+std::string("_xreg_commits_verilator.txt"));
std::string filename=(std::string(argv[7])+std::string("_xreg_commits_verilator.txt"));
FILE *fxreglog = fopen(filename.c_str(), "w");

/*Log File for Vector Registers. Separate log because actual writes to VREGs might be out of order relative to the Xregs. Should NOT be out of order relative to themselves.*/
filename=(std::string(argv[6])+std::string("_vreg_commits_verilator.txt"));
filename=(std::string(argv[7])+std::string("_vreg_commits_verilator.txt"));
FILE *fvreglog = fopen(filename.c_str(), "w");

/*Log File for Scalar Floating Point Registers*/
filename=(std::string(argv[6])+std::string("_freg_commits_verilator.txt"));
filename=(std::string(argv[7])+std::string("_freg_commits_verilator.txt"));
FILE *ffreglog = fopen(filename.c_str(), "w");

//////////////////////////
//Allocate memory latency buffers
//////////////////////////

bool *mem_rvalid_queue = (bool *)malloc(sizeof(bool) * mem_latency);
unsigned char **mem_rdata_queue = (unsigned char **)malloc(sizeof(unsigned char *) * mem_latency); //memory data port
bool *mem_err_queue = (bool *)malloc(sizeof(bool) * mem_latency);

for(int queue_pos = 0; queue_pos < mem_latency; queue_pos++)
{
mem_rdata_queue[queue_pos] = (unsigned char *)malloc(sizeof(unsigned char) * mem_w/8);
bool *mem_rvalid_queue[mem_ports];
unsigned char **mem_rdata_queue[mem_ports];
bool *mem_err_queue[mem_ports];

for(int i = 0; i < mem_ports; i++){
mem_rvalid_queue[i] = (bool *)malloc(sizeof(bool) * mem_latency);
mem_rdata_queue[i] = (unsigned char **)malloc(sizeof(unsigned char *) * mem_latency);
mem_err_queue[i] = (bool *)malloc(sizeof(bool) * mem_latency);

for(int queue_pos = 0; queue_pos < mem_latency; queue_pos++)
{
mem_rdata_queue[i][queue_pos] = (unsigned char *)malloc(sizeof(unsigned char) * mem_w/8);
}
}


bool *mem_ivalid_queue = (bool *)malloc(sizeof(bool) * mem_latency);
unsigned char **mem_idata_queue = (unsigned char **)malloc(sizeof(unsigned char *) * mem_latency); //memory instruction port
bool *mem_ierr_queue = (bool *)malloc(sizeof(bool) * mem_latency);
//even though known instruction interface width of 32 bits, malloc like this for compatability with memory management helper functions
for(int queue_pos = 0; queue_pos < mem_latency; queue_pos++)
{
mem_idata_queue[queue_pos] = (unsigned char *)malloc(sizeof(unsigned char) * 32/8);
mem_idata_queue[queue_pos] = (unsigned char *)malloc(sizeof(unsigned char) * mem_w/8);
}

Vvproc_top *top = new Vvproc_top;
Expand All @@ -110,11 +121,11 @@ int main(int argc, char **argv) {
//Setup vcd trace file
//////////////////////////
VerilatedTrace_t *tfp = NULL;
if (argc == 10) {
if (argc == 11) {
#ifdef TRACE_VCD
tfp = new VerilatedTrace_t;
top->trace(tfp, 99); // Trace 99 levels of hierarchy
tfp->open(argv[9]);
tfp->open(argv[10]);
#endif
}

Expand Down Expand Up @@ -161,10 +172,12 @@ int main(int argc, char **argv) {
//////////////////////////

int i;
for (i = 0; i < mem_latency; i++) {
mem_rvalid_queue[i] = 0;
for(int j = 0; j < mem_ports; j++){
for (i = 0; i < mem_latency; i++) {
mem_rvalid_queue[j][i] = 0;
}
top->mem_rvalid_i[j] = 0;
}
top->mem_rvalid_i = 0;
top->mem_irvalid_i = 0;
top->clk_i = 0;
top->rst_ni = 0;
Expand All @@ -187,7 +200,7 @@ int main(int argc, char **argv) {


char *endptr;
int vreg_w = strtol(argv[7], &endptr, 10);
int vreg_w = strtol(argv[8], &endptr, 10);

int cycles_begin_trace = 0; //Traces begin at this cycle count. TODO: expose to the command line
int cycles_end_trace = 0; //Traces end at thsi cycle count. TODO: expose to the command line
Expand Down Expand Up @@ -215,14 +228,15 @@ int main(int argc, char **argv) {
//////////////////////////
//Update Memory interfaces
//////////////////////////

//Update write interface

for(int i = 0; i < mem_ports; i++){
//Update write interface
//Update read interface TODO - STALL IF (top->mem_req_o && !top->mem_we_o). Original Vicuna also did not contain this condition TODO: MEM_REQ_VALID NEEDS TO BE SIGNALLED for writes
update_mem_load(top->mem_addr_o, (top->mem_req_o && !top->mem_we_o), mem_w, mem_latency, mem_sz, (unsigned char*)&(top->mem_rdata_i), (bool*)&(top->mem_rvalid_i), (bool*)&(top->mem_err_i), mem_rdata_queue, mem_rvalid_queue, mem_err_queue, mem);
update_mem_write(top->mem_addr_o, (top->mem_req_o && top->mem_we_o), mem_w, mem_latency, mem_sz, (unsigned char*)&(top->mem_wdata_o), (unsigned char*)&(top->mem_be_o), mem_rvalid_queue, mem_err_queue, mem);
update_mem_load(top->mem_addr_o[i], (top->mem_req_o[i] && !top->mem_we_o[i]), mem_w, mem_latency, mem_sz, (unsigned char*)&(top->mem_rdata_i[i]), (bool*)&(top->mem_rvalid_i[i]), (bool*)&(top->mem_err_i[i]), mem_rdata_queue[i], mem_rvalid_queue[i], mem_err_queue[i], mem);
update_mem_write(top->mem_addr_o[i], (top->mem_req_o[i] && top->mem_we_o[i]), mem_w, mem_latency, mem_sz, (unsigned char*)&(top->mem_wdata_o[i]), (unsigned char*)&(top->mem_be_o[i]), mem_rvalid_queue[i], mem_err_queue[i], mem);
}

//Update instruction memory interface
update_mem_load(top->mem_iaddr_o, top->mem_ireq_o, 32, mem_latency, mem_sz, (unsigned char*)&(top->mem_irdata_i), (bool*)&(top->mem_irvalid_i), (bool*)&(top->mem_ierr_i), mem_idata_queue, mem_ivalid_queue, mem_ierr_queue, mem);
update_mem_load(top->mem_iaddr_o, top->mem_ireq_o, mem_w, mem_latency, mem_sz, (unsigned char*)&(top->mem_irdata_i), (bool*)&(top->mem_irvalid_i), (bool*)&(top->mem_ierr_i), mem_idata_queue, mem_ivalid_queue, mem_ierr_queue, mem);


top->eval();
Expand All @@ -236,7 +250,7 @@ int main(int argc, char **argv) {

//Use memory mapped IO at address 0x400 to signal success or failure
char w_port;
if (check_memmapio(top->mem_addr_o, (top->mem_req_o && top->mem_we_o), 8, (unsigned char*)&(top->mem_wdata_o), 0x00000400u, &w_port)){
if (check_memmapio(top->mem_addr_o[0], (top->mem_req_o[0] && top->mem_we_o[0]), 8, (unsigned char*)&(top->mem_wdata_o[0]), 0x00000400u, &w_port)){
if (w_port == 0)
{
fprintf(stderr, "SUCCESS: TEST PASS - TEST %d - Output Match\n", v_test_failure+v_test_success+2);
Expand Down Expand Up @@ -323,15 +337,21 @@ int main(int argc, char **argv) {
free(dump_path);
free(line);
free(mem);
free(mem_rvalid_queue);
for(int i = 0; i < mem_ports; i++){
free(mem_rvalid_queue[i]);
for(int queue_pos = 0; queue_pos < mem_latency; queue_pos++)
{
free(mem_rdata_queue[i][queue_pos]);
}
free(mem_rdata_queue[i]);
free(mem_err_queue[i]);
}

for(int queue_pos = 0; queue_pos < mem_latency; queue_pos++)
{
free(mem_rdata_queue[queue_pos]);
free(mem_idata_queue[queue_pos]);
free(mem_idata_queue[queue_pos]);
}
free(mem_rdata_queue);
free(mem_idata_queue);
free(mem_err_queue);

fclose(fprogs);
fclose(fxreglog);
Expand Down
Loading