I want to use an old value of a signal in a SystemVerilog assertion.
This is what I am currently doing
logic [ADDRESS_WIDTH-1:0] old_address [1:0];
always_ff#(posedge rdclock) begin
old_address[0] <= rdaddress;
old_address[1] <= old_address[0];
end
property FooBar;
#(posedge rdclock) rden |-> ##2 q == mem[old_address[1]];
endproperty
Baz: assert property (FooBar);
Is this how is should be done, or can I somehow use an old version of rdaddress directly in the assertion?
You can use the $past(...) system task. Using $past(rdaddress) will return the value of rdaddress that was sampled in the previous cycle. You can specify how many cycle in the past to go with the second argument. In your case, calling $past(rdaddress, 2) will return the value of rdaddress 2 cycles before.
Related
I want to know if it is possible to convert a enum type, like FSM states to std_logic_vector or integer. I'm doing a testbench with OSVVM for a FSM and I want to use the scoreboard package to automatically compare the expected state with the actual one.
Thanks!
To convert to integer, use:
IntVal := StateType'POS(State) ;
From there, it is easy to convert to std_logic_vector, but I prefer to work with integers when possible as they are smaller in storage than std_logic_vector. For verification, it will be easier if you start to think more about integers when the value is less than 32 bits.
If you need it as std_logic_vector, using only numeric_std you can:
Slv8Val := std_logic_vector(to_unsigned(IntVal, Slv8Val'length)) ;
For verification, I liberally use numeric_std_unsigned, so the conversion is a easier:
Slv8Val := to_slv(IntVal, Slv8Val'length) ;
In the event you have an integer and want to convert it back to a enumerated value, you can use 'VAL.
State := StateType'VAL(IntVal) ;
In OSVVM, we use records with resolved values to create a transaction interface. We have a resoled types for integers (osvvm.ResolutionPkg.integer_max). We transfer enumerated values through the record using 'POS (as we put it in) and 'VAL (as we get it out).
Note don't confuse 'VAL with 'VALUE. 'VALUE converts a string to a value - opposite to 'IMAGE.
You of course learn all of this in SynthWorks' OSVVM class :).
Maybe like this...
function my_func(inp : t_my_enum) return integer is
begin
case inp is
when stateA =>
return 1;
when stateB =>
return 2;
when others =>
return 0;
end case;
end function my_func;
... <= my_func(stateB);`
I am a newbie in verilog. I have been searching online and most of them suggest to not use for-loop in verilog coding. So is there a better alternative to replace for-loop?
The problem that I am facing now is that I need to perform 1 or 2 for-loop in a case statement. And I have been thinking of better alternatives but come up with none. It will be great if any one of you can shed some light on this.
Example of my code:
always #(*)
case (help)
4'd1: for (i=A; i<=20;i=i+B)
begin temp[i-1]=1; end
4'd2: for (i=A; i<=20;i=i+B)
begin temp[i-1]=1; B=B+1; end
4'd3: begin
for (i=A; i<=20;i=i+B)
begin temp[i-1]=1; B=B+1; end
for (i=A; i>=1;i=i-B)
begin temp[i-1]=1; B=B+1; end
end
default: temp = 0;
For-loops are fine in Verilog, but they need to able to static unroll if you plan on synthesizing. Static unroll means the loop is not depended on any external variables. For example for(i=0;i<10;i=i+1) is static. for(i=A; i<=20;i=i+B) is not static as it is a depends on the variables A and B.
You can make a loop static my moving the variables as a condition inside the for-loop. for(i=A; i<=20;i=i+B) becomes:
tmp_var = A;
for (i=0; i<=20;i=i+1) begin
if (i==tmp_var) begin
// ... your logic here ...
tmp_var = tmp_var+B;
end
end
Issues that need to be addressed beyond the scope of the question:
They way you are using B and temp is a little concerning.
B appears to be an input, but you are also incrementing it. For synthesis it is illegal to manipulate an input. If it is an input, then create a local variable with default value as B and you may change this value later in the within same always block. If it is not an input, then it is creating latching logic; which is not good and I will cover that next with temp.
temp is latching logic. Latching logic are troublesome because timing is critical; knowing when the latch is transparent or closed, and respecting the hold time requirements. The more complex the logic the harder it is to predict. In RTL one way latches are inferred is by incomplete assignments inside an combinational blocks (ie always #*). To resolve this, make sure every bit is assigned each pass of the combinational blocks. One way to safe guard this is to assign default values before staring your logic. Example:
always #(*) begin
temp = 0; // default to a constant
temp_B = B; // default to an input value
// ... your logic ...
end
timescale 1ns/10ps
/* resource counter for nor gates
*/
module global_vars;
integer count;
endmodule
module my_nor(y, a, b);
output y;
input a, b;
global_vars gv;
/* at instantiation increment the resources used */
gv =gv +1;
/* add 2ns inherent delay */
nor #2 nor1(y,a,b);
endmodule
When I compile, there is one syntax error at global_vars gv;
I have no idea. Should I initial the gv?
In verilog you can not just do this:
gv = gv +1;
wire types need to use assign:
wire gv;
assign gv = a + b;
reg types can use initial, always #* or always #(posedge clk).
always #* begin
gv = a + b;
end
Your trying to use an instance like a variable, I am not sure what your trying to do with your global_vars, may be make a global variable but creating an instance would make it local not global. Here you would do just as well to make gv an integer rather than an instance.
Note
Wire assignment and always #* are combinatorial, is there is no time delay in the assignment, therefor the value can not be directly referenced to itself. For example
gv = gv + 1;
Is a combinatorial loop, when do you expect the +1 to happen. This is normally solved by making gv a flip-flop and updating its value on a clock edge:
always #(posedge clk) begin
gv <= gv + 1;
end
In this case you still need to set an initial value for gv. for FPGAs this can be done using an initial or an async reset for ASIC.
FPGA using initial:
initial begin
gv = 'b0;
end
always #(posedge clk) begin
gv <= gv + 1;
end
Or for ASIC using reset:
always #(posedge clk or negedge rst_n) begin
if (~rst_n) begin
gv <= 'b0;
end
else begin
gv <= gv + 1;
end
end
It looks like you are trying to embed a reference to a global variable within a synthesizable module so that you can count how many times that module has been instantiated. As #Morgan has already pointed out, you can't reference a module instantiate as a variable. But there is an even more fundamental problem -- you are trying to mix behavioral code (i.e. global variables) into synthesizable code and that just doesn't work.
Creating a synthesized module is really a two step process -- design and then coding. In the design phase, you figure out what kind of logic you are trying to create. You don't need to go down to the gate level, but you should be able to sketch out the function with clouds of combinatorial logic, registers, FIFOs, memories etc. Once you've gained some familiarity with the language, this may strictly be a mental process rather than something committed to paper, but you still need to think about the logic you are creating. Then once you have designed your circuit, you actually go write the code to implement your design.
Global variables do not exist in hardware. You can make a counter that is accessible by multiple modules, but but it would need some sort of arbitration process. But what you're trying to do is create a run-time counter that counts up the number of modules instantiated, for which there is no hardware analog. You could use 'define statements to instantiate a variable number of modules and have a signal from each module which is defined as '1' if the module is instantiated and '0' if it isn't and then count the number of '1's, but that is self defeating since you already had to define a macro telling you the number of modules before you instantiated them! In which case, you might as well just use the macro value directly and dispense with all the extra signals.
How do I write a code segment which would evaluate a generic and create (or not create) an attribute accordingly?
Example :
if G_MY_GENERIC then
attribute my_attribute_typ : string;
attribute my_attribute_typ of signal_having_an_attr : signal is "value";
else
--nothing is created
end if;
It is perfectly possible to write something similar to that, but the attribute will only be visible in the scope of the generate statement.
g_something: if test_condition generate
attribute my_attribute_typ : string;
attribute an_attribute of my_attribute_typ: signal is "value";
begin
-- attribute is visible in this scope
p_my_process: process(clk)
begin
-- attribute is also visible here
end process;
end generate;
-- but not here
Instead you have to use something like the following to conditionally set an attribute (cumbersome, but achieves the result):
signal asvRam : svRam_at(0 to gc_nFifoDepth-1) := (others => (others => '0'));
type svStr_at is array(boolean) of string(0 to 10);
constant c_svRamStyle : svStr_at := (false => " ", true => "distributed");
attribute ram_style : string;
attribute ram_style of asvRam : signal is c_svRamStyle(gc_bDistributedRam);
We talked more generalized conditional compilation in the IEEE VHDL Working Group. The debate was heated. Some wanted a compile time approach (similar to 'C') and some an elaboration time approach. Compile time approach works well in C because constants are also compile time objects, however, in VHDL, a compile time approach will not understand things in the VHDL environment, and hence, using a generic is not an option. OTOH, the compile time option would probably give you vendor name, tool type (simulator, synthesis, ...), ...
I have added your code as a requirement to the proposal page. It is at: http://www.eda.org/twiki/bin/view.cgi/P1076/ConditionalCompilation
If you are willing to share additional insight on your application, I would like to add that to the proposal also.
Basically: this is exactly how VHDL does not work. In VHDL you declare your intent to use specific bits of hardware, and then the synthesizer attempts to connect those bits of hardware. Any semblance of dynamically creating hardware like for ... generate loops are essentially just a semblance: syntactic sugar to take the pain away.
What you can do is conditionally assign to signals/variables:
process (sig1, sig2, enable) is
begin
if enable = '1'
then
out <= sig1;
else
out <= sig2;
end if;
end process;
I am writing a statemachine, which has a generic parameter, and some states existence depends on this. Since I have my states defined in something like an enum (don't know the vhdl term for it), I wonder if I can define this enum depending on the generic somewhat like so:
generic(x: bool); -- in the entity
....
architecture ...
if x then generate
type states_t is (State1, State2, State3ifX)
else
type states_t is (State1, State2)
end generate;
variable state : states_t;
begin
case state is
....
if x then generate
when State3ifX =>
...
end if;
end case
end architecture;
Do I have to carry the dead weight (logic for state3, danger to drop into it (does not matter in my case since I do not expect radiation), additional bit since ceil(ld(3))=2 > ld(2)=1), or is there a possibility to strip unnecessary state(s)?
(In my case there are several states that could be stripped, however seperate architectures are not worth while the effort)
you can define the "states"-type in a process that is optionally generated using a generic. see a reference example below:
entity blabla is
generic(sel: std_logic := '0');
port(
...
architecture Behavioral of blabla is
begin
q1: if sel='0' generate
p: process(clk)
type t_state is (s1, s2, s3);
variable state: t_state;
begin
if rising_edge(clk) then
...
end if;
end process;
end generate;
q2: if sel='1' generate
p: process(clk)
type t_state is (s1, s2);
variable state: t_state;
begin
if rising_edge(clk) then
...
end if;
end process;
end generate;
I can't think of a way to achieve what you need.
On the upside, your concern about having to "carry the dead weight (logic for state3, danger to drop into it)" is not something you need to worry about - the synthesizer will optimise the logic away, so the state register will only be as big as it needs to be for the states you can actually reach.
I know its an old tread but still a hit on google so Im adding how Im doing it
label: if x generate
declarations <- put types, signals & attribures here !!!!
begin
ur code
end generate label;
You might want to consider second architecture or even simpler just a different entity - just another vhd file with slightly different name (like _x1, then _x2)
I find "genercis system" not really practical in more advanced cases (to much bloat-code to write), and then u might use different synthezisers so two archoitecture with one entity might not work, generate with decalrations inside might not work.... I would create different vhd for that - it will work in all the cases)
Cheers