Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

How to dynamically read the input signal parameter of a procedure

Status
Not open for further replies.

Ridamir

Newbie level 3
Joined
May 23, 2018
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
54
Hello world !
After all, i want to mention that it's my first post in this forum and i'm glad to be a part of EDABOARD network.

In testbench, I have an issue with a procedure that I want to monitor its input parameter which is a signal, this signal may contains a number of my internal inputs AND/OR outputs of a module/s or top level design entity. Now the problem is how can I read continually this signal which may dynamically changes.


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
TYPE data_record IS ARRAY (natural range <>) OF STD_LOGIC;
    TYPE data_name_record IS ARRAY(natural range <>) OF STRING(1 TO 32);    
 
PROCEDURE MONITORING_VALUE( 
    N                       : IN  POSITIVE;
    SIGNAL INPUTS_OUTPUT            : IN data_record ;
    EXPECTED_VALUE          : IN data_record ;
    INPUTS_OUTPUT_NAME      : IN data_name_record;
    MONITORING_TIME         : IN TIME );



An alternative that I am using now is mapping this inputs/outputs to a signal of data_record_type :


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
SIGNAL INPUTS_ENTRED            :data_record(0 TO N-1) := ('0', '0', '0', '0');  
 
  --===========================================================================
  -- MAPPING:
  --=========================================================================== 
    
    INPUTS_ENTRED(0) <= input1;
    INPUTS_ENTRED(1) <= input2 ;
    INPUTS_ENTRED(2) <= input3;
    INPUTS_ENTRED(3) <= output1;


But which this solution, I am limited with number of inputs/outputs mapped which make my procedure not useful for all, (e.g. if i have 69 inputs and 9 outputs which I need to monitor a combine of them in each step).

I read about access type in vhdl, but as i have seen it's juts for variables, and i am using signal and 'last_event attribute which make impossible for me to jump to variables. and the entry parameter is a signal.

Thanks for all.:-o
 

During a simulation, a signal cannot change length. So this isnt just a problem with the procedure, its a problem in the testbench. The procedure has to be called from somewhere.
Inside the procedure, you can just read INPUTS_OUTPUT'length to see how long it is.

Why now explain more about what you are actually trying to do.

- - - Updated - - -

PS:

This is illegal, as the strings are not long enough:
SIGNAL INPUTS_ENTRED :data_record(0 TO N-1) := ('0', '0', '0', '0');
 

I'm trying to monitor a number of inputs reacting to an output using a procedure, this procedure has as parameters 4 inputs :
- signal INPUTS_OUTPUT which is an array of my inputs and output (Std_logic)
- EXPECTED_VALUE which represent respectively the expected value of my inputs during MONITORING_TIME and the expected value of my output in the start of monitoring and finally the expected value of my output in the end of monitoring time .( always EXPECTED_VALUE'length = INPUTS_OUTPUT'length +1 ).
- INPUTS_OUTPUT_NAME which is an array of STRING(1 TO 32) to represent the respective name of my inputs and output.
- MONITORING_TIME which represent the time of the call to procedure.

The array is unconstrained and I can enter a number none limited of inputs+output to my procedure.

My type definitions and constant definition are :
CONSTANT N :pOSITIVE := 4;
TYPE data_record IS ARRAY (natural range <>) OF STD_LOGIC;
TYPE data_name_record IS ARRAY(natural range <>) OF STRING(1 TO 32);

My procedure is :

Code:
----------------		BODY OF PROCEDURE		 ----------------	 
  	PROCEDURE MONITORING_VALUE(	
							SIGNAL INPUTS_OUTPUT	: IN data_record ;
							EXPECTED_VALUE			: IN data_record ;
							INPUTS_OUTPUT_NAME		: IN data_name_record;
							MONITORING_TIME			: IN TIME 
							)  IS
  
	BEGIN
    	
	
	WAIT FOR 0 ns ;
	
----------------		BEGINNING CHECK OF OUTPUT		 ----------------		
	NOTE("Expected value of "&INPUTS_OUTPUT_NAME(INPUTS_OUTPUT_NAME'RIGHT)&" is: "&conv_str(EXPECTED_VALUE(EXPECTED_VALUE'RIGHT - 1))
							&" in the time  "&conv_str(NOW));
	NOTE("Observed value of "&INPUTS_OUTPUT_NAME(INPUTS_OUTPUT_NAME'RIGHT)&" is: "&conv_str(INPUTS_OUTPUT(INPUTS_OUTPUT'RIGHT))
							&" in the time  "&conv_str(NOW));						
			IF (INPUTS_OUTPUT(INPUTS_OUTPUT'RIGHT) = EXPECTED_VALUE(EXPECTED_VALUE'RIGHT - 1)) THEN
				pass_req(sig_test_cnt,sig_pass_cnt, "The Check of output "&INPUTS_OUTPUT_NAME(INPUTS_OUTPUT_NAME'RIGHT)&" is PASSED");    

			ELSE    
				fail_req(sig_test_cnt,sig_fail_cnt, "The Check of output "&INPUTS_OUTPUT_NAME(INPUTS_OUTPUT_NAME'RIGHT)&" is FAILED");  

			END IF;
-------------------------------------------------------------------------
	
----------------		BEGINNING CHECK OF INPUTS		 ----------------
		FOR i IN 1 to INPUTS_OUTPUT'LENGTH - 1  LOOP
		
		
			NOTE("Observed value of "&(INPUTS_OUTPUT_NAME(i))&" is: "&conv_str(INPUTS_OUTPUT(i))
							&" in the time  "&conv_str(NOW));		
				IF (INPUTS_OUTPUT(i) = EXPECTED_VALUE(i)) THEN
					pass_req(sig_test_cnt,sig_pass_cnt, "The Check of input "&(INPUTS_OUTPUT_NAME(i))&" is PASSED");    

				ELSE    
					fail_req(sig_test_cnt,sig_fail_cnt, "The Check of input "&(INPUTS_OUTPUT_NAME(i))&" is FAILED");  

				END IF;	
		END LOOP;
-------------------------------------------------------------------------

----------------		MONITORING OF INPUTS		 ----------------		
	
	T_START := NOW;
		WAIT UNTIL INPUTS_OUTPUT'EVENT FOR MONITORING_TIME;	
	T_END 	:= NOW;
	
		IF ( NOT(INPUTS_OUTPUT'EVENT) )	THEN
			pass_req(sig_test_cnt,sig_pass_cnt, "The monitoring have been done successfully <PASSED>");   

		ELSE 
			fail_req(sig_test_cnt,sig_fail_cnt, "The monitoring have been failed <FAILED>");  

		END IF;	
--------------------------------------------------------------------------

----------------		CHECK OF STABILITY OF THE INPUTS DURING MONITORING TIME	 ----------------	
		FOR i IN 1 to  INPUTS_OUTPUT'LENGTH - 1  LOOP
		
			NOTE("Observed value of "&(INPUTS_OUTPUT_NAME(i))&" is: "&conv_str(INPUTS_OUTPUT(i))
							&" during at least "&conv_str(T_END - T_START));		
				IF (INPUTS_OUTPUT(i) = EXPECTED_VALUE(i)) THEN
					pass_req(sig_test_cnt,sig_pass_cnt, "The Check of input " &INPUTS_OUTPUT_NAME(i)&" is PASSED");    

				ELSE    
					fail_req(sig_test_cnt,sig_fail_cnt, "The Check of input " &INPUTS_OUTPUT_NAME(i)&" is FAILED");  

				END IF;	
		END LOOP;
------------------------------------------------------------------------------------------------

----------------		FINAL CHECK OF OUTPUT		 ----------------	
	NOTE("Expected value of "&INPUTS_OUTPUT_NAME(INPUTS_OUTPUT_NAME'RIGHT)&" is: "&conv_str(EXPECTED_VALUE(EXPECTED_VALUE'RIGHT))
							&" in the time  "&conv_str(T_END));
	NOTE("Observed value of "&INPUTS_OUTPUT_NAME(INPUTS_OUTPUT_NAME'RIGHT)&" is: "&conv_str(INPUTS_OUTPUT(INPUTS_OUTPUT'RIGHT))
							&" in the time  "&conv_str(T_END));						
			IF (INPUTS_OUTPUT(INPUTS_OUTPUT'RIGHT) = EXPECTED_VALUE(EXPECTED_VALUE'RIGHT)) THEN
				pass_req(sig_test_cnt,sig_pass_cnt, "The Check of output "&INPUTS_OUTPUT_NAME(INPUTS_OUTPUT_NAME'RIGHT)&" is PASSED");  

			ELSE    
				fail_req(sig_test_cnt,sig_fail_cnt, "The Check of output "&INPUTS_OUTPUT_NAME(INPUTS_OUTPUT_NAME'RIGHT)&" is FAILED");  

			END IF;
	NOTE("Last change on output "&INPUTS_OUTPUT_NAME(INPUTS_OUTPUT_NAME'RIGHT)&" have been occured at least "&conv_str(INPUTS_OUTPUT(INPUTS_ENTRED'RIGHT)'LAST_EVENT));
----------------------------------------------------------------------			

  END PROCEDURE;

P.S. pass_req and fail_req are procedures defined in a package which help to display in simulation file result the status of the check
the same for sig_test_cnt,sig_test_cnt and sig_pass_cnt which are variables which help to count number of checks and also pass and failed checks to compared to the total of check.

In my testbench, i'm calling my procedure
Code:
	INPUTS_ENTRED(0) <= CBIT_MUX13_FAILURE_spy;
	INPUTS_ENTRED(1) <= CONT_1_FUSE_ST_SPY ;
	INPUTS_ENTRED(2) <= in_duv_data.sig_XBDC;
	INPUTS_ENTRED(3) <= BDC_DSO_FAILURE_spy;

	MONITORING_VALUE(INPUTS_ENTRED,('0','1','0','0','0'),
					("CBIT_MUX13_FAILURE_spy          ","CONT_1_FUSE_ST                  ",
					"out_XBDC                        ","BDC_DSO_FAILURE_spy             "),
					TCONF_BDC_DSO_FAILURE_max);
With
Code:
 SIGNAL INPUTS_ENTRED		:	data_record(0 TO 3);

Now i'm trying to solve this issue : when I assign my inputs+output to a signal , the change on them are not detected because they are not mapped to my signal INPUT_ENTRED , HOW can I enter my signal of type data_record corresponding to INPUTS_OUTPUT parameter and my procedure keep reading dynamically its value .

P.S I have issue with LAST_EVENT been used in procedure with INPUTS_ENTRED'length instead of INPUTS_OUTPUT'length because of INPUT_OUTPUT is unconstrained, but that can be ignored.
 

Basically, you cant. A signal cannot change its length when a simulation is running. And once you've called the procedure, the length of INPUTS_ENTERED is already fixed.
But I think you're doing this wrong. You shouldnt have a single monolithic procedure to do the checking, you should have a process capturing the output and comparing it to the expected value.
You should maybe look into protected types for this (added in VHDL 2002). They are very handy for for things like this. VHDL 2008 makes life even easier with generic types and heirarchical references, making it very easy to build generic linked lists, queues etc.

You should also look into OSVVM - a scoreboard was added to V2016.10 that does eactly what you're trying to do - store up expected values and compare them to outputs as they arrive.

- - - Updated - - -

for example:


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
shared variable sboard    : my_scoreboard_t;
 
.....
--process to generated expected results:
process
begin
 
--  stick in all expected data at time 0
  for i in expected_data'range loop
    sboard.push(expected_data(i));
  end loop;
 
  wait
end process;
 
 
output_capture_proc : process(clk)
begin
  wait until rising_edge(clk) and output_en = '1';
 
  -- check the data as it is generated.
  sboard.check(output_data);
end process;



The beauty of this scoreboard is that it can use any type, and the check function is also user defined. So you can have a generic testbench in which all you need to pass in is the type and the check function.
 
Thanks TrickyDicky, I'll try to change my way of doing this, maybe swap to VHDL 2008 will be a better choice for me to use all features of the language. :)
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top