Skip to content

Commit

Permalink
adding test_LineCode8b10bTb.py
Browse files Browse the repository at this point in the history
  • Loading branch information
ruck314 committed Jul 2, 2023
1 parent c755ebe commit f92629a
Show file tree
Hide file tree
Showing 4 changed files with 257 additions and 4 deletions.
87 changes: 87 additions & 0 deletions protocols/line-codes/tb/LineCode8b10bTb.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
-------------------------------------------------------------------------------
-- Title : Line Code 8B10B: https://en.wikipedia.org/wiki/8b/10b_encoding
-------------------------------------------------------------------------------
-- Company : SLAC National Accelerator Laboratory
-------------------------------------------------------------------------------
-- Description: 8B10B Line Code Test bed for cocoTB
-------------------------------------------------------------------------------
-- This file is part of 'SLAC Firmware Standard Library'.
-- It is subject to the license terms in the LICENSE.txt file found in the
-- top-level directory of this distribution and at:
-- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
-- No part of 'SLAC Firmware Standard Library', including this file,
-- may be copied, modified, propagated, or distributed except according to
-- the terms contained in the LICENSE.txt file.
-------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;

library surf;
use surf.StdRtlPkg.all;

entity LineCode8b10bTb is
generic (
TPD_G : time := 1 ns;
NUM_BYTES_G : positive := 1);
port (
-- Clock and Reset
clk : in sl;
rst : in sl;
-- Encoder Interface
validIn : in sl;
dataIn : in slv(NUM_BYTES_G*8-1 downto 0);
dataKIn : in slv(NUM_BYTES_G-1 downto 0);
-- Decoder Interface
validOut : out sl;
dataOut : out slv(NUM_BYTES_G*8-1 downto 0);
dataKOut : out slv(NUM_BYTES_G-1 downto 0);
codeErr : out slv(NUM_BYTES_G-1 downto 0);
dispErr : out slv(NUM_BYTES_G-1 downto 0));
end entity LineCode8b10bTb;

architecture mapping of LineCode8b10bTb is

signal validEncode : sl;
signal dataEncode : slv(NUM_BYTES_G*10-1 downto 0);

begin

U_Encoder : entity surf.Encoder8b10b
generic map (
TPD_G => TPD_G,
NUM_BYTES_G => NUM_BYTES_G,
RST_POLARITY_G => '1',
RST_ASYNC_G => false,
FLOW_CTRL_EN_G => true)
port map (
clk => clk,
clkEn => '1',
rst => rst,
validIn => validIn,
readyIn => open,
dataIn => dataIn,
dataKIn => dataKIn,
validOut => validEncode,
readyOut => validEncode,
dataOut => dataEncode);

U_Decoder : entity surf.Decoder8b10b
generic map (
TPD_G => TPD_G,
NUM_BYTES_G => NUM_BYTES_G,
RST_POLARITY_G => '1',
RST_ASYNC_G => false)
port map (
clk => clk,
clkEn => '1',
rst => rst,
validIn => validEncode,
dataIn => dataEncode,
validOut => validOut,
dataOut => dataOut,
dataKOut => dataKOut,
codeErr => codeErr,
dispErr => dispErr);

end mapping;
5 changes: 2 additions & 3 deletions protocols/sugoi/ruckus.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ source $::env(RUCKUS_PROC_TCL)
# Load Source Code
loadSource -lib surf -dir "$::DIR_PATH/rtl"

# Load Simulation
loadSource -lib surf -sim_only -dir "$::DIR_PATH/tb"

# Check for non-zero Vivado version (in-case non-Vivado project)
if { $::env(VIVADO_VERSION) > 0.0} {
loadSource -lib surf -dir "$::DIR_PATH/rtl/7Series"
loadSource -lib surf -dir "$::DIR_PATH/rtl/UltraScale"
# Load Simulation (includes library UNISIM)
loadSource -lib surf -sim_only -dir "$::DIR_PATH/tb"
} else {
loadSource -lib surf -dir "$::DIR_PATH/rtl/dummy"
}
2 changes: 1 addition & 1 deletion ruckus.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ source $::env(RUCKUS_PROC_TCL)

# Check for submodule tagging
if { [info exists ::env(OVERRIDE_SUBMODULE_LOCKS)] != 1 || $::env(OVERRIDE_SUBMODULE_LOCKS) == 0 } {
if { [SubmoduleCheck {ruckus} {4.8.2} ] < 0 } {exit -1}
if { [SubmoduleCheck {ruckus} {4.8.4} ] < 0 } {exit -1}
} else {
puts "\n\n*********************************************************"
puts "OVERRIDE_SUBMODULE_LOCKS != 0"
Expand Down
167 changes: 167 additions & 0 deletions tests/test_LineCode8b10bTb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
##############################################################################
## This file is part of 'SLAC Firmware Standard Library'.
## It is subject to the license terms in the LICENSE.txt file found in the
## top-level directory of this distribution and at:
## https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
## No part of 'SLAC Firmware Standard Library', including this file,
## may be copied, modified, propagated, or distributed except according to
## the terms contained in the LICENSE.txt file.
##############################################################################

# dut_tb
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge

# test_DspComparator
from cocotb_test.simulator import run
import pytest
import glob
import os

@cocotb.coroutine
def dut_init(dut):

# Initialize the inputs
dut.rst.value = 1
dut.validIn.value = 0
dut.dataIn.value = 0
dut.dataKIn.value = 0

# Start clock (200 MHz) in a separate thread
cocotb.start_soon(Clock(dut.clk, 5.0, units='ns').start())

# Wait 5 clock cycle
for i in range(5):
yield RisingEdge(dut.clk)

# De-assert the reset
dut.rst.value = 0

# Wait 1 clock cycle
yield RisingEdge(dut.clk)

@cocotb.coroutine
def load_value(dut, dataIn, dataKIn):

# Load the values
dut.dataIn.value = dataIn
dut.dataKIn.value = dataKIn

# Assert valid flag
dut.validIn.value = 1

# Wait 1 clock cycle
yield RisingEdge(dut.clk)

# De-assert valid flag
dut.validIn.value = 0

# Wait for the result
while ( dut.validOut.value != 1 ):
yield RisingEdge(dut.clk)


def check_result(dut, dataIn, dataKIn):
# Check (dataIn = dataOut) or (dataKIn = dataKOut) result
if (dataIn != dut.dataOut.value) or (dataKIn != dut.dataKOut.value):
dut._log.error( f'dataIn={hex(dataIn)},dataKIn={hex(dataKIn)} but got dataOut={hex(dut.dataOut.value)},dataKOut={hex(dut.dataKOut.value)}')
assert False

# Check (codeErr = 0) or (dispErr = 0) result
if (dut.codeErr.value != 0) or (dut.dispErr.value != 0):
dut._log.error( f'ERROR: codeErr={hex(dut.codeErr.value)},dispErr={hex(dut.dispErr.value)}')
assert False

@cocotb.test()
def dut_tb(dut):

# Initialize the DUT
yield dut_init(dut)

# Read the parameters back from the DUT to set up our model
width = dut.NUM_BYTES_G.value.integer
dut._log.info( f'Found NUM_BYTES_G={width}' )

# Sweep through all possible combinations of data codes
dataKIn = 0
for dataIn in range(2**(8*width)):

# Load the values
yield load_value(dut, dataIn, dataKIn)

# Check the results for errors
check_result(dut, dataIn, dataKIn)

# Sweep through the defined Control Code Constants
dataKIn = 1
controlCodes = [
0x1C, # K28.0, 0x1C
0x3C, # K28.1, 0x3C (Comma)
0x5C, # K28.2, 0x5C
0x7C, # K28.3, 0x7C
0x9C, # K28.4, 0x9C
0xBC, # K28.5, 0xBC (Comma)
0xDC, # K28.6, 0xDC
0xFC, # K28.7, 0xFC (Comma)
0xF7, # K23.7, 0xF7
0xFB, # K27.7, 0xFB
0xFD, # K29.7, 0xFD
0xFE, # K30.7, 0xFE
]
for dataIn in controlCodes:

# Load the values
yield load_value(dut, dataIn, dataKIn)

# Check the results for errors
check_result(dut, dataIn, dataKIn)

dut._log.info("DUT: Passed")

tests_dir = os.path.dirname(__file__)
tests_module = 'LineCode8b10bTb'

@pytest.mark.parametrize(
"parameters", [
{'NUM_BYTES_G': '1'}, # Test 1 byte interface
{'NUM_BYTES_G': '2'}, # Test 2 byte interface
])
def test_LineCode8b10bTb(parameters):

# https://github.com/themperek/cocotb-test#arguments-for-simulatorrun
# https://github.com/themperek/cocotb-test/blob/master/cocotb_test/simulator.py
run(
# top level HDL
toplevel = f'surf.{tests_module}'.lower(),

# name of the file that contains @cocotb.test() -- this file
# https://docs.cocotb.org/en/stable/building.html?#envvar-MODULE
module = f'test_{tests_module}',

# https://docs.cocotb.org/en/stable/building.html?#var-TOPLEVEL_LANG
toplevel_lang = 'vhdl',

# VHDL source files to include.
# Can be specified as a list or as a dict of lists with the library name as key,
# if the simulator supports named libraries.
vhdl_sources = {
'surf' : glob.glob(f'{tests_dir}/../build/SRC_VHDL/surf/*'),
'ruckus' : glob.glob(f'{tests_dir}/../build/SRC_VHDL/ruckus/*'),
},

# A dictionary of top-level parameters/generics.
parameters = parameters,

# The directory used to compile the tests. (default: sim_build)
sim_build = f'{tests_dir}/sim_build/{tests_module}.' + ",".join((f"{key}={value}" for key, value in parameters.items())),

# A dictionary of extra environment variables set in simulator process.
extra_env=parameters,

# Select a simulator
simulator="ghdl",

# Dump waveform to file ($ gtkwave sim_build/LineCode8b10bTb.NUM_BYTES_G\=1/LineCode8b10bTb.vcd)
sim_args =[f'--vcd={tests_module}.vcd'],
)

0 comments on commit f92629a

Please sign in to comment.