2
votes

This code works with some tools

  • Aldec Riviera Pro

but not others

  • GHDL ( ERROR choice must be locally static expression)
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;

ENTITY INSTRUCTION_PROCESSOR IS

    PORT (
        clk : IN std_logic;
        instruction : IN INTEGER
    );
END ENTITY INSTRUCTION_PROCESSOR;
ARCHITECTURE behavioural OF INSTRUCTION_PROCESSOR IS

    TYPE INSTRUCTION_t IS RECORD
        instr : INTEGER;
        cycles : INTEGER;
    END RECORD;

    CONSTANT CMD_A : INSTRUCTION_t := (instr => 0, cycles => 5);
    CONSTANT CMD_B : INSTRUCTION_t := (instr => 1, cycles => 3);

BEGIN
    PROCESSOR : PROCESS (clk)
        VARIABLE loop_cycles : INTEGER := 0;
    BEGIN
        IF clk'event AND clk = '1' THEN
            CASE instruction IS
                WHEN CMD_A.instr =>
                    loop_cycles := CMD_A.cycles;

                WHEN CMD_B.instr =>
                    loop_cycles := CMD_B.cycles;

                WHEN OTHERS =>
                    NULL;
            END CASE;
        END IF;
    END PROCESS;
END ARCHITECTURE;

https://www.edaplayground.com/x/jYD

since CMD_A and CMD_B are declared as constant records i would expect this to work...

any words of wisdom or is it just a bad idea?

2
Added playground example :edaplayground.com/x/jYDCaspar

2 Answers

6
votes

I'm not sure the ghdl-0.35 version on EDA playground is up to handling --std=08 (-2008) for this issue without trying it. A recent ghdl-0.37-dev version shows it works:

ghdl -a --std=08 instruction_processor.vhdl
ghdl -e --std=08 tb
instruction_processor.vhdl:68:8:error: for default port binding of component instance "uut":
instruction_processor.vhdl:68:8:error: type of signal interface "instruction" declared at line 56:9
instruction_processor.vhdl:68:8:error: not compatible with type of port "instruction" declared at line 9:9
instruction_processor.vhdl:68:8:error: signal interface "cycles" has no association in entity "instruction_processor"
ghdl:error: compilation error

even if the testbench and/or entity header needs a bit of work. Both INSTRUCTION_PROCESSOR and TB are located in the same design file used above.

The IEEE Std 1076-2008 revision changed some definitions in 9.4.2 Locally static primaries

9.4.2 Locally static primaries

An expression is said to be locally static if and only if every operator in the expression denotes an implicitly defined operator or an operator defined in one of the packages STD_LOGIC_1164, NUMERIC_BIT, NUMERIC_STD, NUMERIC_BIT_UNSIGNED, or NUMERIC_STD_UNSIGNED in library IEEE, and if every primary in the expression is a locally static primary, where a locally static primary is defined to be one of the following:

...
m) A record aggregate in which all expressions in element associations are locally static expressions.
...

Prior to -2008 a an aggregate could not be locally static. An aggregate is an expression which is 'a formula that defines the computation of a value', previously always globally static for a constant declaration value expression.

Allowing certain expressions to be locally static comes from the VHDL-200x effort producing the -2008 revision (Fast Track Proposal FT-22). The idea is expressions with locally static primaries that produce values from basic or predefined operations including those found in IEEE library packages listed above are implemented as pure functions and are not dependent on elaboration. To avoid confusion a procedure call is a statement.

Analyzing your code with Aldec Riviera Pro used a -2008 compliant flag according to the EDA playground session from your comment:

https://www.edaplayground.com/x/jYD

Should an earlier revision of the standard be required due to tool chain constraints either the case statement can be replaced by an if statement or a concurrent conditional assignment statement which implies and if statement equivalent. A selected signal assignment statement on the other hand implies a case statement and conforms to the same semantics.

0
votes

Try to put constraint into the integer.

instruction : IN INTEGER RANGE 0 TO ...;