How to read data back in the sequencer from VVC component

Hi,
I was trying to implement a simple UVVM environment for my DUT where I am able to drive the data from the sequencer to the VVC component successfully,

But when i am trying to read the data back from the VVC component to the sequencer i am facing some issue in doing that

I don’t have any compilation issues when i am doing that

can someone help me where am i doing the mistake?

Regards,
Riyaz

Hi Riyaz,

What kind of issue are you having and which VVC are you using?

Best regards,
Erick

Hi Erick,

i am not able to read the data back to sequencer maybe a connection issue or maybe I might have missed some thing not sure

I actually tried to attach the snapshots, don’t know why I cant do that it is not accepting it

Best Regards,
Riyaz

Here is an example of how to do a read operation in the SBI VVC (taken from the VVC Quick Reference):

variable v_cmd_idx : natural; – Command index for the last read
variable v_data : work.vvc_cmd_pkg.t_vvc_result; – Result from read.
(…)
sbi_read(SBI_VVCT, 1, C_ADDR_UART_BAUDRATE, “Read from Peripheral 1”);
v_cmd_idx := get_last_received_cmd_idx(SBI_VVCT, 1);
await_completion(SBI_VVCT,1, v_cmd_idx, 1 us, “Wait for read to finish”);
fetch_result(SBI_VVCT,1, v_cmd_idx, v_data, “Fetching result from read operation”);

Remember that when you do a read or receive operation in a VVC you need to wait until the command has completed (await_completion) and you need to fetch the data from the VVC.

Best Regards,
Erick

Is there any possibility that I can contact you to explain my issue and some inputs for that

I feel like I need some more info regarding this

It will be helpful if you do this :slight_smile:

Best Regards,
Riyaz

You could try copying the part of the testbench code that you are using to read the data from the VVC so I can understand better what the issue is. Otherwise, you can send an email to support@bitvis.no explaining your issue if you prefer.

Best regards,
Erick

p_main: process
– variable v_ready : std_logic ;
– variable v_done : std_logic;
variable v_result : std_logic_vector(15 downto 0);
begin
wait for 50 ns;
alu_write(ALU_INTF_VVCT,1,“00000011”,“00000010”,“001”,‘1’,“ALU_INTF_WRITE”, C_SCOPE);
alu_read(ALU_INTF_VVCT,1,v_result,“input data result”, C_SCOPE);
await_completion(ALU_INTF_VVCT,1,100 ns, “wait till finish”);
wait for 100 ns;
alu_write(ALU_INTF_VVCT,1,“00000111”,“00000101”,“010”,‘1’,“ALU_INTF_WRITE”, C_SCOPE);
alu_read(ALU_INTF_VVCT,1,v_result,“input data result”, C_SCOPE);
await_completion(ALU_INTF_VVCT,1,100 ns, “wait till finish”);
wait for 100 ns;
alu_write(ALU_INTF_VVCT,1,“00000111”,“00000101”,“011”,‘1’,“ALU_INTF_WRITE”, C_SCOPE);
alu_read(ALU_INTF_VVCT,1,v_result,“input data result”, C_SCOPE);
await_completion(ALU_INTF_VVCT,1,100 ns, “wait till finish”);
wait for 100 ns;
alu_write(ALU_INTF_VVCT,1,“00001010”,“00000010”,“100”,‘1’,“ALU_INTF_WRITE”, C_SCOPE);
alu_read(ALU_INTF_VVCT,1,v_result,“input data result”, C_SCOPE);
await_completion(ALU_INTF_VVCT,1,100 ns, “wait till finish”);

this is what I was trying to do in my test sequencer

procedure alu_intf_read(
variable data_value : out std_logic_vector;
constant msg : in string;
signal clk : in std_logic;
signal alu_intf_if : inout t_alu_intf_if;
constant scope : in string := C_SCOPE;
constant msg_id_panel : in t_msg_id_panel := shared_msg_id_panel;
constant config : in t_alu_intf_bfm_config := C_ALU_INTF_BFM_CONFIG_DEFAULT
) is

begin

-- wait until alu_intf_if.done = '1';
data_value := alu_intf_if.rslt;

end procedure;

this is in bfm package
procedure alu_read(
signal VVCT : inout t_vvc_target_record;
constant vvc_instance_idx : in integer;
variable data_out : out std_logic_vector;
constant msg : in string;
constant scope : in string := C_VVC_CMD_SCOPE_DEFAULT
) is
constant proc_name : string := “alu_read”;
constant proc_call : string := proc_name & “(” & to_string(VVCT, vvc_instance_idx) – First part common for all
& ", " & to_string(data_out) & “)”;
variable v_msg_id_panel : t_msg_id_panel := shared_msg_id_panel;
begin
– Create command by setting common global ‘VVCT’ signal record and dedicated VVC ‘shared_vvc_cmd’ record
– locking semaphore in set_general_target_and_command_fields to gain exclusive right to VVCT and shared_vvc_cmd
– semaphore gets unlocked in await_cmd_from_sequencer of the targeted VVC
set_general_target_and_command_fields(VVCT, vvc_instance_idx, proc_call, msg, QUEUED, ALU_INTF_READ);
shared_vvc_cmd.operation := ALU_INTF_READ;
data_out := shared_vvc_cmd.rslt;
– data_out := shared_vvc_response.result;

-- shared_vvc_cmd.parent_msg_id_panel := parent_msg_id_panel;
-- if parent_msg_id_panel /= C_UNUSED_MSG_ID_PANEL then
  -- v_msg_id_panel := parent_msg_id_panel;
-- end if;
send_command_to_vvc(VVCT, std.env.resolution_limit, scope, v_msg_id_panel);

end procedure;

this is in the methods package

      when ALU_INTF_READ =>
     -- Call the corresponding procedure in the BFM package.
        alu_intf_read(data_value    => v_result,
                      msg           => format_msg(v_cmd),
                      clk           => clk,
                      alu_intf_if   => alu_intf_vvc_if,
                      scope         => C_SCOPE,
                      msg_id_panel  => v_msg_id_panel,
                      config        => vvc_config.bfm_config);

this is an instantiation of bfm i had done in my VVC

Best Regards,
Riyaz

I think the problem is in the alu_read() procedure in the methods_pkg.
You are assigning the shared_vvc_cmd.rslt to data_out. However at this moment the BFM procedure alu_intf_read() hasn’t been executed, as this only happens after the send_command_to_vvc(). Also shared_vvc_cmd is reset at the beginning of the procedure with set_general_target_and_command_fields(), therefore this shared variable will never have the read data and is only meant to be used to transmit data towards the VVC.

The correct way of doing this would be to use the fetch procedure which should be in your VVC if you used the vvc_generator.py script.

This is the standard way of reading data from a VVC since the procedure calls are non-time consuming (from the test sequencer) so any read data has to be stored in a queue inside the VVC. This is the code in the VVC that does that:

work.td_vvc_entity_support_pkg.store_result(result_queue => result_queue,
cmd_idx => v_cmd.cmd_idx,
result => v_result);

So from your test sequencer you can use the following commands:

alu_write(ALU_INTF_VVCT,1,“00000011”,“00000010”,“001”,‘1’,“ALU_INTF_WRITE”, C_SCOPE);
alu_read(ALU_INTF_VVCT,1,“input data result”, C_SCOPE);
v_cmd_idx := get_last_received_cmd_idx(ALU_INTF_VVCT, 1);
await_completion(ALU_INTF_VVCT,1,100 ns, “wait till finish”); – this waits for all VVC cmds to finish
fetch_result(ALU_INTF_VVCT,1, v_cmd_idx, v_result, “Fetching result from read operation”);

You could of course make an overload procedure if you want to avoid repeating some of the commands.
I hope this helps.

Best Regards,
Erick

It is working now when I added those lines into my test sequencer

I have one more question here if you have some signals which will come out as output to tell the status how can I read it like how you are reading the result

because
work.td_vvc_entity_support_pkg.store_result(result_queue => result_queue,
cmd_idx => v_cmd.cmd_idx,
result => v_result);
this store result will store only one result

can you explain this doubt also?

Best Regards,
Riyaz

If you want to read more than one signal, i.e. status signals, from your alu_intf_read() procedure, then you can just add the output signals to the procedure and change the t_vvc_result subtype in vvc_cmd_pkg.vhd to use a record type with those signals, so that you can store the signals in the result_queue.

Best Regards,
Erick

Hi Erick,

when i drive one set of data my output will take 60 ns of time to come out and after that a ready signal will generate which indicate that the next set of data can be driven

when I do the same thing of setting the delay to 80 ns my TB is not working it is throwing an error

this is first set of stimuli

alu_write(ALU_INTF_VVCT,1,"00000011","00000010","001",'1',"ALU_INTF_WRITE", C_SCOPE);
alu_read(ALU_INTF_VVCT,1,"input data result", C_SCOPE);
v_cmd_idx := get_last_received_cmd_idx(ALU_INTF_VVCT, 1);
await_completion(ALU_INTF_VVCT,1,80 ns); -- this waits for all VVC cmds to finish
fetch_result(ALU_INTF_VVCT,1, v_cmd_idx, v_result, "Fetching result from read operation");
wait for 80 ns;

this is second set of stimuli

alu_write(ALU_INTF_VVCT,1,"00000111","00000101","010",'1',"ALU_INTF_WRITE", C_SCOPE);
alu_read(ALU_INTF_VVCT,1,"input data result", C_SCOPE);
v_cmd_idx := get_last_received_cmd_idx(ALU_INTF_VVCT, 1);
await_completion(ALU_INTF_VVCT,1,80 ns);
fetch_result(ALU_INTF_VVCT,1, v_cmd_idx, v_result, "Fetching result from read operation");
wait for 80 ns;

error is like time out for uvvm cmd : await_completion(ALU_INTF_VVCT,1,80 ns); while waiting for acknowledge from VVC

can you tell what is the reason for this error

Best Regards,
Riyaz

Hi Riyaz,

The error await_completion(ALU_INTF_VVCT,1,80 ns); while waiting for acknowledge from VVC means that the VVC is still busy executing a command, so probably the DUT is hasn’t finished doing what it’s supposed to. Try extending the timeout in await_completion().

Best Regards,
Erick

A post was split to a new topic: Randomization seed