Error (10500): VHDL syntax error------expecting "(", or an identifier ("others" is a reserved keyword), or unary operator - vhdl

Can anyone see what is wrong with my code?
I copied the code from my textbook, but there are some errors which is not contained in my book.
This are the errors:
library IEEE;
use IEEE.std_logic_1164.all;
entity Moore_State is
port(
CLK: in STD_LOGIC;
S: in STD_LOGIC;
FB: in STD_LOGIC;
BACK_OUT: out STD_LOGIC;
FORWARD_OUT: out STD_LOGIC
);
end Moore_State;
architecture Moore1_arch of Moore_State is
type StateType is (idle,ready,back,forward);
signal state:StateType;
begin
Process(CLK)
begin
if(CLK'event and CLK='1') then
case state is
when idle=>
if S='1' then state<=ready;
else state<=idle;
end if;
when ready=>
if FB='0' then state<=back;
else state<=forward;
end if;
when back=>
if S='1' then state<=idle;
else state<=back;
end if;
when forward=>
if S='1' then state<=idle;
else state<=forward;
end if;
end case;
end if;
end Process;
with state select
BACK_OUT <='1' when back,
'0' when others;
FORWARD_OUT <='1' when forward,
'0' when others;
end Moore1_arch;
and the error messages appear in the last paragraph:
1.Error (10500): VHDL syntax error at VHDL1.vhd(48) near text ","; expecting ";"
2.Error (10500): VHDL syntax error at VHDL1.vhd(49) near text "others"; expecting "(", or an identifier ("others" is a reserved keyword), or unary operator

You forgot the with-select statement in the second part:
with state select
BACK_OUT <= '1' when back,
'0' when others;
with state select
FORWARD_OUT <= '1' when forward,
'0' when others;

Related

Making a single-input DeMultiplexer

I wrote a code to make a 3-1 multiplexer with 1 selector which works by selector pulses,and Here's the code i wrote below.
However, the the output assigns to the input and its chance ONLY During the if condition. How to make it always assigns to that value whenever it changes ?
library ieee;
use ieee.std_logic_1164.all;
entity selector is
port( ip,selec: in std_logic;
a,b,c: inout std_logic);
end selector;
architecture Behaviour of selector is
signal temp : std_logic;
begin
process(selec)
begin
if (selec'EVENT and selec ='1') then
if(a = ip) then
temp<= b;
elsif (b = ip) then
temp <= c;
else
temp <= a;
end if;
end if;
end process;
end if;
end Behaviour;
I'm using only ModelSim since i don't have access to hardware to test on :(
In your process you have only included selec in the sensitivity list. Therefore the assignment to temp only takes place upon event on selec.
This would be much better suited to a conditional assignment.
https://www.ics.uci.edu/~jmoorkan/vhdlref/cond_s_a.html
signal_name <= expression_1 when condition_1 else
expression_2 when condition_2 else
expression_3 ;

In VHDL, how to print current hierachy path for the current entity/architecture?

Here's what I can do in Verilog:
module xyz();
initial begin
$display("%m <= current module path");
end
endmodule
How to do this in VHDL? I heard that the 'INSTANCE_NAME attribute might be what i'm looking for... but how to use it to get the full path to the entity/architecture as a string?
-- Proc1'PATH_NAME = ":e:a:proc1[natural,integer]:"
-- Proc1'INSTANCE_NAME = ":e:a:proc1[natural,integer]:"
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
use std.env.stop;
entity test_stop is
port(
clk :in std_logic
);
end entity;
architecture sim of test_stop is
procedure print(s: in string) is
variable L :line;
begin
write(L, string'(s & LF));
writeline(output, L);
flush(output);
end procedure;
begin
process
begin
print(entity'INSTANCE_NAME & "<== need full hierarchy to this module here");
wait;
end process;
end architecture;

In VHDL, How to implement two tristate buffers driving the same pin with a PULLUP?

In VHDL, How to implement two tristates driving the same pin with a pullup? I tried to do the same thing in Verilog and it synthesizes without any problem:
`timescale 1ns/10ps
module driver(
input wire oe,
input wire di,
output tri1 do
);
assign do = oe ? di : 1'bz;
endmodule
`timescale 1ns/10ps
module top(
input wire oe1,
input wire di1,
input wire oe2,
input wire di2,
output tri1 do
);
driver driver1(
.oe (oe1),
.di (di1),
.do (do)
);
driver driver2(
.oe (oe2),
.di (di2),
.do (do)
);
endmodule
When I try to write this in VHDL, I get a little bit stuck because VHDL I'm not sure how to map Verilog's tri1 "pullup" into VHDL.
library ieee;
use ieee.std_logic_1164.all;
entity driver is
port(
oe :in std_logic;
di :in std_logic;
do :out std_logic
);
end entity;
architecture rtl of driver is
begin
do <= di when (oe = '1') else 'Z';
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity top is
port(
oe1 :in std_logic;
di1 :in std_logic;
oe2 :in std_logic;
di2 :in std_logic;
do :out std_logic
);
end entity;
architecture rtl of top is
begin
driver1: entity work.driver
port map(
oe => oe1,
di => di1,
do => do
);
driver2: entity work.driver
port map(
oe => oe2,
di => di2,
do => do
);
-- QUESTION: signal 'do' doesn't pull up to 'H'
---when oe1='0' and oe2='0'..
-- How to fix it in VHDL to do this so that pulls up
-- like 'tri1' signal in the Verilog version of this code.
end architecture;
I tried change the 'Z' in driver to 'H'... this cause synthesis to fail with a warning of multiple drivers to signal 'do'.
I tried add the line "do <= 'H';" to the top level architecture as suggested in another stackoverflow post on VHDL pullups. Also doesn't work, synthesis fails with a warning of multiple drivers to signal 'do'.
My question is: how to get the functionality of "tri1" pullup in VHDL code to pull up signal 'do' to 'H' when its not driven and both drivers have 'Z' output.
What about adding this line in the top architecture:
do <= 'Z' when (oe1 = '1') or (oe2 = '1') else 'H';
-- implementing a pullup...
-- this appears to synthesize in vivado without multiple driver error...
-------------------------------------
-- module: pullup
-------------------------------------
library ieee;
use ieee.std_logic_1164.all;
-- pullup
entity pullup is
port(
di: in std_logic;
dz: out std_logic
);
end entity;
architecture rtl of pullup is
begin
dz <= 'H' when (di = 'Z') else di;
end architecture;
-------------------------------------
-- module: driver
-------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity driver is
port(
oe :in std_logic;
di :in std_logic;
do :out std_logic
);
end entity;
architecture rtl of driver is
begin
process(oe, di)
begin
if (oe = '1') then
do <= di;
else
do <= 'Z';
end if;
end process;
end architecture;
-------------------------------------
-- module: top
-------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity top is
port(
oe1 :in std_logic;
di1 :in std_logic;
oe2 :in std_logic;
di2 :in std_logic;
do :out std_logic
);
end entity;
architecture rtl of top is
signal doz: std_logic;
begin
driver1: entity work.driver
port map(
oe => oe1,
di => di1,
do => doz
);
driver2: entity work.driver
port map(
oe => oe2,
di => di2,
do => doz
);
pullup: entity work.pullup
port map(
di => doz,
dz => do
);
--do <= 'H' when (doz = 'Z') else doz;
end architecture;

VHDL fsm error - near "when": (vcom-1576) expecting END

I am trying to make a fsm in vhdl using modelsim but when i try and compile my code i have this errors
** Error: C:/Users/manor/Desktop/ldh/mult_fsm.vhd(34): near "when": (vcom-1576) expecting END.
** Error: C:/Users/manor/Desktop/ldh/mult_fsm.vhd(60): near "when": (vcom-1576) expecting END.
** Error: C:/Users/manor/Desktop/ldh/mult_fsm.vhd(72): near "else": (vcom-1576) expecting END.
And this is my code
library ieee;
use ieee.std_logic_1164.all;
entity mult_fsm is
port(ck,adx,m: in std_logic;
adsh,sh,cm,mdone: out std_logic);
end entity mult_fsm;
architecture ideal of mult_fsm is
type StateType is (S0, S1, S2, S3, S4);
signal CurrentState, NextState: StateType;
begin
NS_CS: process( ck)
begin
if ck'event and ck='1' then
case CurrentState is
when S0=>
if (adx='0') then
NextState <= S0;
else
NextState <= S1;
end if;
when S1=>
NextState <= S2;
when S2=>
if (m='1') then
NextState<=S3;
else if (m='0') then
NextState<=S2;
end if;
when S3=>
NextState <= S4;
when S4=>
NextState <= S0;
end case;
end if;
end process NS_CS;
OL: process (CurrentState)
begin
case CurrentState is
when S0=>
if (adx = '0') then
adsh<='0';
sh<='0';
cm<='0';
mdone<='0';
else if (adx = '1') then
if (m='1') then
adsh<='1';
else if (m='0') then
sh<='1';
end if;
end if;
when S1=>
if (m='1') then
adsh<='1';
else if (m='0') then
sh<='1';
end if;
when S2=>
if (m='0') then
adsh<='0';
sh<='0';
cm<='0';
mdone<='0';
else if (m='1') then
adsh<='1';
end if;
when S3=>
if (m='0') then
sh='1';
else if (m='1') then
cm<='1';
adsh<='1';
end if;
when S4=>
mdone<='1';
end case;
end process OL;
end architecture ideal;
I tried fixing the code myself but i just can't figure out what is the problem with it.
Replace your else ifs with elsifs.
In VHDL, each if needs an end if. If you write
if ... then
...
else if ... then
you need two end ifs - one for each if:
if ... then
...
else IF ... THEN
...
END IF;
end if;
VHDL has an elsif statement. That does not start a new if statement, but instead is part of the if statement it follows. If you replace else IF in the above example, you only need one end if:
if ... then
...
elsif ... then
...
end if;
Looking at the following code:
if (m='1') then
NextState<=S3;
else if (m='0') then
NextState<=S2;
end if;
I think you meant elsif instead of else if. Alternatively, since m is an std_logic, you may be able to simplify this block down to:
if (m='1') then
NextState<=S3;
else
NextState<=S2;
end if;

change signal inside a process with if statement - VHDL

I have this code in VHDL. What I want is to rise rst when sw'event and afterwards, the rst is to fall by itself. But when I simulate this, rst never falls!
process(rst,clk,sw)
begin
if (clk'EVENT and clk='1') then
if (rst='1') then
rst<='0';
elsif (sw'event) then
rst<='1';
elsif (my_counter="11") then
deb_sw<=sw;
end if;
end if;
end process;
sw'event is very unlikely to be true at exactly the same time as clk'event is.
This is because signals are usually driven by another process which is also doing a clk'event, so the signal will be updated after the clk event.
If you want to detect when sw changes from '0' to '1' (or vice versa), you have to keep track of its previous value:
if sw /= last_sw then
-- do what you need to do when it changes
end if;
last_sw := sw;
finally i solved it like this
process(rst,clk,sw)
begin
if (clk'EVENT and clk='1') then
if (rst='1' and rst'last_value='0') then
rst<='0';
elsif (sw='1') then
rst<='1';
deb_sw<=sw;
elsif (my_counter="1010") then -- clock cycles=10*f
deb_sw<=sw;
end if;
end if;
end process;

Resources