mirror of https://github.com/lnis-uofu/SOFA.git
[SOFA_HD] Updated verification script
This commit is contained in:
parent
5c12369380
commit
13fc082cb3
|
@ -1,3 +1,5 @@
|
||||||
|
##########################################################################################
|
||||||
|
##########################################################################################
|
||||||
|
|
||||||
SHELL=bash
|
SHELL=bash
|
||||||
PYTHON_EXEC=python3.8
|
PYTHON_EXEC=python3.8
|
||||||
|
@ -5,70 +7,54 @@ RERUN = 0
|
||||||
TB = top
|
TB = top
|
||||||
OPTIONS =
|
OPTIONS =
|
||||||
|
|
||||||
|
BLOCK_MAKE_ACTIONS=init_design place_opt clock_opt_cts
|
||||||
|
|
||||||
.SILENT:
|
.SILENT:
|
||||||
.ONESHELL:
|
.ONESHELL:
|
||||||
|
|
||||||
UpdatePostPnRNetlist:
|
RunTest:
|
||||||
source ../config.sh
|
source ../config.sh
|
||||||
DESIGN_NAME=$${TOP_MODULE:-$${DESIGN_NAME}}
|
VerificationFile=$${TECHNOLOGY}_tests
|
||||||
echo "Collecting files $${DESIGN_NAME}"
|
|
||||||
cp ../pnr/$${DESIGN_NAME}/outputs_icc2/$${DESIGN_NAME}_icv_in_design.pt.v . || true
|
|
||||||
cp ../$${DESIGN_NAME}/outputs_icc2/$${DESIGN_NAME}_icv_in_design.pt.v . || true
|
|
||||||
|
|
||||||
RunPostPnRTest:
|
|
||||||
source ../config.sh
|
|
||||||
INCLUDE_POSTPNR=$${INCLUDE_POSTPNR:-include_postpnr}
|
|
||||||
DESIGN_NAME=$${TOP_MODULE:-$${DESIGN_NAME}}
|
|
||||||
VerificationFile=$${TEST_FILE:-fpga_test}
|
|
||||||
# = = = = = = = = = = = = = = Log Information = = = = = = = = = = = =
|
|
||||||
echo "DESIGN_NAME = $${DESIGN_NAME}"
|
|
||||||
echo "VerificationFile = $${DESIGN_NAME}"
|
|
||||||
echo "INCLUDE_FILE = $${INCLUDE_POSTPNR}"
|
|
||||||
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
|
||||||
echo $${VerificationFile}
|
|
||||||
if [ ! -f "./$${VerificationFile}.py" ]; then
|
if [ ! -f "./$${VerificationFile}.py" ]; then
|
||||||
echo "Test file not found $${VerificationFile}.py"
|
VerificationFile=fpga_tests
|
||||||
fi
|
fi
|
||||||
echo "Using test file $${VerificationFile}.py"
|
echo "Using test file $${VerificationFile}.py"
|
||||||
Tests=`grep -A 1 "^@cocotb.test" ./$${VerificationFile}.py | grep "def" | sed "s/.*def \(.*\)(.*/\1/g"`
|
Tests=`grep -A 1 "@cocotb.test" ./$${VerificationFile}.py | grep "def" | sed "s/.*def \(.*\)(.*/\1/g"`
|
||||||
select RUN_TB in $${Tests}
|
select RUN_TB in $${Tests}
|
||||||
do
|
do
|
||||||
echo "Running $${RUN_TB} Test"
|
echo "Running $${RUN_TB} Test"
|
||||||
if [[ -d "$${RUN_TB}_run" ]] && [[ -z "$${RERUN}" ]]; then
|
if [[ -d "$${RUN_TB}_run" ]] && [[ -z "$${RERUN}" ]]; then
|
||||||
echo "Skipping copying source, which will skip the compilations";
|
echo "Skipping copying source";
|
||||||
cp *_tests.py ./$${RUN_TB}_run;
|
cp *_tests.py ./$${RUN_TB}_run;
|
||||||
cd $${RUN_TB}_run; break;
|
cd $${RUN_TB}_run; break;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# = = = = = = = = = = = Prepare Netlist = = = = = = = = = = = = = =
|
# = = = = = = = = = = = Prepare Netlist = = = = = = = = = = = = = =
|
||||||
# = = = = = = = = = = = Copy python test = = = = = = = = = = = = =
|
# = = = = = = = = = = = Copy python test = = = = = = = = = = = = =
|
||||||
mkdir -p "$${RUN_TB}_run"
|
mkdir -p "$${RUN_TB}_run"
|
||||||
cp $${VerificationFile}.py ./$${RUN_TB}_run
|
cp $${VerificationFile}.py ./$${RUN_TB}_run
|
||||||
cp $${DESIGN_NAME}_icv_in_design.pt.v ./$${RUN_TB}_run/$${DESIGN_NAME}_cocosim.v
|
# = = = = Make symbolic link to SRC | TaskConfigCopy | TESTBENCH
|
||||||
if [ -d "../*_Verilog/TaskConfigCopy" ]; then
|
SRCDir=`readlink -f ../*_Verilog/SRC`
|
||||||
TaskDir=`readlink -f ../*_Verilog/TaskConfigCopy`
|
rm -rf ./$${RUN_TB}_run/SRC && ln -s $${SRCDir} ./$${RUN_TB}_run
|
||||||
rm -rf ./$${RUN_TB}_run/TaskConfigCopy && ln -s $${TaskDir} ./$${RUN_TB}_run
|
TaskDir=`readlink -f ../*_Verilog/TaskConfigCopy`
|
||||||
elif [ -d "../*_task" ]; then
|
rm -rf ./$${RUN_TB}_run/TaskConfigCopy && ln -s $${TaskDir} ./$${RUN_TB}_run
|
||||||
TaskDir=`readlink -f ../*_task`
|
TestbenchDir=`readlink -f ../*_Verilog/TESTBENCH`
|
||||||
rm -rf ./$${RUN_TB}_run/TaskConfigCopy && ln -s $${TaskDir} ./$${RUN_TB}_run/TaskConfigCopy
|
rm -rf ./$${RUN_TB}_run/TESTBENCH && ln -s $${TestbenchDir} ./$${RUN_TB}_run
|
||||||
else
|
|
||||||
echo "Task configuration directory not found"
|
|
||||||
fi
|
|
||||||
# = = = = = = = = = = = Enter Run Directory = = = = = = = = = = = = =
|
|
||||||
cd $${RUN_TB}_run
|
|
||||||
cp ../INIT/$${INCLUDE_POSTPNR}.v ./fabric_netlists_cocosim.v
|
|
||||||
echo "\`include \"$$(readlink -f $${DESIGN_NAME}_cocosim.v)\"" >> ./fabric_netlists_cocosim.v
|
|
||||||
|
|
||||||
# = = = = = = = = = = = Insert Init Signals = = = = = = = = = = = =
|
# = = = = = = = = = = Enter Run Directory = = = = = = = = = = = = =
|
||||||
|
cd $${RUN_TB}_run
|
||||||
|
cp ./SRC/$${DESIGN_NAME}.v ./$${DESIGN_NAME}_cocosim.v
|
||||||
|
cp ./SRC/fabric_netlists.v ./fabric_netlists_cocosim.v
|
||||||
|
|
||||||
|
# = = = = = = = = = = Modify the netlist = = = = = = = = = = = = =
|
||||||
|
sed -i "s/SRC\/$${DESIGN_NAME}/$${DESIGN_NAME}_cocosim/g" fabric_netlists_cocosim.v
|
||||||
|
|
||||||
|
# Insert Init Signals
|
||||||
if test -f "../INIT/$${RUN_TB}_init.v"; then
|
if test -f "../INIT/$${RUN_TB}_init.v"; then
|
||||||
echo "Found Initialization file [../INIT/$${RUN_TB}_init.v]"
|
echo "Found initialization file"
|
||||||
modLineNo=$$(grep -n "module fpga_top" $${DESIGN_NAME}_cocosim.v | cut -f1 -d:)
|
sed -i "/endmodule/d" $${DESIGN_NAME}_cocosim.v
|
||||||
echo $${modLineNo}
|
cat ../INIT/$${RUN_TB}_init.v >> $${DESIGN_NAME}_cocosim.v
|
||||||
sed -i "$${modLineNo},\$${/endmodule/d}" $${DESIGN_NAME}_cocosim.v
|
printf "\nendmodule" >> $${DESIGN_NAME}_cocosim.v
|
||||||
cat ../INIT/$${RUN_TB}_init.v >> $${DESIGN_NAME}_cocosim.v
|
|
||||||
printf "\nendmodule" >> $${DESIGN_NAME}_cocosim.v
|
|
||||||
else
|
|
||||||
echo "No Initialization file found [../INIT/$${RUN_TB}_init.v]"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# = = = = = = = = Create Makefile to run = = = = = = = = = = = = = =
|
# = = = = = = = = Create Makefile to run = = = = = = = = = = = = = =
|
||||||
|
@ -81,4 +67,48 @@ RunPostPnRTest:
|
||||||
echo "include $(shell cocotb-config --makefiles)/Makefile.sim" >> Makefile
|
echo "include $(shell cocotb-config --makefiles)/Makefile.sim" >> Makefile
|
||||||
break
|
break
|
||||||
done
|
done
|
||||||
if [ -z "$$DRY_RUN" ]; then make; fi
|
make
|
||||||
|
|
||||||
|
GenerateNetlist:
|
||||||
|
cd .. && make clean all
|
||||||
|
|
||||||
|
GenerateTestBench:
|
||||||
|
cd .. && source ./FPGA22_SPY_Verification/generateTestbench.sh
|
||||||
|
|
||||||
|
GenerateSyntheticTestBench:
|
||||||
|
TestbenchDir=`readlink -f ../*_Verilog/TESTBENCH`
|
||||||
|
mkdir -p $$TestbenchDir/AllOne && cp $$TestbenchDir/top/* $$TestbenchDir/AllOne/
|
||||||
|
mkdir -p $$TestbenchDir/AllZero && cp $$TestbenchDir/top/* $$TestbenchDir/AllZero/
|
||||||
|
mkdir -p $$TestbenchDir/Patterned10 && cp $$TestbenchDir/top/* $$TestbenchDir/Patterned10/
|
||||||
|
|
||||||
|
BitStreamLength=(`wc -c $$TestbenchDir/AllOne/fabric_bitstream.bit`)
|
||||||
|
BitStreamLength=$${BitStreamLength[0]}
|
||||||
|
echo "Bitstream Length is $$BitStreamLength "
|
||||||
|
|
||||||
|
for ((i=0; i<$$BitStreamLength; i++)); do printf "1"; done > $$TestbenchDir/AllOne/fabric_bitstream.bit
|
||||||
|
echo "Created AllOne Bitstream"
|
||||||
|
for ((i=0; i<$$BitStreamLength; i++)); do printf "0"; done > $$TestbenchDir/AllZero/fabric_bitstream.bit
|
||||||
|
echo "Created AllZero Bitstream"
|
||||||
|
for ((i=0; i<$$BitStreamLength; i=i+2)); do printf "10"; done > $$TestbenchDir/Patterned10/fabric_bitstream.bit
|
||||||
|
echo "Created Patterned10 Bitstream"
|
||||||
|
|
||||||
|
# Creating PatternedBitstreams
|
||||||
|
PATT=10110
|
||||||
|
PATTLen=`echo $${#PATT}`
|
||||||
|
Remainder=`echo $$(($$BitStreamLength % $$PATTLen))`
|
||||||
|
mkdir -p $$TestbenchDir/Patterned$${PATT} && cp $$TestbenchDir/top/* $$TestbenchDir/Patterned$${PATT}/
|
||||||
|
for ((i=0; i<($$BitStreamLength-$$Remainder); i=i+$$PATTLen)); do printf $$PATT; done > $$TestbenchDir/Patterned$${PATT}/fabric_bitstream.bit
|
||||||
|
printf "$${PATT:0:$$Remainder}">> $$TestbenchDir/Patterned$${PATT}/fabric_bitstream.bit
|
||||||
|
echo "Created Patterned$${PATT} Bitstream"
|
||||||
|
|
||||||
|
# Creating PatternedBitstreams
|
||||||
|
PATT=10110001
|
||||||
|
PATTLen=`echo $${#PATT}`
|
||||||
|
Remainder=`echo $$(($$BitStreamLength % $$PATTLen))`
|
||||||
|
mkdir -p $$TestbenchDir/Patterned$${PATT} && cp $$TestbenchDir/top/* $$TestbenchDir/Patterned$${PATT}/
|
||||||
|
for ((i=0; i<($$BitStreamLength-$$Remainder); i=i+$$PATTLen)); do printf $$PATT; done > $$TestbenchDir/Patterned$${PATT}/fabric_bitstream.bit
|
||||||
|
printf "$${PATT:0:$$Remainder}" >> $$TestbenchDir/Patterned$${PATT}/fabric_bitstream.bit
|
||||||
|
echo "Created Patterned$${PATT} Bitstream"
|
||||||
|
|
||||||
|
|
||||||
|
-include Makefile_project
|
|
@ -1854,3 +1854,170 @@ Passed 1 tests (0 skipped)
|
||||||
*************************************************************************************
|
*************************************************************************************
|
||||||
|
|
||||||
Shutting down...
|
Shutting down...
|
||||||
|
Found test skywater_tests.ScanChainTestFull
|
||||||
|
Running test 1/1: ScanChainTestFull
|
||||||
|
Starting test: "ScanChainTestFull"
|
||||||
|
Description: None
|
||||||
|
Signal received at grid_clb_1__12_ at 8
|
||||||
|
Signal received at grid_clb_1__11_ at 8
|
||||||
|
Signal received at grid_clb_1__10_ at 8
|
||||||
|
Signal received at grid_clb_1__9_ at 8
|
||||||
|
Signal received at grid_clb_1__8_ at 8
|
||||||
|
Signal received at grid_clb_1__7_ at 8
|
||||||
|
Signal received at grid_clb_1__6_ at 8
|
||||||
|
Signal received at grid_clb_1__5_ at 8
|
||||||
|
Signal received at grid_clb_1__4_ at 8
|
||||||
|
Signal received at grid_clb_1__3_ at 8
|
||||||
|
Signal received at grid_clb_1__2_ at 8
|
||||||
|
Signal received at grid_clb_1__1_ at 8
|
||||||
|
Signal received at grid_clb_2__1_ at 8
|
||||||
|
Signal received at grid_clb_2__2_ at 8
|
||||||
|
Signal received at grid_clb_2__3_ at 8
|
||||||
|
Signal received at grid_clb_2__4_ at 8
|
||||||
|
Signal received at grid_clb_2__5_ at 8
|
||||||
|
Signal received at grid_clb_2__6_ at 8
|
||||||
|
Signal received at grid_clb_2__7_ at 8
|
||||||
|
Signal received at grid_clb_2__8_ at 8
|
||||||
|
Signal received at grid_clb_2__9_ at 8
|
||||||
|
Signal received at grid_clb_2__10_ at 8
|
||||||
|
Signal received at grid_clb_2__11_ at 8
|
||||||
|
Signal received at grid_clb_2__12_ at 8
|
||||||
|
Signal received at grid_clb_3__12_ at 8
|
||||||
|
Signal received at grid_clb_3__11_ at 9
|
||||||
|
Signal received at grid_clb_3__10_ at 8
|
||||||
|
Signal received at grid_clb_3__9_ at 8
|
||||||
|
Signal received at grid_clb_3__8_ at 8
|
||||||
|
Signal received at grid_clb_3__7_ at 8
|
||||||
|
Signal received at grid_clb_3__6_ at 8
|
||||||
|
Signal received at grid_clb_3__5_ at 8
|
||||||
|
Signal received at grid_clb_3__4_ at 8
|
||||||
|
Signal received at grid_clb_3__3_ at 8
|
||||||
|
Signal received at grid_clb_3__2_ at 8
|
||||||
|
Signal received at grid_clb_3__1_ at 8
|
||||||
|
Signal received at grid_clb_4__1_ at 8
|
||||||
|
Signal received at grid_clb_4__2_ at 8
|
||||||
|
Signal received at grid_clb_4__3_ at 8
|
||||||
|
Signal received at grid_clb_4__4_ at 8
|
||||||
|
Signal received at grid_clb_4__5_ at 8
|
||||||
|
Signal received at grid_clb_4__6_ at 8
|
||||||
|
Signal received at grid_clb_4__7_ at 8
|
||||||
|
Signal received at grid_clb_4__8_ at 8
|
||||||
|
Signal received at grid_clb_4__9_ at 8
|
||||||
|
Signal received at grid_clb_4__10_ at 8
|
||||||
|
Signal received at grid_clb_4__11_ at 8
|
||||||
|
Signal received at grid_clb_4__12_ at 8
|
||||||
|
Signal received at grid_clb_5__12_ at 8
|
||||||
|
Signal received at grid_clb_5__11_ at 8
|
||||||
|
Signal received at grid_clb_5__10_ at 8
|
||||||
|
Signal received at grid_clb_5__9_ at 8
|
||||||
|
Signal received at grid_clb_5__8_ at 8
|
||||||
|
Signal received at grid_clb_5__7_ at 8
|
||||||
|
Signal received at grid_clb_5__6_ at 8
|
||||||
|
Signal received at grid_clb_5__5_ at 8
|
||||||
|
Signal received at grid_clb_5__4_ at 8
|
||||||
|
Signal received at grid_clb_5__3_ at 8
|
||||||
|
Signal received at grid_clb_5__2_ at 8
|
||||||
|
Signal received at grid_clb_5__1_ at 8
|
||||||
|
Signal received at grid_clb_6__1_ at 8
|
||||||
|
Signal received at grid_clb_6__2_ at 8
|
||||||
|
Signal received at grid_clb_6__3_ at 8
|
||||||
|
Signal received at grid_clb_6__4_ at 8
|
||||||
|
Signal received at grid_clb_6__5_ at 8
|
||||||
|
Signal received at grid_clb_6__6_ at 8
|
||||||
|
Signal received at grid_clb_6__7_ at 8
|
||||||
|
Signal received at grid_clb_6__8_ at 8
|
||||||
|
Signal received at grid_clb_6__9_ at 8
|
||||||
|
Signal received at grid_clb_6__10_ at 8
|
||||||
|
Signal received at grid_clb_6__11_ at 8
|
||||||
|
Signal received at grid_clb_6__12_ at 8
|
||||||
|
Signal received at grid_clb_7__12_ at 8
|
||||||
|
Signal received at grid_clb_7__11_ at 8
|
||||||
|
Signal received at grid_clb_7__10_ at 8
|
||||||
|
Signal received at grid_clb_7__9_ at 8
|
||||||
|
Signal received at grid_clb_7__8_ at 8
|
||||||
|
Signal received at grid_clb_7__7_ at 8
|
||||||
|
Signal received at grid_clb_7__6_ at 8
|
||||||
|
Signal received at grid_clb_7__5_ at 8
|
||||||
|
Signal received at grid_clb_7__4_ at 8
|
||||||
|
Signal received at grid_clb_7__3_ at 8
|
||||||
|
Signal received at grid_clb_7__2_ at 8
|
||||||
|
Signal received at grid_clb_7__1_ at 8
|
||||||
|
Signal received at grid_clb_8__1_ at 8
|
||||||
|
Signal received at grid_clb_8__2_ at 8
|
||||||
|
Signal received at grid_clb_8__3_ at 8
|
||||||
|
Signal received at grid_clb_8__4_ at 8
|
||||||
|
Signal received at grid_clb_8__5_ at 8
|
||||||
|
Signal received at grid_clb_8__6_ at 8
|
||||||
|
Signal received at grid_clb_8__7_ at 8
|
||||||
|
Signal received at grid_clb_8__8_ at 8
|
||||||
|
Signal received at grid_clb_8__9_ at 8
|
||||||
|
Signal received at grid_clb_8__10_ at 8
|
||||||
|
Signal received at grid_clb_8__11_ at 8
|
||||||
|
Signal received at grid_clb_8__12_ at 8
|
||||||
|
Signal received at grid_clb_9__12_ at 8
|
||||||
|
Signal received at grid_clb_9__11_ at 8
|
||||||
|
Signal received at grid_clb_9__10_ at 8
|
||||||
|
Signal received at grid_clb_9__9_ at 8
|
||||||
|
Signal received at grid_clb_9__8_ at 8
|
||||||
|
Signal received at grid_clb_9__7_ at 8
|
||||||
|
Signal received at grid_clb_9__6_ at 8
|
||||||
|
Signal received at grid_clb_9__5_ at 8
|
||||||
|
Signal received at grid_clb_9__4_ at 8
|
||||||
|
Signal received at grid_clb_9__3_ at 8
|
||||||
|
Signal received at grid_clb_9__2_ at 8
|
||||||
|
Signal received at grid_clb_9__1_ at 8
|
||||||
|
Signal received at grid_clb_10__1_ at 8
|
||||||
|
Signal received at grid_clb_10__2_ at 8
|
||||||
|
Signal received at grid_clb_10__3_ at 8
|
||||||
|
Signal received at grid_clb_10__4_ at 8
|
||||||
|
Signal received at grid_clb_10__5_ at 8
|
||||||
|
Signal received at grid_clb_10__6_ at 8
|
||||||
|
Signal received at grid_clb_10__7_ at 8
|
||||||
|
Signal received at grid_clb_10__8_ at 8
|
||||||
|
Signal received at grid_clb_10__9_ at 8
|
||||||
|
Signal received at grid_clb_10__10_ at 8
|
||||||
|
Signal received at grid_clb_10__11_ at 8
|
||||||
|
Signal received at grid_clb_10__12_ at 8
|
||||||
|
Signal received at grid_clb_11__12_ at 8
|
||||||
|
Signal received at grid_clb_11__11_ at 8
|
||||||
|
Signal received at grid_clb_11__10_ at 8
|
||||||
|
Signal received at grid_clb_11__9_ at 8
|
||||||
|
Signal received at grid_clb_11__8_ at 8
|
||||||
|
Signal received at grid_clb_11__7_ at 8
|
||||||
|
Signal received at grid_clb_11__6_ at 8
|
||||||
|
Signal received at grid_clb_11__5_ at 8
|
||||||
|
Signal received at grid_clb_11__4_ at 8
|
||||||
|
Signal received at grid_clb_11__3_ at 8
|
||||||
|
Signal received at grid_clb_11__2_ at 8
|
||||||
|
Signal received at grid_clb_11__1_ at 8
|
||||||
|
Signal received at grid_clb_12__1_ at 8
|
||||||
|
Signal received at grid_clb_12__2_ at 8
|
||||||
|
Signal received at grid_clb_12__3_ at 8
|
||||||
|
Signal received at grid_clb_12__4_ at 8
|
||||||
|
Signal received at grid_clb_12__5_ at 8
|
||||||
|
Signal received at grid_clb_12__6_ at 8
|
||||||
|
Signal received at grid_clb_12__7_ at 8
|
||||||
|
Signal received at grid_clb_12__8_ at 8
|
||||||
|
Signal received at grid_clb_12__9_ at 8
|
||||||
|
Signal received at grid_clb_12__10_ at 8
|
||||||
|
Signal received at grid_clb_12__11_ at 8
|
||||||
|
Signal received at grid_clb_12__12_ at 8
|
||||||
|
Simulation Finished in clocks 1152
|
||||||
|
Per Grid 8.0
|
||||||
|
Test Passed: ScanChainTestFull
|
||||||
|
Passed 1 tests (0 skipped)
|
||||||
|
******************************************************************************************
|
||||||
|
** TEST PASS/FAIL SIM TIME(NS) REAL TIME(S) RATIO(NS/S) **
|
||||||
|
******************************************************************************************
|
||||||
|
** skywater_tests.ScanChainTestFull PASS 11580.00 0.99 11725.64 **
|
||||||
|
******************************************************************************************
|
||||||
|
|
||||||
|
*************************************************************************************
|
||||||
|
** ERRORS : 0 **
|
||||||
|
*************************************************************************************
|
||||||
|
** SIM TIME : 11580.00 NS **
|
||||||
|
** REAL TIME : 1.02 S **
|
||||||
|
** SIM / REAL TIME : 11333.51 NS/S **
|
||||||
|
*************************************************************************************
|
||||||
|
|
||||||
|
Shutting down...
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,330 @@
|
||||||
|
import random
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import glob
|
||||||
|
import math
|
||||||
|
import cocotb
|
||||||
|
import logging
|
||||||
|
import filecmp
|
||||||
|
from logging.handlers import RotatingFileHandler
|
||||||
|
from collections import OrderedDict
|
||||||
|
from pprint import pprint
|
||||||
|
from xml.dom import minidom
|
||||||
|
from cocotb.binary import BinaryValue
|
||||||
|
from cocotb.log import SimLogFormatter
|
||||||
|
from cocotb.clock import Clock
|
||||||
|
from cocotb import wavedrom
|
||||||
|
from cocotb.handle import Force, Release, Deposit
|
||||||
|
from cocotb.monitors import Monitor
|
||||||
|
from cocotb.scoreboard import Scoreboard
|
||||||
|
from cocotb.triggers import FallingEdge, RisingEdge, Timer, ClockCycles
|
||||||
|
|
||||||
|
root_logger = logging.getLogger()
|
||||||
|
|
||||||
|
|
||||||
|
file_handler = RotatingFileHandler(
|
||||||
|
"run.log", maxBytes=(5 * 1024 * 1024), backupCount=2)
|
||||||
|
# file_handler.setFormatter(SimLogFormatter())
|
||||||
|
root_logger.addHandler(file_handler)
|
||||||
|
|
||||||
|
|
||||||
|
@cocotb.test()
|
||||||
|
async def AutoConfigureTest(dut):
|
||||||
|
|
||||||
|
CFFPaths = CreateCCFFChainPaths(dut)
|
||||||
|
TB = cocotb.os.environ['TB']
|
||||||
|
BitFile = os.path.join(".", "TESTBENCH", TB, "fabric_bitstream.xml")
|
||||||
|
# Create a 10us period clock on port clk
|
||||||
|
clock = Clock(dut.prog_clk_pad, 10, units="ns")
|
||||||
|
cocotb.fork(clock.start()) # Start the clock
|
||||||
|
|
||||||
|
# Initializing Chip with reset
|
||||||
|
dut.pReset_pad <= 1
|
||||||
|
dut.Reset_pad <= 1
|
||||||
|
await FallingEdge(dut.prog_clk_pad)
|
||||||
|
await FallingEdge(dut.prog_clk_pad)
|
||||||
|
|
||||||
|
dut._log.info(f"Testbench {BitFile}")
|
||||||
|
|
||||||
|
# Initializing Chip with reset
|
||||||
|
dut.pReset_pad <= 0
|
||||||
|
dut.Reset_pad <= 0
|
||||||
|
|
||||||
|
AutoConfigure(dut, BitFile, CFFPaths)
|
||||||
|
await RisingEdge(dut.prog_clk_pad)
|
||||||
|
with open("AfterProgramming.data", "w") as fp:
|
||||||
|
for eachPath in CFFPaths:
|
||||||
|
val = eval(eachPath)
|
||||||
|
if "0" in val.value.binstr:
|
||||||
|
dut._log.error(f"Wrong path {eachPath} {val.value}")
|
||||||
|
val = "\n".join(list(val.value.binstr))
|
||||||
|
fp.write(val+"\n")
|
||||||
|
await ClockCycles(dut.prog_clk_pad, 1)
|
||||||
|
|
||||||
|
|
||||||
|
@cocotb.test()
|
||||||
|
async def FastConfigureAndResetTest(dut):
|
||||||
|
'''
|
||||||
|
This test configures the fabric with given bitstream and
|
||||||
|
then resets it for one clock cycle and checks for all paths for logice 0
|
||||||
|
'''
|
||||||
|
|
||||||
|
chainLength, CFFPaths = CreateCCFFChainPaths(dut)
|
||||||
|
TB = cocotb.os.environ['TB']
|
||||||
|
BitFile = os.path.join(".", "TESTBENCH", TB, "fabric_bitstream.bit")
|
||||||
|
|
||||||
|
# Create a 10ns period clock on port clk
|
||||||
|
clock = Clock(dut.prog_clk_pad, 10, units="ns")
|
||||||
|
cocotb.fork(clock.start(start_high=True)) # Start the clock
|
||||||
|
SaveConfiguration(CFFPaths, "BeforeInit.data", style="adjusted")
|
||||||
|
|
||||||
|
# Initializing Chip with reset
|
||||||
|
dut.pReset_pad <= 1
|
||||||
|
dut.Reset_pad <= 1
|
||||||
|
await FallingEdge(dut.prog_clk_pad)
|
||||||
|
await FallingEdge(dut.prog_clk_pad)
|
||||||
|
|
||||||
|
# Initializing Chip with reset
|
||||||
|
dut.pReset_pad <= 0
|
||||||
|
dut.Reset_pad <= 0
|
||||||
|
dut.ccff_head_pad <= 0
|
||||||
|
SaveConfiguration(CFFPaths, "BeforeProgramming.data", style="adjusted")
|
||||||
|
|
||||||
|
await AutoConfigure(dut, BitFile, CFFPaths, chainLength)
|
||||||
|
# await ProgramPhase(dut, BitFile)
|
||||||
|
|
||||||
|
# await RisingEdge(dut.prog_clk_pad)
|
||||||
|
SaveConfiguration(CFFPaths, "AfterProgramming.data", style="adjusted")
|
||||||
|
|
||||||
|
for _ in range(8):
|
||||||
|
await FallingEdge(dut.prog_clk_pad)
|
||||||
|
|
||||||
|
SaveConfiguration(CFFPaths, "After10Clocks.data", style="adjusted")
|
||||||
|
|
||||||
|
# Reset device
|
||||||
|
dut.pReset_pad <= 1
|
||||||
|
await FallingEdge(dut.prog_clk_pad)
|
||||||
|
dut.pReset_pad <= 0
|
||||||
|
|
||||||
|
# Check if all FF are Reset
|
||||||
|
for _, eachModule in CFFPaths.items():
|
||||||
|
for eachPath in eachModule:
|
||||||
|
val = eachPath["obj"].value.binstr
|
||||||
|
if "1" in val:
|
||||||
|
dut._log.error(f"Failed to reset {val} {eachPath['name']}")
|
||||||
|
dut._log.error(eachPath["obj"].value)
|
||||||
|
|
||||||
|
SaveConfiguration(CFFPaths, "AfterReset.data", style="adjusted")
|
||||||
|
await RisingEdge(dut.prog_clk_pad)
|
||||||
|
|
||||||
|
|
||||||
|
@cocotb.test()
|
||||||
|
async def ConfigChainTestFull(dut):
|
||||||
|
|
||||||
|
DESIGN_NAME = os.environ.get('DESIGN_NAME', 'fpga_top')
|
||||||
|
ProgClockPort = dut.prog_clk_pad if DESIGN_NAME == 'fpga_top' else dut.prog_clk
|
||||||
|
|
||||||
|
# Create a 10us period clock on port clk
|
||||||
|
clock = Clock(ProgClockPort, 10, units="ns")
|
||||||
|
cocotb.fork(clock.start()) # Start the clock
|
||||||
|
|
||||||
|
# Initializing Chip with reset
|
||||||
|
dut.pReset_pad <= 1
|
||||||
|
dut.Reset_pad <= 1
|
||||||
|
await FallingEdge(ProgClockPort)
|
||||||
|
await FallingEdge(ProgClockPort)
|
||||||
|
|
||||||
|
# Initializing Chip with reset
|
||||||
|
dut.pReset_pad <= 0
|
||||||
|
dut.Reset_pad <= 0
|
||||||
|
|
||||||
|
# Push single bit in chain
|
||||||
|
dut.ccff_head_pad <= 1
|
||||||
|
await FallingEdge(ProgClockPort)
|
||||||
|
dut.ccff_head_pad <= 0
|
||||||
|
|
||||||
|
# Check CCFF_tail of each module in sequence
|
||||||
|
CCFFChain = CreateCCFFChain()
|
||||||
|
ChainTrack = 0
|
||||||
|
PrevCapture = 0
|
||||||
|
for i in range(sys.maxsize):
|
||||||
|
await FallingEdge(ProgClockPort)
|
||||||
|
if eval(CCFFChain[ChainTrack]) == 1:
|
||||||
|
dut._log.info(
|
||||||
|
f"{ChainTrack} Received at {CCFFChain[ChainTrack]}" +
|
||||||
|
f" after {i-PrevCapture} Clocks at [{i}]")
|
||||||
|
PrevCapture = i
|
||||||
|
ChainTrack += 1
|
||||||
|
if ChainTrack == len(CCFFChain):
|
||||||
|
break
|
||||||
|
dut._log.info(f"Total bitstream length {i} bits")
|
||||||
|
|
||||||
|
|
||||||
|
# ###================================================================
|
||||||
|
# = = = = = = = = = = Utils Functions = = = = = = = = = = = = = = = =
|
||||||
|
# ###================================================================
|
||||||
|
|
||||||
|
|
||||||
|
@cocotb.coroutine
|
||||||
|
async def ProgramPhase(dut, BitFile, maxCycles=sys.maxsize):
|
||||||
|
dut.pReset_pad = 0
|
||||||
|
bitCount = 0
|
||||||
|
with open(BitFile, "r") as fp:
|
||||||
|
dut._log.info(f"Bitfile opened : {BitFile}")
|
||||||
|
while bitCount < maxCycles:
|
||||||
|
c = fp.read(1)
|
||||||
|
if not c in ["0", "1"]:
|
||||||
|
dut._log.info(f"Configured device with {bitCount} bits")
|
||||||
|
break
|
||||||
|
bitCount += 1
|
||||||
|
if (bitCount % 50) == 0:
|
||||||
|
dut._log.info(f"Writen {bitCount} bits")
|
||||||
|
dut.ccff_head_pad = int(c)
|
||||||
|
await FallingEdge(dut.prog_clk_pad)
|
||||||
|
|
||||||
|
|
||||||
|
@cocotb.coroutine
|
||||||
|
async def AutoConfigure(dut, BitFile, ccPaths, BitstreamLen):
|
||||||
|
TotalBitsCount = 0
|
||||||
|
PreviousSync = 0
|
||||||
|
# Locking Signal
|
||||||
|
with open(BitFile, "r") as fp:
|
||||||
|
dut._log.info(f"Bitfile opened {BitFile}")
|
||||||
|
syncPts = math.ceil(BitstreamLen/4800)
|
||||||
|
InitialBits = [int(i) for i in list(fp.read(syncPts+1))]
|
||||||
|
dut._log.info(f"Will make total {syncPts} sync {InitialBits}")
|
||||||
|
for inst, eachModule in ccPaths.items():
|
||||||
|
BitsCount = 0
|
||||||
|
for eachPath in eachModule:
|
||||||
|
size = eachPath["width"]
|
||||||
|
BitsCount += size
|
||||||
|
try:
|
||||||
|
Stream = fp.read(size)
|
||||||
|
bits = int(Stream, 2)
|
||||||
|
except:
|
||||||
|
dut._log.info(f"Padding Zero")
|
||||||
|
bits = 0
|
||||||
|
eachPath["obj"] <= Force(bits)
|
||||||
|
TotalBitsCount += BitsCount
|
||||||
|
dut._log.info(f"Configured {inst} with {BitsCount} bits ")
|
||||||
|
dut.ccff_head_pad <= InitialBits.pop()
|
||||||
|
await FallingEdge(dut.prog_clk_pad)
|
||||||
|
|
||||||
|
# Releasing Signals
|
||||||
|
PreviousSync = 0
|
||||||
|
TotalBitsCount = 0
|
||||||
|
for inst, eachModule in ccPaths.items():
|
||||||
|
for eachPath in eachModule:
|
||||||
|
eachPath["obj"] <= Release()
|
||||||
|
TotalBitsCount += eachPath["width"]
|
||||||
|
if (TotalBitsCount-PreviousSync) > 4800:
|
||||||
|
dut.ccff_head_pad <= InitialBits.pop()
|
||||||
|
await FallingEdge(dut.prog_clk_pad)
|
||||||
|
PreviousSync = TotalBitsCount
|
||||||
|
dut._log.info(f"Releasing config of {inst}")
|
||||||
|
dut.ccff_head_pad <= InitialBits.pop()
|
||||||
|
await FallingEdge(dut.prog_clk_pad)
|
||||||
|
dut._log.info(f"Configured {TotalBitsCount} bits")
|
||||||
|
|
||||||
|
|
||||||
|
def SaveConfiguration(CFFPaths, filename, style="default"):
|
||||||
|
lineW = 0
|
||||||
|
with open(filename, "w") as fp:
|
||||||
|
for _, eachModule in CFFPaths.items():
|
||||||
|
for eachPath in eachModule:
|
||||||
|
val = eachPath["obj"].value.binstr
|
||||||
|
if style == 'default':
|
||||||
|
val = "\n".join(list(val))
|
||||||
|
fp.write(val+"\n")
|
||||||
|
elif style == "bitstream":
|
||||||
|
fp.write(val)
|
||||||
|
elif style == "detailed":
|
||||||
|
fp.write(f"{eachPath['name']} {val}\n")
|
||||||
|
elif style == "adjusted":
|
||||||
|
for eachC in val:
|
||||||
|
fp.write(eachC)
|
||||||
|
lineW += 1
|
||||||
|
if (lineW == 32):
|
||||||
|
fp.write("\n")
|
||||||
|
lineW = 0
|
||||||
|
|
||||||
|
|
||||||
|
def CreateCCFFChain():
|
||||||
|
CCFFChain = []
|
||||||
|
mydoc = minidom.parse(
|
||||||
|
glob.glob("./TaskConfigCopy/*_task/arch/fabric_key.xml")[0])
|
||||||
|
items = mydoc.getElementsByTagName('key')
|
||||||
|
for elem in items:
|
||||||
|
inst = elem.attributes['alias'].value
|
||||||
|
CCFFChain.append(f"dut.fpga_core_uut.{inst}.ccff_tail")
|
||||||
|
return CCFFChain
|
||||||
|
|
||||||
|
|
||||||
|
def returnPaths(Node, PathList):
|
||||||
|
Nodes = [e for e in Node.childNodes if not isinstance(e, minidom.Text)]
|
||||||
|
# pprint(Nodes)
|
||||||
|
for eachN in Nodes:
|
||||||
|
eachNChild = [
|
||||||
|
e for e in eachN.childNodes if not isinstance(e, minidom.Text)]
|
||||||
|
Bitstream = [e for e in eachNChild if e.tagName == "bitstream"]
|
||||||
|
if Bitstream:
|
||||||
|
Hier = eachN.getElementsByTagName("hierarchy")[0]
|
||||||
|
path = [each.attributes["name"].value
|
||||||
|
for each in Hier.getElementsByTagName("instance")]
|
||||||
|
path = ".".join(path).replace('fpga_top', 'dut.fpga_core_uut')
|
||||||
|
|
||||||
|
bitEles = Bitstream[0].getElementsByTagName("bit")
|
||||||
|
ports = [path + "." + each.attributes["memory_port"].value.split("[")[0]
|
||||||
|
for each in bitEles[:1]]
|
||||||
|
length = len(bitEles)
|
||||||
|
value = "".join([e.attributes["value"].value for e in bitEles])
|
||||||
|
PathList.append({
|
||||||
|
"name": ports[0],
|
||||||
|
"width": length,
|
||||||
|
"value": value
|
||||||
|
})
|
||||||
|
elif eachN.tagName == "bitstream_block":
|
||||||
|
returnPaths(eachN, PathList)
|
||||||
|
|
||||||
|
|
||||||
|
def get_modules():
|
||||||
|
FabricKey = minidom.parse(
|
||||||
|
glob.glob("./TaskConfigCopy/*_task/arch/fabric_key.xml")[0])
|
||||||
|
items = FabricKey.getElementsByTagName('key')
|
||||||
|
return [elem.attributes['alias'].value for elem in items]
|
||||||
|
|
||||||
|
|
||||||
|
def CreateCCFFChainPaths(dut):
|
||||||
|
BitstreamXML = minidom.parse(
|
||||||
|
glob.glob("./TESTBENCH/top/fabric_indepenent_bitstream.xml")[0])
|
||||||
|
|
||||||
|
ModulesDict = {}
|
||||||
|
BT_BLocks = BitstreamXML.getElementsByTagName('bitstream_block')
|
||||||
|
for element in BT_BLocks:
|
||||||
|
if element.getAttribute('hierarchy_level') == "1":
|
||||||
|
ModulesDict[element.attributes['name'].value] = element
|
||||||
|
|
||||||
|
FabricKey = minidom.parse(
|
||||||
|
glob.glob("./TaskConfigCopy/*_task/arch/fabric_key.xml")[0])
|
||||||
|
items = FabricKey.getElementsByTagName('key')
|
||||||
|
|
||||||
|
pathList = OrderedDict()
|
||||||
|
chainLength = 0
|
||||||
|
|
||||||
|
for elem in items:
|
||||||
|
modulePaths = []
|
||||||
|
moduleLen = 0
|
||||||
|
inst = elem.attributes['alias'].value
|
||||||
|
returnPaths(ModulesDict[inst], modulePaths)
|
||||||
|
for eachEle in modulePaths:
|
||||||
|
eachEle["obj"] = eval(eachEle["name"])
|
||||||
|
moduleLen += eachEle["width"]
|
||||||
|
pathList[inst] = modulePaths
|
||||||
|
chainLength += moduleLen
|
||||||
|
return (chainLength, pathList)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
CC = CreateCCFFChainPaths(None)
|
||||||
|
pprint(CC["grid_clb_1__2_"][:5])
|
||||||
|
pprint(len(CC["grid_clb_1__2_"]))
|
|
@ -89,6 +89,7 @@ async def ConfigChainTestFull(dut):
|
||||||
TestFailure(
|
TestFailure(
|
||||||
f"Expected 8 ticks on module {ModuleName} received {CLKTick}")
|
f"Expected 8 ticks on module {ModuleName} received {CLKTick}")
|
||||||
end_ccff_time = get_sim_time(units='ns')
|
end_ccff_time = get_sim_time(units='ns')
|
||||||
|
await ClockCycles(prog_clk, 10)
|
||||||
TotalClock = math.ceil((end_ccff_time-start_ccff_time)/PCLK_PERIOD)
|
TotalClock = math.ceil((end_ccff_time-start_ccff_time)/PCLK_PERIOD)
|
||||||
dut._log.info(f"Simulation Finished in clocks {TotalClock}")
|
dut._log.info(f"Simulation Finished in clocks {TotalClock}")
|
||||||
except SimTimeoutError:
|
except SimTimeoutError:
|
||||||
|
@ -146,6 +147,7 @@ async def ScanChainTestFull(dut):
|
||||||
f"Expected 8 ticks on module {ModuleName} received {CLKTick}")
|
f"Expected 8 ticks on module {ModuleName} received {CLKTick}")
|
||||||
end_scff_time = get_sim_time(units='ns')
|
end_scff_time = get_sim_time(units='ns')
|
||||||
TotalClock = math.ceil((end_scff_time-start_scff_time)/CLK_PERIOD)
|
TotalClock = math.ceil((end_scff_time-start_scff_time)/CLK_PERIOD)
|
||||||
|
await ClockCycles(clk, 10)
|
||||||
dut._log.info(f"Simulation Finished in clocks {TotalClock}")
|
dut._log.info(f"Simulation Finished in clocks {TotalClock}")
|
||||||
dut._log.info(f"Per Grid {TotalClock/(PConf['FPGA_SIZE_X']**2)}")
|
dut._log.info(f"Per Grid {TotalClock/(PConf['FPGA_SIZE_X']**2)}")
|
||||||
except SimTimeoutError:
|
except SimTimeoutError:
|
||||||
|
|
Loading…
Reference in New Issue