On Jan 3, 2012, at 7:10 AM, René Doß wrote:

> That was a good hint,
> 
> 
> rm -rf work
> mkdir work
> ghdl -i *.vhd
> ghdl -i --work=simprim /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/*.vhd
> ghdl -i --work=simprim 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/mti/*.vhd
> ghdl -i --work=simprim 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/*.vhd
> ghdl -m -g -Psimprim -Wa,--32 -Wl,-m32 --warn-no-vital-generic 
> --no-vital-checks --ieee=synopsys -fexplicit  tb_lm_cpu
> ../../../src/vital2000/timing_b.vhdl:196:15:warning: procedure "vitalerror" 
> is never referenced
> ../../../src/vital2000/timing_b.vhdl:217:15:warning: procedure "vitalerror" 
> is never referenced
> ../../../src/vital2000/prmtvs_b.vhdl:1041:15:warning: function "toedge" is 
> never referenced
> ../../../src/synopsys/std_logic_arith.vhdl:391:14:warning: function 
> "left_signed_arg" is never referenced
> ../../../src/synopsys/std_logic_arith.vhdl:400:14:warning: function 
> "left_unsigned_arg" is never referenced
> ../../../src/synopsys/std_logic_arith.vhdl:409:14:warning: function 
> "mult_signed_arg" is never referenced
> ../../../src/synopsys/std_logic_arith.vhdl:418:14:warning: function 
> "mult_unsigned_arg" is never referenced
> ../../../src/synopsys/std_logic_arith.vhdl:1258:14:warning: function 
> "unsigned_return_boolean" is never referenced
> ../../../src/synopsys/std_logic_arith.vhdl:1266:14:warning: function 
> "signed_return_boolean" is never referenced
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_RAMB16BWER.vhd:1199:18:warning:
>  universal integer bound must be numeric literal or attribute
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_RAMB16BWER.vhd:1229:18:warning:
>  universal integer bound must be numeric literal or attribute
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_RAMB8BWER.vhd:1192:18:warning:
>  universal integer bound must be numeric literal or attribute
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_RAMB8BWER.vhd:1222:18:warning:
>  universal integer bound must be numeric literal or attribute
> analyze tb_lm_cpu.vhd
> analyze /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/simprim_Vcomponents.vhd
> analyze /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/simprim_Vpackage.vhd
> analyze lm_cpu_map.vhd
> analyze 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_INV.vhd
> analyze 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_RAMB16BWER.vhd
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_RAMB16BWER.vhd:1199:18:warning:
>  universal integer bound must be numeric literal or attribute
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_RAMB16BWER.vhd:1229:18:warning:
>  universal integer bound must be numeric literal or attribute
> analyze 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_BUF.vhd
> analyze 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_RAMB8BWER.vhd
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_RAMB8BWER.vhd:1192:18:warning:
>  universal integer bound must be numeric literal or attribute
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_RAMB8BWER.vhd:1222:18:warning:
>  universal integer bound must be numeric literal or attribute
> analyze 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_SFF.vhd
> analyze 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_LUT6.vhd
> analyze 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_LUT5.vhd
> analyze 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_ZERO.vhd
> analyze 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_CARRY4.vhd
> analyze /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_FF.vhd
> analyze 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_ONE.vhd
> analyze 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_OBUF.vhd
> analyze 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_CKBUF.vhd
> analyze 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_MUX2.vhd
> analyze 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_RAMD64_ADV.vhd
> analyze 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_LATCHE.vhd
> analyze 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_SRLC16E.vhd
> analyze 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_RAMD32.vhd
> analyze 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_ROC.vhd
> analyze 
> /opt/Xilinx/13.1/ISE_DS/ISE/vhdl/src/simprims/primitive/other/X_TOC.vhd
> elaborate tb_lm_cpu
> red@linux-nrd1:~/projekt/mips/LM_CPU/ise/netgen/map> ls
> e~tb_lm_cpu.o   lm_cpu_map.v    simprim-obj93.cf       tb_lm_cpu.o      
> work-obj93.cf  X_FF.o      X_LUT6.o  X_RAMB16BWER.o  X_ROC.o      X_ZERO.o
> lm_cpu_map.nlf  lm_cpu_map.vhd  simprim_Vcomponents.o  tb_lm_cpu.vhd    
> X_BUF.o        X_INV.o     X_MUX2.o  X_RAMB8BWER.o   X_SFF.o
> lm_cpu_map.o    makefile        simprim_Vpackage.o     unisim-obj93.cf  
> X_CARRY4.o     X_LATCHE.o  X_OBUF.o  X_RAMD32.o      X_SRLC16E.o
> lm_cpu_map.sdf  makefile~       tb_lm_cpu              work             
> X_CKBUF.o      X_LUT5.o    X_ONE.o   X_RAMD64_ADV.o  X_TOC.o
> red@linux-nrd1:~/projekt/mips/LM_CPU/ise/netgen/map> make run
> ghdl -r tb_lm_cpu --sdf=./=lm_cpu_map.sdf --wave=tbench.ghw --stop-time=500us
> ./tb_lm_cpu:internal error: cannot allocate stack: memory exhausted
> ghdl: compilation error
> make: *** [run] Error 1
> 
> That runs out of stack space. I have use the stack size option 200MB but this 
> crashed anywhere.
> I feel it is a short step into the goal.
> 
> Thanks
> 
> René

From my limited knowledge of ghdl it suggests there is something memory leaking.

I'd expect the messages:

warning: universal integer bound must be numeric literal or attribute

have something to do with it, associated with lines 1192 and 1222 of 
X_RAMB8BWER.vhd and X_RAMB16BWER.vhd, which are likely derived from the same 
source, varying in size in the memory array.

Syntax warnings

Simply put there are no syntax warnings in VHDL, ambiguous syntax is not 
allowed.  I'd imagine these 'warnings' are left over from the early days of 
ghdl.  VHDL analyzers and simulators tend to be grown organically, and allowing 
questionable constructs by can allow you to continue development.  It would 
likely signify something that wasn't properly revisited later and possibly due 
to a different cause are fatal during simulation here.  To be clear this would 
represent a shortcoming in the ghdl implementation, something not yet finished.

The warning message would have to do with the right bound of a for loop 
iteration scheme (see work around below, di'length-1).  The right bound of the 
range for a standard logic vector di is determined by getting the length and 
subtracting 1, the left bound specified as 0.  The issue is that ghdl seems to 
not properly propagate the type of the left hand side of a predefined operator 
to the output of the operator.  I believe this has shown up twice this year on 
ghdl-discuss.

(I don't have the ability to release new versions of ghdl on ghdl.free.fr.  It 
took Tristan's intervention to be able to make the Mac OS X mcode version 
available there. Because of that I haven't fixed it.)

Semantic Restrictions on the for loop parameter specification

Those simply interested in a potential solution can skip to the Is it possible 
to work around the ghdl problem?  section below. Us VHDL lawyers try to never 
miss an opportunity to pontificate.

Holding Tristan in high regard we can look for deeper meaning in the warning, 
checking semantics found in various versions of the LRM.  The bound from the 
warning refers to the rightmost range bound given in the for loop range 
constraint.

From IEEE 1076-1993 (LRM-93), 8.9 Loop statement, paragraphs 9 and 10:

For a loop statement with a for iteration scheme, the loop parameter 
specification is the declaration of the loop parameter with the given 
identifier. The loop parameter is an object whose type is the base type of the 
discrete range. Within the sequence of statements, the loop parameter is a 
constant. Hence, a loop parameter is not allowed as the target of an assignment 
statement. Similarly, the loop parameter must not be given as an actual 
corresponding to a formal of mode out or inout in an association list.

For the execution of a loop with a for iteration scheme, the discrete range is 
first evaluated. If the discrete range is a null range, the iteration scheme is 
said to be complete and the execution of the loop statement is therefore 
complete; otherwise, the sequence of statements is executed once for each value 
of the discrete range (subject to the loop not being left as a consequence of 
the execution of a next statement, an exit statement, or a return statement), 
after which the iteration scheme is said to be complete. Prior to each such 
iteration, the corresponding value of the discrete range is assigned to the 
loop parameter. These values are assigned in left-to-right order.

Part of the understanding required to implement the semantic restrictions 
therein would be understanding what is meant by discrete range and whether 
di'length-1 is valid as a bound of a discrete range.

From the LRM-93 Glossary:

B.76 discrete range: A range whose bounds are of a discrete type.(§ 3.2.1, § 
3.2.1.1) 

B.77 discrete type: An enumeration type or an integer type. Each value of a 
discrete type has a position number that is an integer value. Indexing and 
iteration rules use values of discrete types. (§ 3.1) 
  
From 14.1 Predefined Attributes (LRM-93):

A'LENGTH[(N)] Kind: Value. Prefix:Any prefix A that is appropriate for an array 
object, or an alias thereof, or that denotes a constrained array subtype 
Parameter:A locally static expression of type universal_integer, the value of 
which must not exceed the dimensionality of A. If omitted, it defaults to 1. 
Result Type:universal_integer. Result:Number of values in the Nth index range; 
i.e., if the Nth index range of A is a null range, then the result is 0. 
Otherwise, the result is the value of T'POS(A'HIGH(N)) - T'POS(A'LOW(N)) + 1, 
where T is the subtype of the Nth index of A.

So di'length is a type universal_integer  which is the base type (in abstract) 
for integer types.   Further the type of a result of a subtraction ("-") is the 
type of the left hand argument (di'length).  You might expect the a range given 
as 0 to di-length-1 is discrete.  (And note that Modeltech (mti) appears 
capable of elaborating and simulating the for loop iteration schemes found in 
these two models).  This is where the supposition that ghdl is unfinished in 
this area comes from.  

You could note the "never referenced" messages aren't syntax warnings and my 
above statement on syntax warnings is not inconsistent with these warnings.

"cannot allocate stack: memory exhausted"

The runtime error "cannot allocate stack: memory exhausted" message comes from  
ghdl/translate/grt/grt-processes.adb line 126 in procedure Process_Register.  
grt is the GHDL Run Time, the simulator kernel that executes the model.  
Essentially the analyzer is constructing a model that the simulator can't 
execute faithfully, instead causing a memory leak.  It would essentially be 
getting off the beaten track and likely never returning to the proper confines 
of the model. Likely a very large value is being taken as a range bound and 
something very large is being inferred.

Is it possible to work around the ghdl problem?

By definition this would imply modifying the Xilinx Models. I'd suggest first 
copying them somewhere else then compiling them into your simprim library after 
modification.  You'd want to leave the original copies intact.

We look at the two lines 1192 and 1222 in X_RAMB8BWER.vhd and lines 1199 and 
1229 in X_RAMB16BWER.vhd to see what's peculiar (particular) about them.

Both sets of noted lines reference a for loop:

for i in 0 to di'length-1 loop

One in procedure prcd_write_ram_col, one in procedure prcd_write_ram_ox.  A 
quick survey shows these are the only two places di'length-1 is derived.

Right about now we bog down a bit because these models were written to 
represent any width RAM then later caste (copied, instantiated) to particular 
entity/architecture pairs.  This has to do with columns in the RAM array see 
prcd_col_wr_ram_b and prcd_ox_wr_ram_b for example, where we find that 
arguments to prcd_write_ram_col and prcd_write_ram_ox can contain different di 
ranges inherited from the argument subtype:

  dib_tmp(7 downto 0), dib_tmp(15 downto 8) dib_tmp(23 downto 16), dib_tmp(31 
downto 24)

as arguments to procedures prcd_write_ram_col and prcd_write_ram_ox for various 
RAM widths fitted into RAM columns (a physical cell restriction no doubt).

These are used to assign array elements  (bits) from the input (and constant) 
standard logic vector di to the mem_proc_tmp an alias for the mem_proc inout 
port standard logic vector value with a defined range of memproc-lenth-1 downto 
0.  There's this assumption the lengths of di and proc_mem match, that they are 
both byte width (length = 8).

A secondary goal here is to not re-write the models, fraught with chance of 
introducing error., instead we're looking for a simple solution.

You could note that if di and proc_mem match in length, that we also have an 
alias di_tmp whose  range is specified identically to mem_proc_temp.

In the for loop iteration schemes:

for i in 0 to di'length-1 loop

We could use the range of either di_tmp or proc_mem_tmp  e.g. :

for i in  proc_mem_tmp'RANGE  loop

for lines ll92 and 1222 of  X_RAMB8BWER.vhd and lines 1199 and 1229 of 
X_RAMB16BWER.vhd  avoiding the problem of the expression (di'length-1) 
propagating the left hand type to the output type which ghdl appears to have 
problems with.

When the left hand and right sides of the variable assignments in the following 
lines involve the _tmp aliases, it's unclear why di'length was used in any 
event.  The goal is to have matching ranges for the di value and proc_mem value 
(their aliases).

The Actual Fixes:

So try changing the range constraint of the for loop iteration schemes to avoid 
using expressions, e.g.:

        for i in  proc_mem_tmp'RANGE  loop

for lines 1192 and 1222 of X_RAMB8BWER.vhd and lines 1199 and 1229 of 
X_RAMB16BWER.vhd respectively.  

These should be guaranteed to be discrete ranges not depending on predefined 
operators passing their lefthand side type to the output type.

Let us know if that works.  You could note these changes should be compatible 
with how Xilinx uses the models.


 
_______________________________________________
Ghdl-discuss mailing list
[email protected]
https://mail.gna.org/listinfo/ghdl-discuss

Reply via email to