In general an analysis error is associated with a line of your VHDL design description. Comments that are close don't really cut it and the actual error message can be significant.
library ieee;
use ieee.std_logic_1164.all;
entity controller is
Port (
reset: in std_logic;
clk: in std_logic;
ring_k_1: in std_logic;
b_n: in std_logic_vector(3 downto 0);
start: in std_logic;
STOP: out std_logic;
LOAD_CMD: out std_logic;
ADD_CMD: out std_logic;
BYPASS_CMD: out std_logic
);
end controller;
architecture Behavioral of controller is
--declare states
type state_typ is (IDLE, INIT, TEST, ADD, BYPASS);
signal state : state_typ;
begin
process(reset,clk)
variable i : natural := 0;
begin
if reset = '0' then
state <= IDLE;
elsif clk'event and clk = '1' then
case state is
when IDLE =>
if START = '1' then
state <= INIT;
else
state <= IDLE;
end if;
when INIT =>
state <= TEST;
when TEST =>
if ring_k_1 = '1' then
state <= IDLE;
elsif ring_k_1 = '0' and b_n(i) = '0' then
state <= BYPASS;
i := i+1;
elsif ring_k_1 = '0' and b_n(i) = '1' then
state <= ADD;
i := i+1;
-- How do you prevent b_n(i) from going outside of 3 downto 0?
end if;
when others => -- when ADD, when BYPASS must have all states
end case;
end if;
end process;
STOP <= '1' when state = IDLE else '0';
ADD_CMD <= '1' when state = ADD else '0';
BYPASS_CMD <= '1' when state = BYPASS else '0';
LOAD_CMD <= '1' when state = INIT else '0';
end Behavioral;
Besides the corrections you made there is at least one more error with the case statement, in that all the choices must be represented you are missing representation for states ADD and BYPASS:
If the expression is the name of an object whose subtype is locally
static,whether a scalar type or an array type, then each value of the
subtype must be represented once and only once in the set of choices
of the case statement, and no other value is allowed;...
(From the LRM)
I don't know enough about the intent of your design to add branches from states ADD
and BYPASS
.
Comment out the when others =>
and ghdl tells us directly that two state enumerations are represented among the choices:
ghdl -a controller.vhdl
controller.vhdl:34:13: no choices for add to bypass
ghdl: compilation error
Error messages aren't standardized in VHDL, ghdl pointed to the line the case statement begins on but did specify the range of values missing from the specified choices.
Notice the simple mechanism used to allow analysis to successfully complete doesn't handle state transitions and likely should.
There's also nothing apparent that will keep b_n(i) within the index range 3 downto 0. Scalar arithmetic operators their conventional mathematical meaning while b_n(i) evaluation will be bounds checked potentially resulting in a run time error should b_n(i)
be evaluated and i
as an index and fall outside the subtype index range.
Integer arithmetic results can be out of range for use as an index to b_n. You are only using +
so only have to limit i
to 3
(b_n'LEFT
).
If you synthesize the design you'd want to range constrain i
to specify the number of bits necessary to implement i
(as a counter in this case).
Range constraining i
for synthesis implies evaluating for 3
before assigning the new i
value to avoid an out of range error. If i = 3, set i
to 0
instead, otherwise add 1
to `i1.
In place of i := i+1;
use
if i=3 then
i := 0;
else
i:= i+1;
end if;
For synthesis declare the range of i:
variable i : integer range 0 to 3 := 0;
if b_n'LEFT
were the result of a generic or constant declaration and use you could use that instead of 3:
variable i : integer range b_n'RIGHT to b_n'LEFT := b_n'RIGHT; -- 3 downto 0
or
variable i : integer range b_n'RANGE := b_n'RIGHT; -- where b_n'RIGHT = 0
And in place of i := i+1;
in your original code use
if i = b_n'LEFT then
i := 0; -- or use i := b_n'RIGHT;
else
i:= i + 1;
end if;
Addendum
Your changed code had an else if
in place of elsif
where the clock was being evaluated:
library ieee;
use ieee.std_logic_1164.all;
entity controller is
port (
reset: in std_logic;
clk: in std_logic;
ring_k_1: in std_logic_vector(3 downto 0);
b_n: in std_logic_vector(3 downto 0);
start: in std_logic;
STOP: out std_logic;
LOAD_CMD: out std_logic;
ADD_CMD: out std_logic;
BYPASS_CMD: out std_logic
);
end controller;
architecture behavioral of controller is
--declare states
type state_typ is (IDLE, INIT, TEST, ADD, BYPASS);
signal state : state_typ;
begin
process(reset,clk)
--variable i : natural := 0;
variable i : integer range b_n'RIGHT to b_n'LEFT := b_n'RIGHT; -- 3 downto 0
begin
if reset = '1' then
state <= IDLE;
STOP <= '1';
elsif clk'event and clk = '1' then -- else if
case state is
when IDLE =>
if START = '1' then
state <= INIT;
else
state <= IDLE;
STOP <= '1';
end if;
when INIT =>
LOAD_CMD <= '1';
state <= TEST;
when TEST =>
if ring_k_1(3) = '1' then
state <= IDLE;
STOP <= '1';
elsif ring_k_1(3) = '0' and b_n(i+1) = '0' then
state <= BYPASS;
BYPASS_CMD <= '1';
-- i := i+1;
if i = b_n'LEFT then
i := 0;
else
i:= i + 1;
end if;
elsif (ring_k_1(3) = '0' and b_n(i+1) = '1') then
state <= ADD;
ADD_CMD <= '1';
if i = b_n'LEFT then
i := 0; -- or use i := b_n'RIGHT;
else
i:= i + 1;
end if;
end if;
when BYPASS =>
state <= TEST;
when ADD =>
state <= TEST;
end case;
end if; --end for the clock event
end process;
end behavioral;
The analyzer I was using complained that there should have been if
following end
instead of process (above end behavioral
). It shows among other things the value of readability as well as including the actual error messages:
cont_mod.vhdl:72:9: 'if' is expected instead of 'process'
ghdl: compilation error
Note the line number : character position wasn't particularly helpful other than to tell us something else was missing an enclosing end
statement. If I'm not mistaken this is the same problem Vladimir Craver pointed out in his answer, which I used as a starting point.
I'd suggest a separate question might be in order should you need help with the simulation results.
Now that your design description for entity controller should analyze perhaps you could ask a separate question should you have trouble with functionality.
I reformatted your second code posting to allow the error to show up a bit easier. Through indentation we don't see any missing level of end if
which leaves a syntax error implying the need for another level. else
and if
in
else if clk'event and clk = '1' then
implies a separate end if
for the else
and if
.
Best Answer
If you don't have a precompiled ZOTLIB you'll need its source. Perhaps you can buy it from wherever you got this code.
If you have the source, add that info to the question, and it becomes a simple matter of how to run the compiler.
If you can't find the ZOTLIB source, how to move forward? I would simply comment out the
library ZOTLIB/use ZOTLIB.*
statements and compile the file anyway.If you're lucky, it will simply compile. Often proprietary code treats these clauses as boilerplate, including them whether they are used or not. In such cases they can safely be eliminated. If the compile succeeds, you didn't need them. VHDL in this respect is much safer than languages like C where implicit declarations are assumed (possibly wrongly) if something goes wrong in the #includes.
However, you may see compilation errors of the form
entity ZOTLIB.ZOTLIB_Components.DFF not found at line xxy
If you're lucky, there will only be a few, or they all reference the same few components. Now you need to replace the missing units. This requires knowledge (occasionally encrypted in the form of "documentation") as to what the missing units do.
In the case of
entity ZOTLIB.ZOTLIB_Components.DFF
it's reasonably likely that the component is a D-type flipflop, which you can borrow from somebody elses library or replace with a few lines of VHDL.In the case of
entity ZOTLIB.ZOTLIB_Components.FFT
orentity ZOTLIB.ZOTLIB_Components.80186
you are probably out of luck, as not only do you need to write an FFT processor or Intel-compatible CPU, but it must be an exact match for the way ZOTLIB implemented it. At that point, this VHDL file is beyond rescue, you're better starting from scratch.