Concurrent Statement on a case VHDL - vhdl

Hi all i'm trying to synthesize a VHDL code using alliance tool. But im having an illegal concurrent statement error. I'm new in VHDL and i'm trying to understand the concurrent and sequential statements, So i dont really understand why i'm getting a illegal concurrent statement inside a the case. Could you please help me on this error.
Here is a piece of the code, but is basically the same:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity reg_P is
port (
A : in unsigned(7 downto 0);
CLK : in std_logic;
EstPresente : in unsigned(7 downto 0);
P : out unsigned(7 downto 0);
RI : in unsigned(7 downto 0);
RPS : in std_logic
);
end reg_P;
architecture FromVerilog of reg_P is
signal P_Reg : unsigned(7 downto 0);
begin
P <= P_Reg;
process (CLK)
begin
if (rising_edge(CLK)) then
if ((not RPS) = '1') then
P_Reg <= X"00";
else
case EstPresente is
when X"02" then
case RI is
when X"16" then
P_Reg <= A;
when X"36" then
P_Reg <= (P_Reg - X"01");
when X"26" then
P_Reg <= (P_Reg - X"01");
when others then
P_Reg <= P_Reg;
end case;
when others then
P_Reg <= P_Reg;
end case;
end if;
end if;
end process;
end architecture;

The thens in your case statement choices should be the compound delimiter =>.
Replace those 6 instances and your code analyzes.
case EstePresente is
when X"02" =>
case RI is
when X"16" =>
P_Reg <= A;
when X"36" =>
P_Reg <= (P_Reg - X"01");
when X"26" =>
P_Reg <= (P_Reg - X"01");
when others =>
P_Reg <= P_Reg;
end case;
when others =>
P_Reg <= P_Reg;
end case;
ghdl -a reg_p.vhdl
reg_p.vhdl:26:19: '=>' is expected instead of 'then'
ghdl: compilation error
From a historical perspective synthesis was so costly you were expected to validate your models through simulation before synthesis.
Simulation tools tend to have better error reporting.

Related

VHDL generic case statement

I am trying to instantiate a mux with a generic number of case statements. Currently my code looks like this:
In these examples data_array and selector are inputs, data is the output and the width of the mux is 4.
process(all)
begin
case? selector is
when "1---" => data <= data_array(3);
when "01--" => data <= data_array(2);
when "001-" => data <= data_array(1);
when "0001" => data <= data_array(0);
when others => data <= (others => '-');
end case?;
end process;
Is there a way to have a generic number of case statements? Or is there a similar feature that I could use?
I could solve this using code generation to generate the appropriate number of case statements but I was wondering if there is a VHDL(-2008) feature that I could use to solve this.
I have rewritten the mux to use a for loop but unfortunately my implementation tool is not handling this very well. The logic that is inferred is not optimal and quite bad in terms of timing.
In this example GENERIC_WIDTH is the width of the mux.
process(all)
begin
data_v := (others => '0');
for i in 0 to GENERIC_WIDTH-1 loop
if selector(i) then
data <= data_array(i);
end if;
end loop;
end process;
I am targeting a Xilinx device using Vivado 2017.3. Implementation results show that using the case statement yields more efficient logic (in terms of WNS and logic depth) than using the for loop.
It doesn't matter anymore: modern synthesis tools will correctly optimize all logic. I made a comparison between Vivado 2017.3 outputs. The base entity is
library ieee;
use ieee.std_logic_1164.all;
entity MyMux is
generic(
data_width : positive := 32;
data_depth : positive := 4
);
port(
clk : in std_logic;
data_in : in std_logic_vector(data_width-1 downto 0);
selector : in std_logic_vector(data_depth-1 downto 0);
data_out : out std_logic_vector(data_width-1 downto 0)
);
end entity;
Architecture 1:
architecture rtl of MyMux is
subtype data_type is std_logic_vector(data_width-1 downto 0);
type data_array_type is array (0 to data_depth-1) of data_type;
signal data_array : data_array_type := (others => (others => '0'));
begin
read_data : process(clk) begin
if rising_edge(clk) then
for i in data_depth-1 downto 1 loop
data_array(i) <= data_array(i-1);
end loop;
data_array(0) <= data_in;
end if;
end process;
select_output: process(all) begin
case? selector is
when "1---" => data_out <= data_array(3);
when "01--" => data_out <= data_array(2);
when "001-" => data_out <= data_array(1);
when "0001" => data_out <= data_array(0);
when others => data_out <= (others => '-');
end case?;
end process;
end architecture;
Architecture 2:
architecture rtl of MyMux is
subtype data_type is std_logic_vector(data_width-1 downto 0);
type data_array_type is array (0 to data_depth-1) of data_type;
signal data_array : data_array_type := (others => (others => '0'));
begin
read_data : process(clk) begin
if rising_edge(clk) then
for i in data_depth-1 downto 1 loop
data_array(i) <= data_array(i-1);
end loop;
data_array(0) <= data_in;
end if;
end process;
select_output: process(all) begin
data_out <= (others => '-');
for i in 0 to data_depth-1 loop
if selector(i) then
data_out <= data_array(i);
end if;
end loop;
end process;
end architecture;
Architecture 3:
architecture rtl of MyMux is
subtype data_type is std_logic_vector(data_width-1 downto 0);
type data_array_type is array (0 to data_depth-1) of data_type;
signal data_array : data_array_type := (others => (others => '0'));
function my_mux(
selector : std_logic_vector(data_depth-1 downto 0);
data_array : data_array_type) return data_type is
variable data : data_type;
begin
data := (others => '-');
for i in 0 to data_depth-1 loop
if selector(i)='1' then
data := data_array(i);
end if;
end loop;
return data;
end function;
begin
read_data : process(clk) begin
if rising_edge(clk) then
for i in data_depth-1 downto 1 loop
data_array(i) <= data_array(i-1);
end loop;
data_array(0) <= data_in;
end if;
end process;
data_out <= my_mux(selector, data_array);
end architecture;
Output:
Architecture 1: 32 LUT3, 32 LUT6, 128 FDRE
Architecture 2: 32 LUT3, 32 LUT5, 128 FDRE
Architecture 3: 32 LUT3, 32 LUT5, 128 FDRE
So they are all practically the same.
The problem is you case seems to be the non deterministic component: initial placement randomization. In my experience this initial placement is based on some randomizer seed extracted from the hash of the code. The same code will always give the same implementation. But make a very small change in the code, and timing and resource use might be completely different.
You should take note that the logic you describe in you code will implement as a chain of multiplexers. When the GENERIC_WIDTH increases, so will the delay. This is inevitable.

Error: /..integrator.vhd(47): near "process": (vcom-1576) expecting IF VHDL

I'm trying to add two registers storing signed bits one of 3-bit[FRQ(2 downto 0)] and other is 7-bit[PHS(6 downto 0)]...and has to store the addition of these two registers in 7-bit register [PHS(6 downto 0)]. Thanks in advance for your helpful gesture.
the error I get is..>>>
Error: /..integrator.vhd(47): near "process": (vcom-1576) expecting IF VHDL
here is my code:
library IEEE;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--use ieee.std_logic_unsigned.all;
entity integ is
port (
SMP_CLK : in std_logic;
RESET : in std_logic;
PHS : out signed (6 downto 0);
FRQ : in signed (2 downto 0)
);
end integ;
architecture behaviour of integ is
signal sig_FRQ : signed(2 downto 0) := (others => '0');
signal ext_FRQ : signed(6 downto 0) := (others => '0');
signal sig_PHS : signed(6 downto 0) := (others => '0');
signal temp_PHS : signed(6 downto 0) := (others => '0');
begin
sig_FRQ <=FRQ;
temp_PHS <= sig_PHS;
--PHS <=signal_PHS;
process (SMP_CLK, RESET)
begin
if sig_FRQ(2)='1' then
ext_FRQ(6 downto 3) <= b"0000";
else
ext_FRQ(6 downto 3) <= b"1111";
--end if;
if RESET='1' then
sig_PHS <= b"0000000";
elsif (rising_edge(SMP_CLK) ) then
-- temp_PHS <= sig_PHS;
sig_PHS <= signed(ext_FRQ) + signed(temp_PHS);
end process;
sig_PHS => PHS;
end behaviour;
You have some mess with if-elsif-else statement. After the line with ext_FRQ(6 downto 3) <= b"1111"; you have commented --end if; if you want to continue if-elsif-else statement next condition should start with elsif word rather than simple if as in your code.
And you need to close the if-elsif-else construction in the end.
As well as you need to add to sensitivity list sig_FRQ signal because you use it in comparison, if you don't add it to sensitivity list the following construction
if sig_FRQ(2)='1' then
ext_FRQ(6 downto 3) <= b"0000";
else
ext_FRQ(6 downto 3) <= b"1111";
end if;
will work wrong.
In your case I suppose right version of the if-elsif-else constructions looks like:
process (sig_FRQ)
begin
if sig_FRQ(2)='1' then
ext_FRQ(6 downto 3) <= b"0000";
else
ext_FRQ(6 downto 3) <= b"1111";
end if;
end process;
process (SMP_CLK, RESET)
if RESET='1' then
sig_PHS <= b"0000000";
elsif (rising_edge(SMP_CLK)) then
--temp_PHS <= sig_PHS;
sig_PHS <= ext_FRQ + temp_PHS;
end if;
end process;
In the end, if you would like to assign result to output, you need to use another operator
PHS <= sig_PHS;.

VHDL sequential conditional signal assignment statement error

In my VHDL code I have an error in sig_out_real <= X"00" & sig_in when sig_in(7)='0' else X"ff" & sig_in;.
I don't think it is a syntax error. But Quartus shows an error at that point.
I don`t understand why it's an error.
Can anyone provide information:
-- Error--
Error (10500): VHDL syntax error at S8BT16B.vhd(35) near text "when"; expecting ";"
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_arith.all;
use work.fft_package.all;
entity S8BT16B is
port(
clk_50 : in std_logic;
clk_baud : in std_logic;
main_reset : in std_logic;
enable : in std_logic;
sig_in : in signed (7 downto 0);
sig_out : out complex;
valid_output : out std_logic
);
end S8BT16B;
architecture Behavioral of S8BT16B is
type state is (idle,start);
signal state_reg, next_state_reg : state;
signal sig_out_real : signed(15 downto 0);
begin
state_change : process(clk_50, main_reset)
begin
if (main_reset = '1' or enable = '0') then
state_reg <= idle;
elsif (main_reset ='0' and enable = '1') then
state_reg <= next_state_reg;
end if;
end process;
S8BT16B_active : process(clk_baud, state_reg)
begin
if (state_reg = idle) then
sig_out_real <="0000000000000000";
sig_out <=(sig_out_real,"0000000000000000");
next_state_reg <= start;
valid_output <= '0';
elsif (state_reg = start and enable = '1') then
sig_out_real <= X"00" & sig_in when sig_in(7)='0' else X"ff" & sig_in;
sig_out <= (signed_converted_input, "0000000000000000");
next_state_reg <= idle;
valid_output <= '1';
end if;
end process;
end Behavioral;
You code does not present a Minimal, Complete, and Verifiable example.
The package fft_package presumably containing the type declaration for complex is not present.
The declaration for signed_converted_input is also not present.
A sequential conditional signal assignment statement is only available in VHDL-2008.
There's a good argument to be made that the Synopsys packages std_logic_arith and std_logic_signed are not compatible with IEEE Std 1076-2008's defined package std_logic_1164. It's possible they've been re-written to accomidate the new definitions of std_logic_vector and std_ulogic vector, although not if they work without -2008 compatibility, without some serious automagic on the part of ALDEC.
If passing a -2008 compatibility flag doesn't fix things for you the simplest thing you can do is replace the sequential conditional signal assignment statement with two simple signal assignment statements inside an if statement:
library ieee;
use ieee.std_logic_1164.all;
-- use ieee.numeric_std.all;
use ieee.std_logic_arith.all;
package fft_package is
type complex is record
sig_real: signed (15 downto 0);
sig_imaginary: signed (15 downto 0);
end record;
constant signed_converted_input: signed (15 downto 0) := (others => '0');
end package;
library ieee;
use ieee.std_logic_1164.all;
-- use ieee.numeric_std.all;
use ieee.std_logic_arith.all;
use work.fft_package.all;
entity S8BT16B is
port(
clk_50: in std_logic;
clk_baud: in std_logic;
main_reset: in std_logic;
enable: in std_logic;
sig_in: in signed (7 downto 0);
sig_out: out complex;
valid_output: out std_logic
);
end S8BT16B;
architecture Behavioral of S8BT16B is
type state is (idle,start);
signal state_reg, next_state_reg: state;
signal sig_out_real: signed(15 downto 0);
begin
state_change:
process(clk_50, main_reset)
begin
if (main_reset = '1' or enable = '0') then
state_reg <= idle;
elsif (main_reset ='0' and enable = '1') then
state_reg <= next_state_reg;
end if;
end process;
S8BT16B_active:
process(clk_baud, state_reg)
begin
if state_reg = idle then
sig_out_real <= "0000000000000000";
sig_out <=(sig_out_real,"0000000000000000");
next_state_reg <= start;
valid_output <= '0';
elsif state_reg = start and enable = '1' then
-- sig_out_real <= X"00" & sig_in when sig_in(7)='0' else
-- X"ff" & sig_in;
if sig_in(7) = '0' then
sig_out_real <= X"00" & sig_in;
else
sig_out_real <= X"ff" & sig_in;
end if;
sig_out <= (signed_converted_input, "0000000000000000");
next_state_reg <= idle;
valid_output <= '1';
end if;
end process;
end Behavioral;
This code analyzes, elaborates and simulates (to show there are no length mismatches without regards to sig_in(7) = '0') while any claim to it's functionality is not made. The length looks right in the assignments to sig_out_real.
And of course without seeing the actual contents of your package fft_package claims to syntax and semantic validity can't be absolutely made (the faux package and your modified code are consistent with each other).

How to add std_logic to an integer value

I am trying to run two 7 segments here, I have searched everywhere but could not find a satisfactory reply, how can I add 1 to a std_logic ? I tried the logic_arith library as well but nothing works. I read somewhere that i gotta use a (0 to 0) vector but umm i didn't really get that part. Here is my code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use ieee.std_logic_arith.all;
entity blah is
Port ( clk : in STD_LOGIC;
anode: out STD_LOGIC_VECTOR (3 downto 0);
segment: out STD_LOGIC_VECTOR (6 downto 0));
end blah;
architecture Behavioral of blah is
signal sel: STD_LOGIC;
signal r_anode: STD_LOGIC_VECTOR (3 downto 0);
begin
anode <= r_anode;
process (clk) begin
if (clk'event and clk = '1') then
sel <= sel+1;
end if;
end process;
process (sel) begin
case sel is
when '0' => r_anode <= "1110";
when '1' => r_anode <= "1101";
when others => r_anode <= "1111";
end case;
case r_anode is
when "1110" => segment <= "0100100";
when "1101" => segment <= "0010010";
when others => segment <= "1111111";
end case;
end process;
end;
And the error
ERROR:HDLParsers:808 - "E:/Xilinx Projects/blah/blah.vhd" Line 19. + can not have such operands in this context.
The sel is only a single bit, so adding 1 is like a not sel.
However, if sel is more bits in a std_logic_vector, you can add a
natural to std_logic_vector as unsigned with:
sel <= std_logic_vector(unsigned(sel) + 1);
Use only ieee.numeric_std, thus remove the ieee.std_logic_arith, since
std_logic_arith is not a standard library (Synopsys proprietary).

VHDL code does not synthesize

I have written 2 state machines in my VHDL code. The simulation works fine, but the code does not synthesize. Any help would be appreciated. Here is my code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_arith.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
use IEEE.NUMERIC_STD.ALL;
entity pulse_width is
Port ( clk : in STD_LOGIC;
timer2:in std_logic;
input: in STD_LOGIC;
result: inout STD_LOGIC_VECTOR (15 downto 0);
SEL_LINE: IN STD_LOGIC_VECTOR(5 DOWNTO 0);
data_out: out STD_LOGIC_VECTOR (23 downto 0):=x"000000");
end pulse_width;
architecture Behavioral of pulse_width is
TYPE count_states is (s0,s0_dash,s1,s2,s3,s1_dash);
SIGNAL current_state, next_state : count_states := s0 ;
TYPE write_states is (ws0,ws0_dash,ws1,ws2,ws3,ws4);
SIGNAL current_state1, next_state1 : write_states := ws0 ;
TYPE index_array is ARRAY(integer range 0 to 65535) of std_logic_vector(15 downto 0);
SIGNAL mem: index_array;
SIGNAL count: std_logic_vector(15 downto 0):=x"0000";
SHARED VARIABLE j: integer:=0;
SHARED VARIABLE a,i: integer:=1;
SIGNAL flag,push_data,push_first,push_final,push_pulses,rw_first,rw_end: std_logic:='0';
SIGNAL y_clk_input ,y_clk_timer2, enable_count: std_logic:='0';
SIGNAL first,final: std_logic_vector(15 downto 0):= x"0001";
begin
-- Pulse width count
process (clk)
begin
if rising_edge(clk) then
current_state<=next_state;
current_state1<=next_state1;
end if;
end process;
process(input,SEL_LINE,current_state)
begin
------------------------------------------------------------------------
case current_state is
when s0 =>
if(input='1') then
next_state<=s1;
else
next_state<=s0;
end if;
when s1 =>
flag<='0';
if input='1' then
count <= count+ x"0001";
next_state<=s1_dash;
else
next_state<=s2;
end if;
when s1_dash =>
if input='1' then
count <= count+ x"0001";
next_state<=s1;
else
next_state<=s2;
end if;
when s2 =>
result <= count;
next_state<=s3;
when s3=>
count <= x"0000";
next_state<=s0;
enable_count<='0';
when others =>
next_state<=s0;
end case;
--------------------------------------------------------------------------
case current_state1 is
when ws0 =>
if (result>x"0000") then
next_state1<=ws1;
else
next_state1<=ws0_dash;
end if;
when ws0_dash =>
if (result>x"0000") then
next_state1<=ws1;
else
next_state1<=ws0;
end if;
when ws1=>
if rw_first='1' and rw_end='1' then
next_state1<=ws0;
else
mem(a) <= result;
a:=a+1;
final<=final+x"0001";
next_state1<=ws2;
end if;
when ws2 =>
next_state1<=ws0;
result<=x"0000";
when others =>
next_state1<=ws0;
end case;
end process;
I eventually need to implement three state machines.
The math you're trying to do in the asynchronous state logic is not registered and won't synthesize well. You need to re-arrange your state logic so statements like:
count <= count+ x"0001";
...
final<=final+x"0001";
...are synchronous and not 'free running' in an asynchronous loop.
The problem is that you read and write the same signals in one combinational process.
Either put everything in one clocked (synchronous) process
Or: use explicit registers: count_next <= count + x"0001";
Not related to your error, but still worth paying attention to:
You have a ton of unused signals and shared variables:
push_data,push_first,push_final,push_pulses, y_clk_input ,y_clk_timer2, first, i,j
This is confusing for anybody trying to read your code. 1
The packages STD_LOGIC_arith and STD_LOGIC_unsigned are deprecated

Resources