can someone help me on how to change this vhdl code to using 'when' statement?
Here is the code that I have written:
library IEEE;
use IEEE.std_logic_1164.all;
entity sel2_1 is
port( A, B, SEL : in std_logic;
outsgnl : out std_logic);
end sel2_1;
architecture EX1 of sel2_1 is
begin
outsgnl <= (not SEL and A) or (SEL and B);
end EX1;
the simulation result is as follows:
simulation
When keyword is used in different VHDL assignments. Assuming SEL is only '0' or '1' you can simpley replace
outsgnl <= (not SEL and A) or (SEL and B);
by a selected signal assignment, often referred as with/select assignment
with SEL select outsgnl <=
A when '0',
B when others;
Alternatively you may use conditional signal assignment often referred as when/else
outsgnl <= A when SEL = '0' else B;
Related
i am using an inline compiler (https://www.edaplayground.com/) and im not understanding the online compilers error message. I am trying to build the boolean expression (a * !b) + (b * !c) + (!b * c).
My code is:
library IEEE;
use IEEE.std_logic_1164.all;
ENTITY (MySimp) IS
PORT (A: in STD_LOGIC;
B: in STD_LOGIC;
C: in STD_LOGIC;
Z: out STD_LOGIC;
);
End MySimp;
ARCHITECTURE (details) OF (MySimp) IS
BEGIN
PROCESS
VARIABLE D, E, F: STD_LOGIC;
BEGIN
IF A AND (NOT B)= '1' THEN D:= '1';
ELSE D:= '0';
END IF:
IF B AND (NOT C)= '1' THEN E:= '1';
ELSE E:= '0';
END IF:
IF C AND (NOT B)= '1' THEN F:= '1';
ELSE F:= '0';
END IF:
Z <= D OR E OR F;
END PROCESS;
END details;
As the error shows, you are compiling a VHDL file (.vhd) as a (System) Verilog file (.sv). Those are two different hardware description languages.
In the Languages and Libraries tab on the left, you need to set the Testbench + Design to VHDL.
But there's a problem in your code. The process statement doesn't have a sensitivity list. HDLs are usually parallel languages, which means you need to indicate when a process needs to be triggered: else it will try to loop indefinitely in an infinitesimal time. You either need to add a wait-statement, to stop the loop, or implicitly do that by adding the trigger signals to the process sensitivity list. e.g.
process (a,b,c)
There are more semantical issues with your code. I added them in comments
library ieee;
use ieee.std_logic_1164.all;
entity MySimp is -- no braces around the name
port (
a: in std_logic;
b: in std_logic;
c: in std_logic;
z: out std_logic -- no semicolon
);
end entity;
architecture arch of MySimp is
begin
process(a, b, c)
variable d, e, f: std_logic;
begin
if (a and (not b))= '1' then -- add braces around the logic expression
d:= '1';
else
d:= '0';
end if; -- semicolon instead of colon
-- alternative method 1
if b='1' and c='0' then
e:= '1';
else
e:= '0';
end if;
-- alternative method 2
f := c and (not b);
z <= d or e or f;
end process;
-- or replace the whole process by:
--z <= (a and (not b)) or (b xor c);
-- as (b and (not c)) or (c and (not b)) is an exclusive-or operation
end architecture;
Is there a data type in VHDL that is an array like a "std_logic_vector", but instead of having all having 9 possible states:
'U': uninitialized. This signal hasn't been set yet.
'X': unknown. Impossible to determine this value/result.
'0': logic 0
'1': logic 1
'Z': High Impedance
'W': Weak signal, can't tell if it should be 0 or 1.
'L': Weak signal that should probably go to 0
'H': Weak signal that should probably go to 1
'-': Don't care.
has only two possible states:
'0': logic 0
'1': logic 1
The reason why I ask this is because i'm looking for the VHDL equivalent of the verilog case statement. Verilog Example:
module m1(input a, input b, output reg[7:0] q);
wire [1:0] sel = {a, b};
always #* begin
case(sel)
2'b00: q = 8'd1;
2'b01: q = 8'd2;
2'b10: q = 8'd3;
2'b11: q = 8'd4;
endcase
end
endmodule
In VHDL, I can do this with no problems:
entity m1 is
port(
a :in std_logic;
b :in std_logic;
q :out std_logic_vector(7 downto 0)
);
end entity;
architecture rtl of m1 is
signal sel :std_logic_vector(1 downto 0);
begin
sel <= a & b;
process(sel)
begin
case sel is
when "00" => q <= 1;
when "01" => q <= 2;
when "10" => q <= 3;
when "11" => q <= 4;
end case;
end process;
end architecture;
The problem with this is that both Xilinx ISE and Modelsim refuse to compile this code saying that I didn't cover the states for 'X', 'U', 'L', 'H', etc...
so i need to add a "when others => q <= 'X';" statement to my VHDL....
Then, when I compile the code with Vivado, it says, "WARNING: you have a default case eventhough your full case was covered." so then I delete the "when others=>" clause of the case...
Well, this is just annoying... is there a way to get it to work in every tool without generating either an ERROR message or a bogus warning message?
My idea was to just use an array type that can be only "0" or "1" like an integer... but instead more like std_logic_vector without supporting all the other logic states that mess up the case select and require the "when others =>" clause....
possible? its there a VHDL data type like this already built in? an array of only '0' or '1' and nothing else specifically for catatentating together and being used as a case selection? integer types don't have 'U' or 'X', but are perfectly ok to use in a VHDL case... i'm wondering if the same holds for an array type of ('0', '1')?
You should stick with std_logic and std_logic_vector, an other post is presenting the differences: When to use STD_LOGIC over BIT in VHDL
I think your problem comes (also) from the fact that you are putting an integer into a std_logic_vector. You should use the conversion functions:
to_unsigned(arg: natural, size: natural) return unsigned
std_logic_vector(arg: signed or unsigned) return std_logic_vector
Which leads you to:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all; --DO NOT FORGET THIS LIBRARY TO USE THE CONVERSION FUNCTION
entity m1 is
port(
a :in std_logic;
b :in std_logic;
q :out std_logic_vector(7 downto 0)
);
end entity;
architecture rtl of m1 is
signal sel :std_logic_vector(1 downto 0);
begin
sel <= a & b;
process(sel)
begin
case sel is
when "00" => q <= std_logic_vector(to_unsigned(1,q'length));
when "01" => q <= std_logic_vector(to_unsigned(2,q'length));
when "10" => q <= std_logic_vector(to_unsigned(3,q'length));
when "11" => q <= std_logic_vector(to_unsigned(4,q'length));
when others => q <= std_logic_vector(to_unsigned(1,q'length));
end case;
end process;
end architecture;
Try VHDL Predefined Types from the package standard:
type bit is ('0', '1');
type bit_vector is array (natural range <>) of bit;
funciton to_stdlogicvector (b :bit_vector) return std_logic_vector;
function to_bitvector (s :std_ulogic_vector) return bit_vector;
architecture rtl of m1 is
signal sel :std_logic_vector(1 downto 0);
signal bv :bit_vector(1 downto 0);
begin
sel <= a & b;
bv <= to_bitvector(sel);
process(bv)
begin
case bv is
when "00" => q <= 1;
when "01" => q <= 2;
when "10" => q <= 3;
when "11" => q <= 4;
end case;
end process;
end architecture;
I'm trying to learn VHDL through P. Ashenden's book: Designer's Guide to VHDL. Chapter one's exercise 10 asks you to write 2-to-1 (I'm assuming 1 bit wide) MUX in VHDL and simulate it. I apologize in advance for being a complete noob. This is my first VHDL code.
My MUX didn't produce any errors or warnings in synthesis. My test bench doesn't produce errors or warnings, either. However, the simulation comes up completely blank, except for the names of the signals.
I've tried looking at a multitude of other MUX examples online (as well as a bench test example from the book), all of which gave errors when I tried sythesizing them, so I wasn't confident enough to use them as guides and didn't get much out of them. I'm not sure what I'm doing wrong here. I'd include an image of the simulation, but I don't have enough rep points :(
Also, I realize that a good MUX should also have cases for when it receives no select input/high impedance values, ect.. In this case, I'm just trying to get the toy model working.
The MUX code is:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity MUXtop is
Port (a, b, sel: in bit;
z: out bit);
end MUXtop;
architecture behav of MUXtop is
begin
choose: process is
begin
if sel = '0' then
z <= b;
else
z <= a;
end if;
end process choose;
end architecture behav;
The test bench code is:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY MUXtest IS
END MUXtest;
ARCHITECTURE behavior OF MUXtest IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT MUXtop
PORT(
a : IN bit;
b : IN bit;
sel : IN bit;
z : OUT bit
);
END COMPONENT MUXtop;
--Inputs
signal a : bit := '0';
signal b : bit := '0';
signal sel : bit := '0';
--Outputs
signal z : bit;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: MUXtop PORT MAP (
a => a,
b => b,
sel => sel,
z => z
);
-- Stimulus process
stimulus: process
begin
wait for 10 ns;
a <= '1';
wait for 10 ns;
sel <= '1';
wait for 10 ns;
b <= '1';
wait;
end process stimulus;
END architecture behavior;
You don't need a use clause for package std_logic_1164 when using type bit (declared in package standard).
Your process statement choose in MUXtop has no sensitivity clause which cause the process to continually execute in simulation. (It won't do anything until you trip over a delta cycle iteration limit which might be set to infinity).
I added a sensitivity list, commented out the superfluous use clauses in the two design units and added some more stimulus steps as well as a final wait for 10 ns; to allow the last action to be seen in your testbench:
library IEEE;
-- use IEEE.STD_LOGIC_1164.ALL;
entity MUXtop is
Port (a, b, sel: in bit;
z: out bit);
end MUXtop;
architecture behav of MUXtop is
begin
choose: process (a, b, sel) -- is
begin
if sel = '0' then
z <= b;
else
z <= a;
end if;
end process choose;
end architecture behav;
LIBRARY ieee;
-- USE ieee.std_logic_1164.ALL;
ENTITY MUXtest IS
END MUXtest;
ARCHITECTURE behavior OF MUXtest IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT MUXtop
PORT(
a : IN bit;
b : IN bit;
sel : IN bit;
z : OUT bit
);
END COMPONENT MUXtop;
--Inputs
signal a : bit := '0';
signal b : bit := '0';
signal sel : bit := '0';
--Outputs
signal z : bit;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: MUXtop PORT MAP (
a => a,
b => b,
sel => sel,
z => z
);
-- Stimulus process
stimulus: process
begin
wait for 10 ns;
a <= '1';
wait for 10 ns;
sel <= '1';
wait for 10 ns;
sel <= '0'; -- added
wait for 10 ns; -- added
b <= '1';
wait for 10 ns; -- added
wait;
end process stimulus;
END architecture behavior;
And that gives:
(clickable)
I have to make a 4bit magnitude comparator in VHDL with only concurrent statements (no if/else or case/when).
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Exercise is
port ( A : in std_logic_vector (3 downto 0);
B : in std_logic_vector (3 downto 0);
Ag : out std_logic;
Bg : out std_logic;
AeqB: out std_logic
);
end Exercise;
architecture Comparator of Exercise is
begin
Ag <= '1'when (A>B) else '0';
Bg <= '1' when (B>A) else '0'; --Problem: Here if i sumulate B="ZZZZ", Bg is 1, asi if B>A
AeqB<= '1' when (A=B) else '0';
end Comparator;
The problem is that i need to take in count all the other values of std_logic (U,X,Z,W,L,H,-), i know there is the others but cant figure it out how to make the comparator with with/select statement.
Thanks
In general you can 'convert' the various values that std_logic can take into either 0 or 1 using the to_01 function. I think it's in package numeric_std.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity comp_4 is
port ( A:IN STD_LOGIC_VECTOR(0 to 3);
B:IN STD_LOGIC_VECTOR(0 to 3);
ET:OUT STD_LOGIC;
GT:OUT STD_LOGIC;
LT:OUT STD_LOGIC);
end comp_4;
architecture dataflow of comp_4 is
begin
with A-B(0 to 3) select
ET <= '1' when "0000",
'0' when others;
with A > B select
GT <= '1' when true,
'0' when others;
with A < B select
LT <= '1' when true,
'0' when others;
end dataflow;
Suppose one has an entity which has two architectures defined. Those two architectures work with the same entity (obviously) and subsequently the two set the output pins to different values. My question is, how does the program (simulator) determine what the output should be (i.e. which architecture to choose)?
Here is an example:
library ieee;
use ieee.std_logic_1164.all;
entity Exercise_4 is
generic (n : integer := 4);
port(
a, b : std_logic_vector (n-1 downto 0);
clk, rst : std_logic;
q, qn : buffer std_logic_vector (n-1 downto 0));
end;
architecture one of Exercise_4 is
begin
process (clk, rst)
begin
if rst = '0' then
q <= (others=>'0');
elsif (clk' event and clk = '0') then
q <= a ;
end if;
end process;
process (clk, rst)
begin
if rst = '0' then
qn <= (others=>'1');
elsif (clk' event and clk = '0') then
for i in a'range loop
qn(i) <= not q(i) ;
end loop;
end if;
end process;
end;
architecture two of Exercise_4 is
begin
process (clk,rst)
begin
if rst = '0' then
q <= (others=>'0');
qn <= (others=>'0');
elsif (clk' event and clk = '0') then
q <= a;
qn <= b ;
end if;
end process;
end;
I did a simulation and saw that q gets the value of a assigned and qn gets the value of b assigned. It seems that the second architecture has been chosen by the compiler I don't understand why the program decided to do so.
Thank you.
If you don't specify yourself which architecture to choose² then the compiler will take "the most recently analyzed architecture body associated with the entity declaration" (assuming the compiler is compliant to the IEEE standard) [1].
² You can select the architecture you prefer e.g. in the component declaration section (where you map the signals) on a higher design level:
entity topentity is
end;
architecture toparch of topentity is
-- component instantiation
component Exercise_4 is
generic (n : integer := 4);
port(
a, b : std_logic_vector (n-1 downto 0);
clk, rst : std_logic;
q, qn : buffer std_logic_vector (n-1 downto 0));
end component Exercise_4;
begin
-- component mapping
E4: entity work.Exercise_4(one)
generic map ( .. )
port( .. );
end architecture toparch;
[1] IEEE Std 1076-2008 7.3.3 Default binding indication, paragraph 4.
Disclaimer: Answer was constructed with the help of the comments above. No copyright infringement intended. ;P
In absence of configuration binding, by default the compiler consider the last architecture body in the code file.