Skip to content

Commit

Permalink
WIP extend json4vhdl with b16 encodings
Browse files Browse the repository at this point in the history
  • Loading branch information
1138-4EB committed Nov 27, 2019
1 parent 41ce155 commit 3e9a005
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 47 deletions.
7 changes: 6 additions & 1 deletion examples/vhdl/json4vhdl/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@

tb_cfg = read_json(join(root, "src/test/data/data.json"))
tb_cfg["dump_debug_data"] = False
vu.set_generic("tb_cfg", encode_json(tb_cfg))

json_str = encode_json(tb_cfg)

vu.set_generic("tb_cfg", json_str)

vu.set_generic("tb_cfg_b16", json_str.encode("utf-8").hex())

vu.main()
98 changes: 52 additions & 46 deletions examples/vhdl/json4vhdl/src/test/tb_json_gens.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
-- Copyright (c) 2014-2019, Lars Asplund lars.anders.asplund@gmail.com
library vunit_lib;
context vunit_lib.vunit_context;
use vunit_lib.encodings_pkg.all;
library JSON;
context JSON.json_ctx;

Expand All @@ -13,68 +14,73 @@ entity tb_json_gens is
runner_cfg : string;
tb_path : string;
tb_cfg : string;
tb_cfg_b16 : string;
tb_cfg_file : string := "data/data.json"
);
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
if run("stringified JSON generic") then
info("RAW generic: " & tb_cfg);
JSONContent := jsonLoad(tb_cfg);
run_test(JSONContent);
run_record_test(JSONContent);
elsif run("b16encoded stringified JSON generic") then
info("RAW generic: " & tb_cfg_b16);
JSONContent := jsonLoad(b16decode(tb_cfg_b16));
run_test(JSONContent);
run_record_test(JSONContent);
elsif run("JSON from file path generic") then
-- Full path of the JSON file
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"));
run_test(jsonLoad(tb_path & tb_cfg_file));
end if;
end loop;
test_runner_cleanup(runner);
Expand Down
1 change: 1 addition & 0 deletions vunit/builtins.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ def add_vhdl_builtins(self, external=None):
self._add_files(join(VHDL_PATH, "*.vhd"))
for path in (
"core",
"encodings",
"logging",
"string_ops",
"check",
Expand Down
16 changes: 16 additions & 0 deletions vunit/vhdl/encodings/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Copyright (c) 2014-2019, Lars Asplund lars.anders.asplund@gmail.com

from os.path import join, dirname
from vunit import VUnit

root = dirname(__file__)

ui = VUnit.from_argv()

lib = ui.library("vunit_lib")
lib.add_source_files(join(root, "test", "*.vhd"))
ui.main()
59 changes: 59 additions & 0 deletions vunit/vhdl/encodings/src/encodings_pkg.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
-- This Source Code Form is subject to the terms of the Mozilla Public
-- License, v. 2.0. If a copy of the MPL was not distributed with this file,
-- You can obtain one at http://mozilla.org/MPL/2.0/.
--
-- Copyright (c) 2014-2019, Lars Asplund lars.anders.asplund@gmail.com

package encodings_pkg is

function b16decode(str: string) return string;
function b16encode(str: string) return string;

end;

package body encodings_pkg is

function to_natural (c: character) return natural is
constant offset_0 : natural := character'pos('0');
constant offset_U : natural := character'pos('A') - 10;
constant offset_l : natural := character'pos('a') - 10;
variable num: integer := -1;
begin
num := character'pos(c);
case c is
when '0' to '9' => return num - offset_0;
when 'A' to 'F' => return num - offset_U;
when 'a' to 'f' => return num - offset_l;
when others => return -1;
end case;
end;

function b16decode(str: string) return string is
variable res: string (1 to str'length/2);
begin
for x in 1 to str'length/2 loop
res(x) := character'val(to_natural(str(2*x-1)) *16 + to_natural(str(2*x)));
end loop;
return res;
end;

function to_character(num: natural) return character is
begin
if num<10 then
return character'val(num+48);
end if;
return character'val(num+87);
end;

function b16encode(str: string) return string is
variable res: string (1 to 2*str'length);
variable num: natural;
begin
for x in 1 to str'length loop
num := character'pos(str(x));
res(2*x-1 to 2*x) := to_character(num / 16) & to_character(num rem 16);
end loop;
return res;
end function;

end;
31 changes: 31 additions & 0 deletions vunit/vhdl/encodings/test/tb_encodings_pkg.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
-- This Source Code Form is subject to the terms of the Mozilla Public
-- License, v. 2.0. If a copy of the MPL was not distributed with this file,
-- You can obtain one at http://mozilla.org/MPL/2.0/.
--
-- Copyright (c) 2014-2019, Lars Asplund lars.anders.asplund@gmail.com

library vunit_lib;
use vunit_lib.run_pkg.all;
use vunit_lib.check_pkg.all;
use vunit_lib.encodings_pkg.all;

entity tb_encodings is
generic (runner_cfg : string);
end;

architecture a of tb_encodings is
constant str: string := "[""test"",[true,false,18,null,""hello""],[9,8],3324.34,832432,""world""]";
constant enc: string := "5b2274657374222c5b747275652c66616c73652c31382c6e756c6c2c2268656c6c6f225d2c5b392c385d2c333332342e33342c3833323433322c22776f726c64225d";
begin
main : process
variable gstr: string(1 to str'length);
variable genc: string(1 to enc'length);
begin
test_runner_setup(runner, runner_cfg);
gstr := b16decode(enc);
genc := b16encode(str);
check_equal(gstr, str);
check_equal(genc, enc);
test_runner_cleanup(runner);
end process;
end;

0 comments on commit 3e9a005

Please sign in to comment.