I developped an user interface for simulating different types of failures on CAN signals contained in a frame (clock stuck, erroneous CRC). I need also to simulate unavailable values but in order to do so I have to use the input from the user which represents the signal name.
I don't know how to look in the database and retrieve the corresponding CAN signal in order to give it the unavailable value.
To get CAN signal from database use
signal * lookupSignal(char signalName[]);
For example:
signal * mySig = lookupSignal("MyNetwork::Node1::MyMessage::SignalName");
Then to get/set signal value
float value;
value = getSignal(mySig);
write("mySig value is %f", value);
setSignal(mySig, 0);
Related
I have an image processing entity that I want to test. I created a package with several stimulus as constant. and I created a driver to apply the stimulus to the DUT.
assuming this is the stimulus package:
package sim_pkg is
type pixel is record
x: std_logic_vector(3 downto 0);
y: std_logic_vector(3 downto 0);
end record;
type array_pixel is array (natural range <>) of pixel;
constant array_1 : array_pixel(0 to 2) :=
(0 => (x"0", x"0"),
1 => (x"1", x"1"),
2 => (x"2", x"2")
);
constant array_2 : array_pixel(0 to 3) :=
(0 => (x"0", x"0"),
1 => (x"1", x"1"),
2 => (x"2", x"2"),
3 => (x"2", x"2")
);
-- more stimulus
...
end package;
and a driver that just applies the requested array to the input of the DUT.
entity img_test is
port(pixel_out : out pixel)
end entity;
architecture foo of img_test is
begin
-- here it supposes to receive a constant name, for example array_1, and apply its element to pixel_out?
end architecture;
I am using Vunit, so I want to send a msg to the driver with the stimulus name. I know how to send a msg but I am having a problem figuring out how to tell the driver which stimuli I want to send.
I know that I can have a procedure to apply the stimulus directly from the testbench but I would like to know if it is possible to have a procedure for example apply_img that takes a stimulus name in my testbench that asks the driver to apply a specific stimulus.
procedure apply_img(start : boolean; some parameter to specify the stimulus);
Is it possible to pass a constant name to another entity in a way that this other entity can use the data object that has this name in vhdl
Pushing and popping the individual elements of the record and creating convenience wrapper subprograms is the recommended way in VUnit but let's explore the options.
What you can do is to store your pixel arrays in an associative array/dictionary type of data structure (https://en.m.wikipedia.org/wiki/Associative_array) where the key is the name you pass to the driver. The driver can then search that data structure for the data associated with the key.
You can create such a data structure from scratch but you can also use the dictionary type shipped with VUnit (https://github.com/VUnit/vunit/blob/master/vunit/vhdl/data_types/src/dict_pkg.vhd). It can only map a string (like your name) to a string so you would have to encode your pixel arrays to string to make that work. What you can do is to store your pixels using the integer vector pointer type (https://github.com/VUnit/vunit/blob/master/vunit/vhdl/data_types/src/integer_vector_ptr_pkg.vhd) and then use its encode/decode functions. Finally I recommend that you write wrapper functions to do everything in one step.
I'm searching a solution in CAPL that allows me to get the value description of a signal described in the dbc.
For example, I have the following signal that has the indicated value:
msgStatusCCAN1.PowerMode = 1
msgStatusCCAN1 is the message
PowerMode is the signal
1 is the value that corresponds in the DBC to ON
So, is there a method that doing for example getDescription(message,signal,value) will give me the description of that value that it is ON?
Thanks
If the signal PowerMode has associated Value Table then your CAPL code can refer to value ON as follows:
msgStatusCCAN1.PowerMode = msgStatusCCAN1.PowerMode::ON
I have been trying to convert this Signal of type integer into an std_logic vector and assign the converted value into another signal that has the same width as a VHDL integer
signal temp : std_LOGIC_VECTOR(31 downto 0) := (others => '0');
signal FrameCumulative : integer :=0;
temp <= to_stdlogicvector(to_unsigned(FrameCumulative));
However I get this error:
Error (10346): VHDL error at vga.vhd(107): formal port or parameter
"SIZE" must have actual or default value
I am using use IEEE.NUMERIC_STD.ALL; and use IEEE.STD_LOGIC_1164.ALL;
First I made the mistake of not checking the integer size within VHDL and tried to assign an integer into a 14-bit vector but after I gave it some thought I relised my mistake.
Now according to many on-line resources, what I am doing should work but my synthesiser complains about it.
If you do know the cause for this would you mind ellaborating on your answer rather than just posting the correct code, Thanks!
The function to_unsigned must be provided with a parameter specifying the width of the vector that you want it to produce. The function to_stdlogicvector is also not the correct thing to be using. Your line should look like this:
temp <= std_logic_vector(to_unsigned(FrameCumulative, temp'length));
The function to_unsigned is a conversion function, it must be provided with the target width. Here, as suggested by #BrianDrummond, the width is specified by taking the length attribute from the target vector itself (temp). The std_logic_vector is a type cast, where the unsigned value is simply interpreted directly as an std_logic_vector.
I am new to SV and would like to get some opinions about randomization. I have two signals.
rand bit [20:0] data;
rand bit data_valid;
I want to generate random data only when data_valid signal goes high. When valid signal is low, data should contain the previous signal. I have tried the following on
constraint valid_data {data -> data_valid ==1'b1; }
It generates random data when valid signal is high but then data becomes 0 when valid signal goes low. Is there any other way to do that? What I want is data signal should not change when valid becomes low. It should keep the current value of valid signal goes low.
Another issue is the randomization of data_valid signal. This is a 1 bit signal and I want to make this signal high randomly for 1 clock cycle only. At the moment it can remain high for any clock cycles which I don't want.
You need to build a state machine by saving a copy of the previously generated values
class tx;
rand bit [20:0] data;
rand bit data_valid;
bit [20:0] prev_data;
bit prev_data_valid;
function void post_randomize;
prev_data = data;
prev_data_valid = data_valid;
endfunction
constraint one_cycle { prev_data_valid -> data_valid == 0;}
constraint latch_data { !prev_data_valid -> data == prev_data;}
endclass
This works assuming you call randomize() once per clock cycle.
OK, I was able to solve my first problem. But still can not figure out how to generate random valid signal which will stay high one clock cycle only. Any tips would be appreciated.
I'm very new to VHDL and XILINX ISE. I use the version 13.2 for Xilinx ISE.
I want to design a very simple counter with the following inputs:
Direction
Count
The count input will be assigned to a button and I want the counter to count up or down according to direction input when the button is pressed. I have written a sample VHDL before this one. It had a clock input and It was counting according to the clock input. Now I want it to count when I press the button instead of counting synchronously.
Here's my VHDL code (please tell me if my code have a logical or any other flaw):
entity counter is
Port ( COUNT_EN : in STD_LOGIC;
DIRECTION : in STD_LOGIC;
COUNT_OUT : out STD_LOGIC_VECTOR (3 downto 0));
end counter;
architecture Behavioral of counter is
signal count_int : std_logic_vector(3 downto 0) := "0000";
begin
process
begin
if COUNT_EN='1' then
if DIRECTION='1' then
count_int <= count_int + 1;
else
count_int <= count_int - 1;
end if;
end if;
end process;
COUNT_OUT <= count_int;
end Behavioral;
I use Spartan xc3s500e and I placed the inputs accordingly. Below is my .ucf file:
#Created by Constraints Editor (xc3s500e-fg320-5) - 2013/03/18
NET "COUNT_EN" LOC = K17;
NET "COUNT_OUT[0]" LOC = F12;
NET "COUNT_OUT[1]" LOC = E12;
NET "COUNT_OUT[2]" LOC = E11;
NET "COUNT_OUT[3]" LOC = F11;
NET "DIRECTION" LOC = L13;
#Created by Constraints Editor (xc3s500e-fg320-5) - 2013/03/18
NET "COUNT_EN" CLOCK_DEDICATED_ROUTE = FALSE;
I needed to change the last line because I was getting the error:
This will not allow the use of the fast path between the IO and the Clock...
After having this error gone, I programmed the device. But the output (leds) acted crazy. They sometimes stood still for a few seconds, sometimes just flashed very fast. I could not figure out where my mistake is. I would appreciate any help, some beginner tutorials are greatly appreciated (the links i found directed me to xilinx's documentations and they seemed quite complicated for a beginner).
From your description I understand that you are not looking for an Asynchronous Counter.
What you need is counter that counts on trigger from PushButton Switch. The below RTL should work:
If any difficulty in HDL coding let me know.
You don't have a clock. Once the COUNT_EN and DIRECTION conditions are satisfied, the count_int variable is going to increase as fast as it possibly can... in fact the timing of when individual bits change will probably make the entire thing completely unstable and incorrect.
You should always use a clock... just to allow the FPGA to get the timing right.
In this case, put the clock back... then add a new signal COUNT_EN_LAST. Save the old COUNT_EN each pass through the clocked process. Only increment when COUNT_EN = '1' and COUNT_EN_LAST = '0'.
In fact, you'll next find that you need to "debounce" the input. Physical buttons/switches "bounce" and give you multiple off-on events per single button press. For that, you'd simply make COUNT_EN_LAST a vector (say 5 long), shift new values into it each time ("COUNT_EN_LAST <= COUNT_EN_LAST(3 downto 0) & COUNT_EN;"), and only increment when COUNT_EN_LAST = "01111", or right before they're all 1's. The length of the vector you need will change depending on how fast your clock is and how long the switch can bounce before settling down to the new state.