Looks like you're trying to get more information out of the OSVVM Scoreboard package
You can do what you want, as Ive done it. The trick is to compare everything as a string. Because you've already written a to_string function. so you can just compare the two results as strings char by char, giving you a char by char matching that you can then have reported in the log. What mine also does is allow you to put 'X' in the expected string to force a match with the actual value. This is useful when, for example, you have byte enables and you only want to check the "valid" bytes in the bus.
So, here is what I do. First off, have a "match_string" function, that returns a string that comapres two strings char by char, and returns a string that has 'X' where there is a missmatch between the two string:
Code VHDL - [expand] |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| --------------------------------------------------------------------------------------------
-- Takes 2 strings and produces another strings that marks missmatches
--------------------------------------------------------------------------------------------
function match_string(s1, s2 : string;
match_char : character := ' ';
missmatch_char : character := 'X';
s1_ignore : string := "";
s2_ignore : string := "" ) return string is
variable ret : string(s1'range);
variable s1_local : string(s1'range) := s1;
variable s2_local : string(s2'range) := s2;
begin
assert (s1'length = s2'length)
report "match_string: S1 and S2 lengths must match" & LF
& "S1 = " & s1 & LF
& "S2 = " & s2
severity FAILURE;
for i in s1'range loop
----------------------------------------------------------------------------
-- Force a match on ignore chars
----------------------------------------------------------------------------
for j in s1_ignore'range loop
s1_local(i) := s2_local(i) when s1_local(i) = s1_ignore(j);
end loop;
for j in s2_ignore'range loop
s2_local(i) := s1_local(i) when s2_local(i) = s2_ignore(j);
end loop;
ret(i) := match_char when (s1_local(i) = s2_local(i)) else missmatch_char;
end loop;
return ret;
end function match_string; |
then a procedure that does what you suggested - returns the matching string (with Xs in it) and whether it was a complete match or not
Code VHDL - [expand] |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| procedure match_string( constant s1, s2 : string;
constant match_char : character := ' ';
constant missmatch_char : character := 'X';
constant s1_ignore : string := "";
constant s2_ignore : string := "";
variable match_str : inout line;
variable matched : out boolean ) is
begin
DEALLOCATE(match_str);
matched := false;
match_str := new string'( match_string(s1, s2, match_char, missmatch_char, s1_ignore, s2_ignore) );
-- return missmatch on any missmatch char
for i in s1'range loop
if match_str(i) = missmatch_char then return; end if;
end loop;
matched := true;
end procedure; |
then finally, the magic match_X_generic function that can take any data type so you can plug it directly to the scoreboard package of osvvm
Code VHDL - [expand] |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| function match_X_generic generic ( type data_t;
function to_string(d : data_t) return string is <> )
parameter( act, exp : data_t )
return boolean is
variable matched : boolean;
variable match_str : line;
begin
match_string( s1 => to_string(act),
s2 => to_string(exp),
s2_ignore => "X-" ,
match_str => match_str ,
matched => matched );
if not matched then
-- Dont Use Alert, as this will come in Scoreboard
log(TBTOOLS_ALERT_ID, "act: " & to_string(act), ALWAYS);
log(TBTOOLS_ALERT_ID, "exp: " & to_string(exp), ALWAYS);
log(TBTOOLS_ALERT_ID, " " & match_str.all , ALWAYS);
end if;
DEALLOCATE(match_str);
return matched;
end function match_X_generic; |
so then, in your log, you can get output like this every time the scoreboard performs a check:
Code:
%% Log ALWAYS in testbench_tools_pkg, act: tid: 0x00 tdata: 0x9B3EC00E13ECBA2E tuser: 0xXXXXA5420F6560 tkeep: 0xFF tlast: 0 at 5570 ns
%% Log ALWAYS in testbench_tools_pkg, exp: tid: 0x00 tdata: 0xFFFFFFFFFFFFFFFF tuser: 0xXXXXA5420F6560 tkeep: 0xFF tlast: 0 at 5570 ns
%% Log ALWAYS in testbench_tools_pkg, XXXXXXXXXXXXXXXX at 5570 ns
%% Alert ERROR in Filtered Packet Checker, Received: tid: 0x00 tdata: 0x9B3EC00E13ECBA2E tuser: 0xXXXXA5420F6560 tkeep: 0xFF tlast: 0 Expected: tid: 0x00 tdata: 0xFFFFFFFFFFFFFFFF tuser: 0xXXXXA5420F6560 tkeep: 0xFF tlast: 0 Item Number: 1 at 5570 ns