Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

json4vhdl: use base16 encodings #595

Merged
merged 2 commits into from
Feb 14, 2020
Merged
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
18 changes: 15 additions & 3 deletions examples/vhdl/json4vhdl/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,29 @@
"""

from pathlib import Path
from vunit import VUnit, read_json, encode_json
from vunit import VUnit
from vunit.json4vhdl import read_json, encode_json, b16encode

TEST_PATH = Path(__file__).parent / "src" / "test"

VU = VUnit.from_argv()
VU.add_json4vhdl()

VU.add_library("test").add_source_files(TEST_PATH / "*.vhd")
LIB = VU.add_library("test")
LIB.add_source_files(TEST_PATH / "*.vhd")

TB_CFG = read_json(TEST_PATH / "data" / "data.json")
TB_CFG["dump_debug_data"] = False
VU.set_generic("tb_cfg", encode_json(TB_CFG))
JSON_STR = encode_json(TB_CFG)
JSON_FILE = Path("data") / "data.json"

TB = LIB.get_test_benches()[0]

TB.get_tests("stringified*")[0].set_generic("tb_cfg", JSON_STR)
TB.get_tests("b16encoded stringified*")[0].set_generic("tb_cfg", b16encode(JSON_STR))
TB.get_tests("JSON file*")[0].set_generic("tb_cfg", JSON_FILE)
TB.get_tests("b16encoded JSON file*")[0].set_generic(
"tb_cfg", b16encode(str(TEST_PATH / JSON_FILE))
)

VU.main()
104 changes: 53 additions & 51 deletions examples/vhdl/json4vhdl/src/test/tb_json_gens.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -10,71 +10,73 @@ context JSON.json_ctx;

entity tb_json_gens is
generic (
runner_cfg : string;
tb_path : string;
tb_cfg : string;
tb_cfg_file : string := "data/data.json"
runner_cfg : string;
tb_path : string;
tb_cfg : string
);
end entity;

architecture tb of tb_json_gens is

-- tb_cfg contains stringified content
constant JSONContent : T_JSON := jsonLoad(tb_cfg);
begin
main: process

-- tb_cfg is the path of a JSON file
constant JSONFileContent : T_JSON := jsonLoad(tb_path & tb_cfg_file);
procedure run_test(JSONContent : T_JSON) is
-- get array of integers from JSON content
constant img_arr : integer_vector := jsonGetIntegerArray(JSONContent, "Image");
begin
-- Content extracted from the JSON
info("JSONContent: " & lf & JSONContent.Content);

-- record to be filled by function decode
type img_t is record
image_width : positive;
image_height : positive;
dump_debug_data : boolean;
end record img_t;
-- Integer array, extracted by function jsonGetIntegerArray with data from the JSON
for i in 0 to img_arr'length-1 loop
info("Image array [" & integer'image(i) & "]: " & integer'image(img_arr(i)));
end loop;

-- function to fill img_t with content extracted from a JSON input
impure function decode(Content : T_JSON) return img_t is
begin
return (image_width => positive'value( jsonGetString(Content, "Image/0") ),
image_height => positive'value( jsonGetString(Content, "Image/1") ),
dump_debug_data => jsonGetBoolean(Content, "dump_debug_data") );
end function decode;
-- Image dimensions as strings, get from the content from the JSON file
info("Image: " & jsonGetString(JSONContent, "Image/0") & ',' & jsonGetString(JSONContent, "Image/1"));

constant img : img_t := decode(JSONContent);
-- Some other content, deep in the JSON
info("Platform/ML505/FPGA: " & jsonGetString(JSONContent, "Platform/ML505/FPGA"));
info("Platform/KC705/IIC/0/Devices/0/Name: " & jsonGetString(JSONContent, "Platform/KC705/IIC/0/Devices/0/Name"));
end procedure;

-- get array of integers from JSON content
constant img_arr : integer_vector := jsonGetIntegerArray(JSONContent, "Image");
procedure run_record_test(JSONContent : T_JSON) is
type img_t is record
image_width : positive;
image_height : positive;
dump_debug_data : boolean;
end record img_t;

-- fill img_t with content extracted from a JSON input
constant img : img_t := (
image_width => positive'value( jsonGetString(JSONContent, "Image/0") ),
image_height => positive'value( jsonGetString(JSONContent, "Image/1") ),
dump_debug_data => jsonGetBoolean(JSONContent, "dump_debug_data")
);
begin
-- Image dimensions in a record, filled with data from the stringified generic
info("Image: " & integer'image(img.image_width) & ',' & integer'image(img.image_height));
end procedure;

variable JSONContent : T_JSON;

begin
main: process
begin
test_runner_setup(runner, runner_cfg);
while test_suite loop
if run("test") then
-- Content extracted from the stringified generic
info("JSONContent: " & lf & JSONContent.Content);

-- Full path of the JSON file, and extracted content
info("tb_path & tb_cfg_file: " & tb_path & tb_cfg_file);
info("JSONFileContent: " & lf & JSONFileContent.Content);

-- Image dimensions in a record, filled by function decode with data from the stringified generic
info("Image: " & integer'image(img.image_width) & ',' & integer'image(img.image_height));

-- Integer array, extracted by function decode_array with data from the stringified generic
for i in 0 to img_arr'length-1 loop
info("Image array [" & integer'image(i) & "]: " & integer'image(img_arr(i)));
end loop;

-- Image dimensions as strings, get from the content from the JSON file
info("Image: " & jsonGetString(JSONFileContent, "Image/0") & ',' & jsonGetString(JSONFileContent, "Image/1"));

-- Some other content, deep in the JSON sources
info("Platform/ML505/FPGA: " & jsonGetString(JSONContent, "Platform/ML505/FPGA"));
info("Platform/ML505/FPGA: " & jsonGetString(JSONFileContent, "Platform/ML505/FPGA"));

info("Platform/KC705/IIC/0/Devices/0/Name: " & jsonGetString(JSONContent, "Platform/KC705/IIC/0/Devices/0/Name"));
info("Platform/KC705/IIC/0/Devices/0/Name: " & jsonGetString(JSONFileContent, "Platform/KC705/IIC/0/Devices/0/Name"));
info("RAW generic: " & tb_cfg);
if run("stringified JSON generic") then
JSONContent := jsonLoad(tb_cfg);
run_test(JSONContent);
run_record_test(JSONContent);
elsif run("b16encoded stringified JSON generic") then
JSONContent := jsonLoad(tb_cfg);
run_test(JSONContent);
run_record_test(JSONContent);
elsif run("JSON file path generic") then
run_test(jsonLoad(tb_path & tb_cfg));
elsif run("b16encoded JSON file path generic") then
run_test(jsonLoad(tb_cfg));
end if;
end loop;
test_runner_cleanup(runner);
Expand Down
5 changes: 5 additions & 0 deletions tests/acceptance/artificial/vhdl/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ def configure_tb_set_generic(ui):
tb.set_generic("str_val", "4ns")
tb.set_generic("str_space_val", "1 2 3")
tb.set_generic("str_quote_val", 'a"b')
str_long_num = 512
tb.set_generic("str_long_num", str_long_num)
tb.set_generic(
"str_long_val", "".join(["0123456789abcdef" for x in range(str_long_num)])
)


def configure_tb_assert_stop_level(ui):
Expand Down
39 changes: 25 additions & 14 deletions tests/acceptance/artificial/vhdl/tb_set_generic.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,48 @@ context vunit_lib.vunit_context;

entity tb_set_generic is
generic (
runner_cfg : string;
is_ghdl : boolean;
true_boolean : boolean;
false_boolean : boolean;
runner_cfg : string;
is_ghdl : boolean;
true_boolean : boolean;
false_boolean : boolean;
negative_integer : integer;
positive_integer : integer;
negative_real : real := 0.0;
positive_real : real := 0.0;
time_val : time := 0 ns;
str_val : string;
str_space_val : string;
str_quote_val : string);
negative_real : real := 0.0;
positive_real : real := 0.0;
time_val : time := 0 ns;
str_val : string;
str_space_val : string;
str_quote_val : string;
str_long_num : integer := 64;
str_long_val : string);
end entity;

architecture tb of tb_set_generic is
impure function str_long(num: natural) return string is
variable str: string(1 to 16*num);
begin
for x in 1 to num loop
str((x-1)*16+1 to x*16) := "0123456789abcdef";
end loop;
return str;
end;
begin
main : process
begin
test_runner_setup(runner, runner_cfg);
assert true_boolean = true;
assert false_boolean = false;
assert true_boolean = true;
assert false_boolean = false;
assert negative_integer = -10000;
assert positive_integer = 99999;
if not is_ghdl then
assert negative_real = -9999.9;
assert positive_real = 2222.2;
assert time_val = 4 ns;
assert time_val = 4 ns;
end if;
assert str_val = "4ns";
assert str_val = "4ns";
assert str_space_val = "1 2 3";
assert str_quote_val = "a""b";
assert str_long_val = str_long(str_long_num);
test_runner_cleanup(runner);
end process;
end architecture;
1 change: 0 additions & 1 deletion vunit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from vunit.ui import VUnit
from vunit.vunit_cli import VUnitCLI
from vunit.about import version, doc
from vunit.json4vhdl import read_json, encode_json

# Repository root
ROOT = abspath(join(dirname(__file__), ".."))
Expand Down
2 changes: 1 addition & 1 deletion vunit/builtins.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ def _add_json4vhdl(self):
except KeyError:
library = self._vunit_obj.add_library(library_name)

library.add_source_files(VHDL_PATH / "JSON-for-VHDL" / "vhdl" / "*.vhdl")
library.add_source_files(VHDL_PATH / "JSON-for-VHDL" / "src" / "*.vhdl")

def add_verilog_builtins(self):
"""
Expand Down
15 changes: 13 additions & 2 deletions vunit/json4vhdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
json4vhdl helper functions
"""

from typing import Union
import json
from base64 import b16encode as b16enc


def encode_json(obj):
def encode_json(obj: object):
"""
Convert object to stringified JSON

Expand All @@ -26,7 +28,7 @@ def encode_json(obj):
return json.dumps(obj, separators=(",", ":"))


def read_json(filename):
def read_json(filename: str):
"""
Read a JSON file and return an object

Expand All @@ -39,3 +41,12 @@ def read_json(filename):
generics = read_json(join(root, "src/test/data/data.json"))
"""
return json.loads(open(filename, "r").read())


def b16encode(data: Union[str, bytes]):
"""
Encode a str|bytes using Base16 and return a str|bytes
"""
if isinstance(data, str):
return b16enc(bytes(data, "utf-8")).decode("utf-8")
return b16encode(data)
2 changes: 1 addition & 1 deletion vunit/vhdl/JSON-for-VHDL
Submodule JSON-for-VHDL updated 375 files