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
|
||||
PYTHON_EXEC=python3.8
|
||||
|
@ -5,70 +7,54 @@ RERUN = 0
|
|||
TB = top
|
||||
OPTIONS =
|
||||
|
||||
BLOCK_MAKE_ACTIONS=init_design place_opt clock_opt_cts
|
||||
|
||||
.SILENT:
|
||||
.ONESHELL:
|
||||
|
||||
UpdatePostPnRNetlist:
|
||||
RunTest:
|
||||
source ../config.sh
|
||||
DESIGN_NAME=$${TOP_MODULE:-$${DESIGN_NAME}}
|
||||
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}
|
||||
VerificationFile=$${TECHNOLOGY}_tests
|
||||
if [ ! -f "./$${VerificationFile}.py" ]; then
|
||||
echo "Test file not found $${VerificationFile}.py"
|
||||
VerificationFile=fpga_tests
|
||||
fi
|
||||
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}
|
||||
do
|
||||
echo "Running $${RUN_TB} Test"
|
||||
if [[ -d "$${RUN_TB}_run" ]] && [[ -z "$${RERUN}" ]]; then
|
||||
echo "Skipping copying source, which will skip the compilations";
|
||||
cp *_tests.py ./$${RUN_TB}_run;
|
||||
cd $${RUN_TB}_run; break;
|
||||
echo "Skipping copying source";
|
||||
cp *_tests.py ./$${RUN_TB}_run;
|
||||
cd $${RUN_TB}_run; break;
|
||||
fi
|
||||
|
||||
# = = = = = = = = = = = Prepare Netlist = = = = = = = = = = = = = =
|
||||
# = = = = = = = = = = = Copy python test = = = = = = = = = = = = =
|
||||
mkdir -p "$${RUN_TB}_run"
|
||||
cp $${VerificationFile}.py ./$${RUN_TB}_run
|
||||
cp $${DESIGN_NAME}_icv_in_design.pt.v ./$${RUN_TB}_run/$${DESIGN_NAME}_cocosim.v
|
||||
if [ -d "../*_Verilog/TaskConfigCopy" ]; then
|
||||
TaskDir=`readlink -f ../*_Verilog/TaskConfigCopy`
|
||||
rm -rf ./$${RUN_TB}_run/TaskConfigCopy && ln -s $${TaskDir} ./$${RUN_TB}_run
|
||||
elif [ -d "../*_task" ]; then
|
||||
TaskDir=`readlink -f ../*_task`
|
||||
rm -rf ./$${RUN_TB}_run/TaskConfigCopy && ln -s $${TaskDir} ./$${RUN_TB}_run/TaskConfigCopy
|
||||
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
|
||||
# = = = = Make symbolic link to SRC | TaskConfigCopy | TESTBENCH
|
||||
SRCDir=`readlink -f ../*_Verilog/SRC`
|
||||
rm -rf ./$${RUN_TB}_run/SRC && ln -s $${SRCDir} ./$${RUN_TB}_run
|
||||
TaskDir=`readlink -f ../*_Verilog/TaskConfigCopy`
|
||||
rm -rf ./$${RUN_TB}_run/TaskConfigCopy && ln -s $${TaskDir} ./$${RUN_TB}_run
|
||||
TestbenchDir=`readlink -f ../*_Verilog/TESTBENCH`
|
||||
rm -rf ./$${RUN_TB}_run/TESTBENCH && ln -s $${TestbenchDir} ./$${RUN_TB}_run
|
||||
|
||||
# = = = = = = = = = = = 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
|
||||
echo "Found Initialization file [../INIT/$${RUN_TB}_init.v]"
|
||||
modLineNo=$$(grep -n "module fpga_top" $${DESIGN_NAME}_cocosim.v | cut -f1 -d:)
|
||||
echo $${modLineNo}
|
||||
sed -i "$${modLineNo},\$${/endmodule/d}" $${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]"
|
||||
echo "Found initialization file"
|
||||
sed -i "/endmodule/d" $${DESIGN_NAME}_cocosim.v
|
||||
cat ../INIT/$${RUN_TB}_init.v >> $${DESIGN_NAME}_cocosim.v
|
||||
printf "\nendmodule" >> $${DESIGN_NAME}_cocosim.v
|
||||
fi
|
||||
|
||||
# = = = = = = = = Create Makefile to run = = = = = = = = = = = = = =
|
||||
|
@ -81,4 +67,48 @@ RunPostPnRTest:
|
|||
echo "include $(shell cocotb-config --makefiles)/Makefile.sim" >> Makefile
|
||||
break
|
||||
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...
|
||||
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(
|
||||
f"Expected 8 ticks on module {ModuleName} received {CLKTick}")
|
||||
end_ccff_time = get_sim_time(units='ns')
|
||||
await ClockCycles(prog_clk, 10)
|
||||
TotalClock = math.ceil((end_ccff_time-start_ccff_time)/PCLK_PERIOD)
|
||||
dut._log.info(f"Simulation Finished in clocks {TotalClock}")
|
||||
except SimTimeoutError:
|
||||
|
@ -146,6 +147,7 @@ async def ScanChainTestFull(dut):
|
|||
f"Expected 8 ticks on module {ModuleName} received {CLKTick}")
|
||||
end_scff_time = get_sim_time(units='ns')
|
||||
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"Per Grid {TotalClock/(PConf['FPGA_SIZE_X']**2)}")
|
||||
except SimTimeoutError:
|
||||
|
|
Loading…
Reference in New Issue