VHDL mux implementation? - vhdl

Is it possible to implement a mux with multiple control signals? For example, I want to do something like this:
with (sig1 & sig2) select
output <= A when "00",
B when "01",
C when "10",
D when "11",
'0' when others;
I know I could just assign them to a new signal and use that, but that's something I want to avoid if possible.

You need to enable VHDL2008 mode on your compiler to have it work.
An alternative (also 2008):
muxing: process (sig1, sig2) is
begin -- process muxing
case sig1 & sig2 is
when "00" => output <= '1';
when "01" => output <= '0';
when "10" => output <= '0';
when "11" => output <= '1';
when others => output <= '0';
end case;
end process muxing;
If you have no VHDL-2008 mode on your compiler it will fail with complaints of
Array type case expression must be of a locally static subtype.
or similar.
If your compiler can't be made to be VHDL-2008 compliant, you have to work around this by creating a type that you can use to surround the sig1 & sig2 to explicitly tell the compiler what's going on:
subtype twobits is bit_vector(0 to 1);
Then:
with twobits'(sig1 & sig2) select
output <= '1' when "00",
-- etc.
or:
case twobits'(sig1 & sig2) is
when "00" => -- etc.

See this, maybe it helps you
entity MUX is
port ( a, i0, i1 : in bit;
o : out bit );
end MUX;
architecture behave of MUX is
begin
process ( a, i0, i1 ) begin
if a = '1' then
o <= i1;
else
o <= i0;
end if;
end process;
end behave;

Related

Why am I getting errors in lines 56-61?

I am trying to set up a problem for state machines in lab and I keep receiving errors when trying to compile in Quartus
I have tried using commas, else statements and nothing seems to work
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.All;
ENTITY SM_VHDL IS -- Do not modify this entity statement!
PORT(X : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
RESETN,
CLOCK : IN STD_LOGIC;
Z : OUT STD_LOGIC;
Q : OUT STD_LOGIC_VECTOR(1 DOWNTO 0) );
END SM_VHDL; -- Do not modify this entity statement!
ARCHITECTURE behavior of SM_VHDL IS
TYPE STATE_TYPE IS (A, B, C);
SIGNAL state : STATE_TYPE;
BEGIN
PROCESS(CLOCK, RESETN)
BEGIN
IF RESETN = '0' THEN
state <= A;
ELSIF CLOCK'EVENT AND CLOCK = '1' THEN
CASE state IS
WHEN A =>
CASE X IS
WHEN "00" =>
state <= B;
WHEN "11" =>
state <= C;
WHEN OTHERS =>
state <= A;
END CASE;
WHEN B =>
CASE X IS
WHEN "10" =>
state <= A;
WHEN "11" =>
state <= C;
WHEN OTHERS =>
state <= B;
END CASE;
WHEN C =>
CASE X IS
WHEN "00" =>
state <= B;
WHEN "01" =>
state <= A;
WHEN OTHERS =>
state <= C;
END CASE;
END CASE;
END IF;
END PROCESS;
Z <= '1' WHEN C;
'0' WHEN A;
'0' WHEN B;
Q <= "00" WHEN A;
"01" WHEN B;
"10" WHEN C;
"11" WHEN "-";
END behavior;
I need it to compile
WHEN can only be used with boolean conditions. A/B/C are all literals of STATE_TYPE. You need to create a boolean result by creating a comparison on the state signal:
Z <= '1' when STATE = C
else '0' when STATE = A -- This state not actually needed as a single ELSE would cover it
else '0';
Ill let you work out the statement for Q
The syntax for assigning to Z and Q is wrong for multiple issues:
Missing WITH state SELECT ... before assign
Uses ";" between when parts, use , instead
Cant use "-" (don't care) after last when, use OTHERS instead
So updated code:
WITH state SELECT Z <=
'1' WHEN C,
'0' WHEN A,
'0' WHEN B;
WITH state SELECT Q <=
"00" WHEN A,
"01" WHEN B,
"10" WHEN C,
"11" WHEN OTHERS;
Btw. consider using ModelSim Starter Edition as compiler/simulator before moving to Quartus, since the compile time is faster and messages often better.

Issue with Synchronous Sequential Circuit using Flip Flop D

Right now i'm working on a project concerning the use of D Flip Flop on Falling Edge, with x and y being the inputs and z being the output.
The Circuit will only give z ='1' only if x and y are both 0 and also if they were both 0 in a previous clock cycle, and the transitions only occurring in the clock's falling edge.
Variables a and b will represent states Q0(a) and Q1(b).
The Mealy machine is of two states : Q0 and Q1, and the transations are as follow:
Q0
x y z
0 0 1
0 1 x
1 0 0 --> goes to next state (Q1)
1 1 x
Q1
x y z
0 0 0 --> goes to next state (Q0) only this time z='0'
0 1 x
1 0 x
1 1 0 --> stays in current state (Q1)
The problem is that when the transition from Q1 to Q0 happens, z is still '1' instead of '0'.
Is there any advice on how could i manage to get around that fast transition?
Here is the code so far:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Mealys is
Port (
inicio: in std_logic;
clk: in std_logic;
x: in std_logic;
y: in std_logic;
z: out std_logic;
a: out std_logic;
b: out std_logic
);
end Mealys;
architecture behavior of Mealys is
type nombres_estados is (Q0, Q1);
signal estado: nombres_estados;
signal entrada_aux: std_logic_vector (1 downto 0);
begin
entrada_aux <= x & y;
FF_D: process (clk)
begin
if (inicio = '1') then
estado <= Q0;
elsif falling_edge(clk) then
case estado is
when Q0 =>
case entrada_aux is
when "00" => estado<=Q0;
when "10" => estado<=Q1;
when others => estado<=Q0;
end case;
when Q1 =>
case entrada_aux is
when "00" => estado<=Q0;
when "11" => estado<=Q1;
when others => estado<=Q1;
end case;
when others => estado<=Q0;
end case;
end if;
end process;
next_decode: process(estado, entrada_aux)
begin
case (estado) is
when Q0 =>
a <= '1';
b <= '0';
if entrada_aux <= "00" then
z<='1';
elsif entrada_aux <= "10" then
z<='0';
end if;
when Q1 =>
a <= '0';
b <= '1';
if entrada_aux <= "00" then
z<='0';
elsif entrada_aux <= "11" then
z<='0';
end if;
end case;
end process;
end behavior;
And here is the state diagram
Thank you for you time.
I assume that you are learning VHDL, that you are starting with the VHDL subset for synthesis and that the final goal is to synthesize your design.
Your design comprises two processes: a synchronous one and a combinatorial one. Both are bogus for synthesis.
Your synchronous process does not correctly handle the reset. If your reset is asynchronous (that is, is taken into account immediately when asserted), it should be in the sensitivity list:
process(clk, inicio)
begin
if inicio = '1' then
<initialize things>
elsif falling_edge(clk) then
<do things>
end if;
end process;
And if it is synchronous (that is taken into account only on the clock falling edge), it should not be in the sensitivity list but the reset part of your process should be under the scope of the clock edge test:
process(clk)
begin
if falling_edge(clk) then
if inicio = '1' then
<initialize things>
else
<do things>
end if;
end if;
end process;
Your combinatorial process has 3 outputs: a, band z. They must all be assigned a value during any execution of the process. This is what combinatorial means: each time an input changes, the signals propagate and all outputs finally get a new value. The new value can be the same as the previous one but this must be by accident, not because the output has not been assigned. Else, it would mean to a synthesizer: "keep the previous value", which usually leads to the inference of latches to store the previous value... Not what you want in a true combinatorial process. In your process, when estado or entrada_aux change, a and b are assigned but not always z (I let you understand why).
There is another problem in this process: the equality test operator is =, not <= which is the less or equal test operator. Note that your code should not even compile as it is.
It is not easy to propose a fixed version of this process because your specification is not 100% clear. What do these x mean in the transition table? For instance, what happens to z if we are in state Q0 and xy is 01 or 11? If the answer is "z does not change", then its computation must involve a memory element and you must describe this in your synchronous process. Else, if it means "z takes any value" (we don't care), then you must decide yourself before coding and add this to your combinatorial process (for instance with an else statement).
I will assume that it means "z does not change". So, you need a memory element (a D-flip-flop) to store the previous value. Add another signal (previous_z) and assign it in your synchronous process:
signal previous_z: std_logic:
...
process(clk, inicio)
begin
if inicio = '1' then
previous_z <= '0';
<initialize other things>
elsif falling_edge(clk) then
previous_z <= z;
<do other things>
end if;
end process;
There is a potential problem here because we are reading the value of z which is an output port of your entity. In VHDL versions previous 2008 this was forbidden. If you are using a pre-2008 version of VHDL you must declare another internal signal (local_z) that you can read and assign, use it everywhere, and assign it to the output z, for instance in a concurrent signal assignment (outside any process):
signal previous_z: std_logic:
signal local_z: std_logic:
...
process(clk, inicio)
begin
if inicio = '1' then
previous_z <= '0';
<initialize other things>
elsif falling_edge(clk) then
previous_z <= local_z;
<do other things>
end if;
end process;
z <= local_z;
Now, you can use this previous_z signal in your combinatorial process to compute local_z (or z in VHDL 2008):
next_decode: process(estado, entrada_aux, previous_z)
begin
case estado is
when Q0 =>
a <= '1';
b <= '0';
if entrada_aux = "00" then
local_z <= '1';
elsif entrada_aux = "10" then
local_z <= '0';
else
local_z <= previous_z;
end if;
when Q1 =>
a <= '0';
b <= '1';
if entrada_aux = "00" then
local_z <= '0';
elsif entrada_aux = "11" then
local_z <= '0';
else
local_z <= previous_z;
end if;
end case;
end process;
Note that previous_z must be added to the sensitivity list. Do you see now how the local_z output of the process will always be assigned?
There is an even better option which consists in assigning a default value to each output, unconditionally, at the beginning of the process and change this if and only if needed:
next_decode: process(estado, entrada_aux, previous_z)
begin
a <= '0':
b <= '0';
local_z <= previous_z;
case estado is
when Q0 =>
a <= '1';
if entrada_aux = "00" then
local_z <= '1';
elsif entrada_aux = "10" then
local_z <= '0';
end if;
when Q1 =>
b <= '1';
if entrada_aux = "00" then
local_z <= '0';
elsif entrada_aux = "11" then
local_z <= '0';
end if;
end case;
end process;
This works because, in a combinatorial process, when a signal is assigned several times, it is the last assignment that wins. And this coding style has a good property: you cannot forget to assign an output.
There is another good option: concurrent signal assignments (outside any process):
a <= '1' when estado = Q0 else '0';
b <= '1' when estado = Q1 else '0';
local_z <= '1' when estado = Q0 and entrada_aux = "00" else
'0' when estado = Q0 and entrada_aux = "10" else
'0' when estado = Q1 and entrada_aux = "00" else
'0' when estado = Q1 and entrada_aux = "11" else
previous_z;
Concurrent signal assignments, when the logic is simple enough, are maybe even better than the two other options because there is no need to worry about sensitivity lists and always assigning the outputs. Probably very good points, at least for beginners.
One last remark: you use the std_logic resolved type without any good reason. This is unfortunate and error prone. You should use std_ulogic, its unresolved parent type instead (u for Unresolved). But this is out of scope your question.

VHDL nested case statement for some case options

I am new to VHDL and working with case statements, I have something like the following:
process(state)
begin
case state is
when stop =>
a <= input;
b <= output;
when move =>
a <= input_1;
b <= output_1;
end case;
end process;
where a,b,input, output,input_1 and output 1 are signals.
My issue is that I want to have a nested case in only one of the options:
for example:
process(state)
begin
case state is
when stop =>
a <= input;
b <= output;
when move =>
a <= if c='0' then input_1 else input_2;
b <= if c='0' then output_1 else output_2;
end case;
end process;
My question is can i do something like above where not all case options are nested but only some of them are or is there any other way in such situation , i tried using when else but got an error, saying that such syntax is not supported.
Any help is appreciated
I'm not quite sure what you're asking here:
can i do something like above where not all case options are nested but only some of them are or is there any other way in such situation
but is this what you are trying to do? (Note that I've added c to the sensitivity list):
process(state,c)
begin
case state is
when stop =>
a <= input;
b <= output;
when move =>
case c is
when '0' =>
a <= input_1;
b <= output_1;
when '1' =>
a <= input_2;
b <= output_2;
when others => null;
end case;
end process;
Your question is fraught with perils. Assigning an output to an internal signal can require an output port mode of inout or buffer or VHDL 2008 support which isn't universal for synthesis. Generally mode buffer isn't supported either.
To get to the heart of your question sequential signal assignments supporting when else are supported in VHDL 2008 but not generally in synthesis.
A case statement choice contains sequential statements.
You can use an if statement instead:
library ieee;
use ieee.std_logic_1164.all;
entity foo is
port (
signal input: in std_logic;
signal output: inout std_logic;
signal input_1: in std_logic;
signal input_2: in std_logic;
signal output_1: inout std_logic;
signal output_2: inout std_logic
);
end entity;
architecture fum of foo is
signal a, b: std_logic;
signal c: std_logic;
type some_state is (stop, move);
signal state: some_state;
begin
UNLABELED:
process(state)
begin
case state is
when stop =>
a <= input;
b <= output;
when move =>
if c = '0' then
a <= input_1;
b <= output_1;
else
a <= input_2;
b <= output_2;
end if;
end case;
end process;
end architecture;
Notice your two evaluations of c have been collapsed into one.
Besides the conditional signal assignment states that are supported as sequential statements in VHDL 2008, there's also selected signal assignment statements (likewise generally not supported by synthesis as sequential statements).
VHDL before 2008 does not have a ternary operator (C-like ? :) for sequential
statements, so you can't write if c='0' then input_1 else input_2, but in
VHDL-2008 you can write input_1 when c='0' else input_2.
However, the compact coding style can be achieved by making a small function:
function ternary(cond : boolean; res_true, res_false : std_logic) return std_logic is
begin
if cond then
return res_true;
else
return res_false;
end if;
end function;
Whereby the move part of the code can be written like:
when move =>
a <= ternary(c='0', input_1, input_2);
b <= ternary(c='0', output_1, output_2);
You can also make a nested case like:
when move =>
case c is
when '0' =>
a <= input_1;
b <= output_1;
when others =>
a <= input_2;
b <= output_2;
end case;
Or do it with if then else as David showed.

How to model two D flip-flops with multiplexing logic

I would like to model two D flip-flops using a multiplexer for some logic. I want to have static outputs of "000" for the three MSB when the multiplexer selects DFF D1 (B = 0) and the three LSB should be fixed to "111" when the multiplexer selects DFF D2 (B = 1).
This is my code -- which I originally typed blindly without checking for obvious syntax errors -- below. I don't know how to solve my problem:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity dff_mux is
Port ( D1, D2 : in STD_LOGIC_VECTOR(11 DOWNTO 0);
clk : in STD_LOGIC;
rst : IN STD_LOGIC;
B : in STD_LOGIC;
data : out STD_LOGIC_VECTOR(11 DOWNTO 0));
end dff_mux;
architecture Behavioral of dff_mux is
signal Q1, Q2 : std_logic_vector(11 downto 0);
begin
process(clk,rst)
begin
if (rst = '1') then
Q1<="000000000000";
elsif (clk'event and clk='1') then
if (B = '0') then
-- I want to fix thee MSB to "000"
-- other bits shall retain their input value
D1(11) <= '0';
D1(10) <= '0';
D1(9) <= '0';
Q1 <= D1;
elsif (B = '1') then
-- fix three LSB to "111"
-- other bits retain their input value
D2(2) <= '1';
D2(1) <= '1';
D2(0) <= '1';
Q2 <= D2;
end if;
end if;
end process;
-- MUX description: select D1 when B = 0, else select D2 when B = 1
MUX : process(B)
begin
data <= Q1 when (B = '0') else
Q2;
end process MUX;
end Behavioral;
Thanks in advance to anybody who can help me.
There are numerous errors in your VHDL design description. The two process statements drive the same signals (Q1 and Q2). The second process has three errors (no process statement label, while a label is specified in closing, concurrent signal assignment statements where sequential signal assignment statements are appropriate). It would appear the second process statement should be eliminated in it's entirety.
If the intent is to have a multiplexer on the inputs to the Q1,Q2 registers the first process is non-functional. You can't assign values to a formal input inside a block.
You should be assigning the B selected values to Q1 and Q2 directly inside the process statement (inside the clk elsif).
Your assignment to D(11) is defective (uses == instead of <=).
It isn't a multiplexer if you only assign one value to a particular signal (e.g. longest static prefix D1 and D2). Note there is no reset value for Q2 provided.
There is no place data is assigned.
If you're doing this for class work there is little benefit in someone providing the answer without learning VHDL a bit more. If you're earnestly trying to learn VHDL you need more and incrementally building exercises.
If I understand what you are trying to do correctly it would look something like this:
architecture Behavioral of basculeD is
-- signal Q1, Q2 : std_logic_vector(11 downto 0);
begin
-- process(clk,rst)
-- begin
-- if (rst='1') then Q1<="000000000000";
-- elsif ( clk'event and clk='1') then
-- if (B='0') then
-- D1(11) =='0'; -- i want to fix the 3MSB of D1 in the "000" ...
-- D1(10) <='0';
-- D1(9) <='0';
-- Q1<= D1;
-- elsif (B='1') then
-- D2(2)<= '1'; -- the 3LSB are fixed to 111 , and defaut value ...
-- D2(1)<='1';
-- D2(0)<='1';
-- Q2<=D2;
-- end if;
-- end if;
-- end process;
-- description MUX : select D1 when B=0, else select D2 when B= 1
-- process( B)
-- begin
-- Q1 <= D1 when B='0' else
-- Q2<=D2 when B='1' ;
-- end process MUX;
MUXED_REG:
process (clk,rst)
begin
if rst = '1' then
data <= (others => '0'); -- equivalent to "000000000000"
elsif clk'event and clk = '1' then
-- the actual multiplexer:
if B = '0' then
data <= ("000" & D1(8 downto 0));
else -- B = '1', or other values
data <= (D2(11 downto 3) & "111");
end if;
end if;
end process;
end Behavioral;
You could of course retain an intermediary signal, say Q and use it in place of data above, with a concurrent signal assignment from Q to data (the output).
Using the above architecture in place of your's analyzes.
With a test bench:
library ieee;
use ieee.std_logic_1164.all;
entity basculeD_test is
end entity;
architecture test of basculeD_test is
component basculeD is
port (
d1, d2: in std_logic_vector(11 downto 0);
clk: in std_logic;
rst: in std_logic;
b: in std_logic;
data: out std_logic_vector(11 downto 0)
);
end component;
signal d1: std_logic_vector(11 downto 0) := (others => '1');
signal d2: std_logic_vector(11 downto 0) := (others => '0');
signal clk: std_logic := '0';
signal rst: std_logic := '1';
signal b: std_logic := '0';
signal data: std_logic_vector(11 downto 0);
begin
CLOCK:
process
begin
wait for 10 ns;
clk <= not clk;
if Now > 100 ns then
wait;
end if;
end process;
RESET:
process
begin
wait for 31 ns;
rst <= '0';
wait;
end process;
DUT:
basculeD
port map (
d1 => d1,
d2 => d2,
clk => clk,
rst => rst,
b => b,
data => data
);
STIMULUS:
process
begin
wait for 65 ns;
b <= '1';
wait;
end process;
end architecture;
And using the replacement architecture for basculeD with the MUXED_REG process:
david_koontz#Macbook: ghdl -a basculeD.vhdl
david_koontz#Macbook: ghdl -e basculeD_test
david_koontz#Macbook: ghdl -r basculeD_test --wave=basculeD_test.ghw
david_koontz#Macbook: open basculeD_test.gtkw (previously saved save file)
Gives:
There's of course the possibility that you are trying to separate storage from multiplexing entirely, which says you could use Q1 and Q2 as registers (and only need 9 bits), a separate multiplexer (as implied in your original basculeD architecture) allowing B to steer between modified Q1 and Q2 register values on output data.
That would look something like this:
architecture Behavioral of basculeD is
signal Q1: std_logic_vector(8 downto 0);
signal Q2: std_logic_vector(11 downto 3);
begin
REGS:
process (clk, rst)
begin
if rst = '1' then
Q1 <= (others => '0');
Q2 <= (others => '0');
elsif clk'event and clk = '1' then
Q1 <= D1 (8 downto 0);
Q2 <= D2(11 downto 3);
end if;
end process;
MUX:
process (B,Q1,Q2)
begin
if B = '0' then
data <= ("000" & Q1);
else
data <= (Q2 & "111");
end if;
end process;
And give you something like this:
VHDL is meant to convey a design specification to the reader, which is made easier when using some convention for capitalization (VHDL isn't case sensitive except in extended identifiers) and indentation.
Welcome to StackOverflow! First off, this is an English Question & Answer site. Please translate all pertinent terms into English, i.e. basculeD => D flip-flop etc. Also, try to describe your problem the best you can without too many spelling mistakes (spell check!) or grammar errors. This will help other people understand you and help you efficiently.
Anyway, your main problem is, that you have input ports D1 and D2 and you try to write to them. Instead, you should just take whatever bits you need and disregard the other bits.
Instead of trying to write to the input, which is not possible, you should try this:
Q2 <= D2(11 downto 3) & "111";
This statement takes bits 11 through 3 from D2 and assigns them to bits 11 through 3 of Q2. Bits 2 through 0 of Q2 are assigned a constant value of "111".
You should remember that you cannot "re-write" input port values. Your last process could also be re-written to a parallel statement.
Also, your design is peculiar in the sense that you want to store the modified value separately.
Consider this:
D1 = x"00A"; D2 = x"00B", B = '0', clk --> rising edge
Now, Q1 = x"00A", Q2 = x"???", data = Q1 = x"00A", B = '0', clk = '1'
Now, Q1 = x"00A", Q2 = x"???", data = Q2 = x"???", B = '1', clk = '1'
You need at least two clock periods to switch your outputs when you want to switch between B = '1' and B = '0', because Q1 resp Q2 will hold old (and possibly uninitialized) values.
Your design might not do what you want it to do. If you want a multiplexer, go for a multiplexer. If you want a flip flop, build a flip flop.
process(clk,rst)
begin
if (rst = '1') then
data <= (others => '0');
elsif (clk'event and clk='1') then
if (B = '1') then
-- Select D2
data <= D2(11 downto 3) & "111";
else
-- Select D1
data <= "000" & D1(8 downto 0);
end if;
end if;
end process;
You might also want to think about whether a reset is really appropriate and whether a synchronous reset might be more beneficial.

how can I use an infix expression in a case statement in VHDL?

I want to compare two binary logic vectors A, and B. However my code won't compile and I am not sure why I am not allowed to use comparison statements here. can anyone help me? My problem is that I am new to VHDL and I need some tips
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--entity declaration of IC74x85 with port definitions
entity IC74x85 is
port( A : in std_logic_vector(3 downto 0); --input A is a 4 bit binary number
B : in std_logic_vector(3 downto 0); --input B is a 4 bit binary number
ALTBOUT : out std_logic; -- A < B
AEQBOUT : out std_logic; -- A = B
AGTBOUT : out std_logic -- A > B
);
end IC74x85;
--architecture of entity
architecture IC74x85_arch of IC74x85 is
begin
process(A,B)
begin
case A is
when (A < B) => ALTBOUT <= '1';
when (A > B) => AGTBOUT <= '1';
when (A = B) => AEQBOUT <= '1';
when others => ALTBOUT, AGTBOUT, AEQBOUT <= '0';
end case;
end process;
end IC74x85_arch;
** Error: C:/Users/Steve/Desktop/Ass1/case signal assignment.vhd(21): Type error resolving infix expression "<" as type ieee.std_logic_1164.STD_LOGIC_VECTOR.
** Error: C:/Users/Steve/Desktop/Ass1/case signal assignment.vhd(21): Choice in CASE statement alternative must be locally static.
** Error: C:/Users/Steve/Desktop/Ass1/case signal assignment.vhd(22): Type error resolving infix expression ">" as type ieee.std_logic_1164.STD_LOGIC_VECTOR.
** Error: C:/Users/Steve/Desktop/Ass1/case signal assignment.vhd(22): Choice in CASE statement alternative must be locally static.
** Error: C:/Users/Steve/Desktop/Ass1/case signal assignment.vhd(23): Type error resolving infix expression "=" as type ieee.std_logic_1164.STD_LOGIC_VECTOR.
** Error: C:/Users/Steve/Desktop/Ass1/case signal assignment.vhd(23): Choice in CASE statement alternative must be locally static.
** Error: C:/Users/Steve/Desktop/Ass1/case signal assignment.vhd(24): near ",": expecting <= or :=
What you are trying to do cannot be accomplished with a case statement, but you can simply write it as an if-then-else. Also, you can't use comparison operations like < and > on std_logic_vectors -- this is something that takes numeric interpretation, so you need to use the signed or unsigned types depending on what kind of numbers you have:
First, include ieee.numeric_std.all:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
Then cast the data types correctly for your comparisons:
process(A,B)
begin
if signed(A) < signed(B) then ALTBOUT <= '1';
elsif signed(A) > signed(B) then AGTBOUT <= '1';
else signed(A) = signed(B) then AEQBOUT <= '1';
else ALTBOUT <=0; AGTBOUT <=0; AEQBOUT <= '0';
end if;
end process;
You can't use a case statement to do this. Your error messages say why:
Type error resolving infix expression "<" as type ieee.std_logic_1164.STD_LOGIC_VECTOR.
You are asking the compiler to choose a case based on the value of A. The code you have written is asking the compiler to compare A (an slv) with A<B which is a boolean. Clearly, that won't ever work.
As answered before, this is a job for the if-elsif-else statements and the signed data type.
However, if for some reason you really wanted to this with a case statement -- as in: "Hey, Joe I'll give you a big bag of money if your can write this in VHDL using a case statement and no if-elsif-else statements." It can be done. Joe Engineer would concatenate the A and B together (it is assumed A and B are 4-bits wide) into an 8-bit std_logic_vector, called C. Then Joe would write a case with C and have 256 when statements -- each when would set ALTBOUT, AGTBOUT, and AEQBOUT to the correct value for each 8-bit pattern.
Of course, this is a silly way to do this (unless someone is going to give you a big bag of money :-) !
BTW: What wjl gave:
process(A,B)
begin
if signed(A) < signed(B) then ALTBOUT <= '1';
elsif signed(A) > signed(B) then AGTBOUT <= '1';
elsif signed(A) = signed(B) then AEQBOUT <= '1';
else ALTBOUT <=0; AGTBOUT <=0; AEQBOUT <= '0';
end if;
end process;
(Sorry, I cannot leave comments to answers, yet, or I would comment on mjl's answer) can be improved (beyond the inferred latch issue): There is no reason to test for A==B. If NOT (A<B) and NOT (A>B) then A must equal B.
process(A,B)
begin
ALTBOUT <=0; AGTBOUT <=0; AEQBOUT <= '0';
if signed(A) < signed(B) then ALTBOUT <= '1';
elsif signed(A) > signed(B) then AGTBOUT <= '1';
else AEQBOUT <= '1';
end if;
end process;

Resources