'last_event VHDL equivalent in verilog - vhdl

I'm searching the verilog equivalent of the VHDL attribute my_signal'last_eventbut in Verilog. I have googled it without success. Does someone know how to do it ?
The 'last_event attribute is used to know the time since the signal last event.
For example, if at time 15us, signal toto toogles from 0 to 1.
Then at time 20us, toto'last_event returns 5us.

Have you tried looking into some of the verilog system tasks? Specifically the following:
$time; // Return current simulation time in 64-bit integer
$monitor("format", v1, v2, ...); // Invoke only once, and execute (
// automatically when any of the
// variables change value.
You can look at the 'nested-if-else-if' example here http://www.asic-world.com/verilog/vbehave2.html for an example of a test bench that uses these.

You could create a time variable and update it whenever the signal changes
time my_signal_last_change;
always #(my_signal) begin
my_signal_last_change = $time;
end
This works in SystemVerilog; not sure if it would in verilog (you can try changing time to reg[63:0] in case it doesn't)

Related

Signal association after port mapping-VHDL

I am working in a TOP file of a project in VHDL. I have a problem-question concerning the port mapping.
Below, is a part of the code that I am trying to implement and afterwards the description of the context.
generate_microfib:
for i in 0 to 5 generate
fib: microfib
Port Map (
InL => SignalNumber(num(i)*2 + i), --Input Left
OutR => SignalNumber(num(i)*2 + i+1) --Output Right
);
end generate generate_microfib;
The code above creates multiple components of microfib. The microfib, has an input and an output port. What I want to do is connect the left input of the current created component with the right output of the previous created one.
My initial thought was to do it inside the port mapping, but VHDL doesn't give many options for calculations in the for..generate statement. So, I decided to do it in two steps. Meaning that, I first create the desired components and afterwards do the connections (by setting the desired signals equal).
So, my question is: Is it possible to do the connections in a function for example, by setting:
SignalNumber(i)=SignalNumber(i-1)?
I know that the '<=' operator is accepted and not the '=' but I want to show you that my goal is to make those two signals equal and not assign the value of the one to the other.
When I've done things like this, I've used an array-type signal to act as an intermediate placeholder. Then, within the generate loop, you can connect the ports to the indexed locations on the array signal.
So you could try something like this, using std_ulogic as an example port type:
architecture rtl of entity is:
constant N_DEVICES : integer := 5;
signal port_connector : std_ulogic vector(N_DEVICES downto 0);
begin
-- Concurrent statements
generate_microfib : for i in N_DEVICES-1 downto 0 generate
fib : microfib
port map (
InL => port_connector(i+1)
OutR => port_connector(i)
)
end generate generate_microfib;
-- Other stuff
end architecture rtl;
Then, port_connector(N_DEVICES) acts as the input to the chain, and port_connector(0) acts as the output from the chain.
This isn't a function, but it is (relatively) clean and avoids too much of a headache with the generate statement. Functions in VHDL, though, are meant to produce calculated values, not circuit connections, so I would recommend against trying for that anyhow.

Failure to force a signal with a verified path using uvm_hdl_force?

I'm trying to force a signal to from within a uvm sequence. I'm using the uvm_hdl_force method.
My syntax, run from within the task in my uvm sequence is:
if( !uvm_hdl_force ("ex_top.ent_lvl1.ent_lvl2.signalname",1'b1);
`uvm_fatal("CM_BUSY_SEQ","uvm_hdl_force failure of signalname")
I'm finding that this always failing.
I've verified the path and if I run uvm_hdl_check_path("ex_top.ent_lvl1.ent_lvl2.signalname") it returns 1, indicating that the path exists. Given that I'm not sure why the force is failing or what I else I should be checking?
I am also open to other methods of forcing the signal high if there are better methodologies then what I'm trying.
This is a mixed code design. The top level is verilog and the lower level level modules including the one where the specific signal I'm trying to force is located are VHDL.
Thank you
From provided snippet the solution is following, wrap the fatal to begin-end. As the ; will mean end of line and thus terminates the if clause. Or if you do not want to use begin-end do not put ; after the if clause.
// this ; invokes end of condition, to be safe wrap the fatal to begin end
// |
// V
if( !uvm_hdl_force ("tb_top.test",1'b1));
`uvm_fatal("CM_BUSY_SEQ","uvm_hdl_force failure of signalname")
// |
// |
// V
if( !uvm_hdl_force ("tb_top.test",1'b1)) begin
`uvm_fatal("CM_BUSY_SEQ","uvm_hdl_force failure of signalname")
end
// Or without ;
if( !uvm_hdl_force ("tb_top.test",1'b1))
`uvm_fatal("CM_BUSY_SEQ","uvm_hdl_force failure of signalname")
Moreover most tools support their own system-tasks for forcing values:
Xcelium $xm_force(string path,string value)
Questa $signal_force(string path,string value)
There are possibly more parameters for these tasks, but I recommend to look for them inside the reference manual for your tool.
For the moment I have fixed this by moving away from uvm_hdl_force to a traditional force statement

Updating VHDL generic map values in execution

Probably an easy one, but has been a while since I've dabbled in VHDL, but I'm trying to figure out how to properly change generic values of a sub-component after instantiation, when an event happens. Some pseudo code is below that jumps to the point:
U1: PARITY
generic map (N => 8)
port map (A => DATA_BYTE,
ODD => PARITY_BYTE);
....
process(Some_button_click)
begin
// Change generic map value for N (integer) in PARITY to 10 //
end process;
I'm not in front of the code, but I've tried using 'shared variables' to no avail.... any help is greatly appreciated as this has been strangely hard to google.
I understand what you want to do, but as far as I understand generics are mean to be used only to make components reusable and flexible. It does not make sense to change a constant value at run time. My suggestion is that if you need to change the value you better use a signal port

VHDL - Why does using the length attribute directly on a function produce a warning?

I have a VHDL function that returns a std_logic_vector representation of a record and I want the length of that std_logic_vector. I am able to use the length attribute directly on the function. Why does this produce a warning in ModelSim? Am I inviting subtle problems? Googling the warning text did not turn up anything I understood to be helpful.
my_function_returns_slv(my_record)'length;
** Warning: ../src/my.vhd(line#): (vcom-1515) Prefix of predefined attribute "length" is function
call "my_function_returns_slv"
I've written the function to assemble the output by concatenating std_logic_vector representations of the record elements. The length of the record is fixed at compile time, but I do not want to hard code the length. I need the length to create signals for using the function output. So I can't just call 'length on the output of the function (ex: call 'length on a signal holding the function output) because it is not possible to declare an unconstrained signal to hold the output. I could write a similar function to calculate the length of the std_logic_vector, but that would add some significant code, especially for the number of records I have. Should I accept the ModelSim warning and carry on? Should I deal with the extra code from writing functions to assemble the bit width of my records? Is there a better solution altogether?
Helpful record pack/unpack subprograms I am making use of:
http://www.eda-twiki.org/twiki/pub/P1076/RecordReflectionToSlv/standard_functions.vhd
Thanks!
Using the 'length attribute directly on a function can be seen as just taking another part of the function result than the primary output, thus from a conceptual point of view there should be nothing wrong with that.
So I would accept the ModelSim warning, but also take it as an indication that the tool is worried about the construction, so I would check that my other tools, e.g. synthesis tools and code checkers, accept this use of an attribute directly on a function call.
Appears that you can avoid the ModelSim warning by making a function like:
function len(slv : std_logic_vector) return natural is
begin
return slv'length;
end function;
and then this won't result in a ModelSim warning:
signal MY_LEN : natural := len(slv_not(CONST));
So being able to avoid the warning using such encapsulation confirms that the warning is a little flaky in the first place.
"I need the length to create signals for using the function output. So I can't just call 'length on the output of the function (ex: call 'length on a signal holding the function output) because it is not possible to declare an unconstrained signal to hold the output."
A fun work around for sizing signals is:
constant MY_CONST : std_logic_vector := my_function_returns_slv(my_record) ;
signal MySig : std_logic_vector(MY_CONST'range) := MY_CONST ;
We have an LCS for VHDL-2017 that allows signals to be unconstrained and get their constraints from the initialization.

Verilog equivalent of time type constant

Is there a Verilog equivalent of the following statement in VHDL? I have some generic ports that require time values
constant TIME_C : time := 10 ms;
I tried this as a guess, but it failed syntax.
localparam TIME_C = 10 ms;
'ms' doesn't appear to be a reserved keyword in Verilog, but my IDE's editor highlights it blue, so I'm thinking maybe there is a way...
You can do this:
`timescale 1ms/1ms
module foo();
localparam TIME_C = 10;
...
endmodule
In Verilog, it is important to understand that variables or constants representing times are simply numerical values without any context. The timescale of the current module is what determines how the value is interpreted. In the example code above, #TIME_C will create a delay of 10ms because TIME_C equals 10 and the timescale is 1ms.
If you have to feed a time value to a port of a module, make sure you know what the timescale of the module is (if specified).
FYI, SystemVerilog added a few features related to specifying times and timescales.

Resources