Take the 2-minute tour ×

I've been trying to write a Finite State Machine in VHDL code for a simple 16-bit processor I'm implementing on an Altera DE1 board. In the Finite State Machine, I have a CASE statement that handles the different 16-bit instructions, which are brought into the FSM by a 16-bit STD_LOGIC_VECTOR. However, I'm having a little trouble in the decode state where the Finite State Machine decodes the instruction. One of the instructions is an ADD which takes two registers as operands and a third as the destination register. However, I also have an ADD instruction which takes a register and a 5-bit immediate value as operands and a second register for the destination. My problem is that in the CASE statement, I need to be able to differentiate between the two different ADD instructions. So, I thought that if I use wildcard values like "-" or "X" in the CASE statement, I would be able to differentiate between the two with just two cases instead of listing all of the possible register/immediate value combinations. For example:

    CASE IR IS --(IR stands for "Instruction Register")
      WHEN "0001------0-----" => (Go to 3-register add);
      WHEN "0001------1-----" => (Go to 2-register/immediate value add);
      WHEN OTHERS => (Do whatever);

These aren't the only two instructions I have, I just put these two to make this post a little shorter. When I compile and run this code, the processor stops executing when it gets to the "decode" state. Also, Quartus gives many, many warnings saying things like "VHDL choice warning at LC3FSM.vhd(37): ignored choice containing meta-value ""0001------0-----""" I am at a loss as to how to go about accomplishing this. I REALLY do not and probably don't need to define every single 16-bit combination, and I hope there's a way to use wildcards in a STD_LOGIC_VECTOR to minimize the number of combinations I will have to define.

Does anybody know how to accomplish this?


share|improve this question
add comment

2 Answers

up vote 1 down vote accepted

Assuming you don't need the other bits in the instruction you could hack your way around this by masking the other bits with a pre-check process. (Or just ensure the other bits are reset when you write the instruction?)

This really is a bit of a hack.

assuming IR is stored as a variable

if IR(15 downto 12) == "0001" then
    IR := IR_in(15 downto 12) & "0000000" & IR_in(5) & "00000";
    IR := IR_in
end if;

  WHEN "0001000000000000" => (Go to 3-register add);
  WHEN "0001000000100000" => (Go to 2-register/immediate value add);
  WHEN OTHERS => (Do whatever);

Alternatively assuming your instruction is cleverly thought out (are the first four bits the command word or something along those lines?) you could do nested case statements and do the differentiation as needed in those sub blocks.

share|improve this answer
Aha, thank you very much, Paul Seeb for your suggestion. After I asked the question yesterday, I thought of using a CASE statement for each operation code, and then using an IF statement to make the other necessary comparisons. Your first method, though makes the code a little bit shorter, so I used that one. Thank you, also Mark Thompson for your suggestion, as well. –  Eric Townsend Feb 10 '12 at 18:19
add comment

That can't be done unfortunately. Rather unexpectedly for most users, the comparison operator = and the case comparison perform a literal comparison. This is because the std_logic type is just a set of characters, which happen to perform like logic values due to the way other functions (eg and and or) are defined.

VHDL-2008 introduces a new case statement case? which performs as you expect - you'll need to tell your compiler to operate in VHDL 2008 mode. In addition, there is a ?= operator in VHDL 2008 which compares two values, taking account of -s.

If you are lumbered with a compiler which still doesn't support VHDL 2008, complain to the supplier. There is also a std_match function allows you to perform comparisons in older VHDL revisions, but nothing that I am aware to make the case statement work that way.

share|improve this answer
+1 for "complain to the supplier"! –  Philippe Feb 10 '12 at 9:15
An FYI for those who, like me who came here after stumbling onto the same problem with the Xilinx ISE: the new "case?" statement (like most VHDL-2008 features) is not present in v14.4 (the current release as of the time of this writing) and it's not clear when or if it'll be present in the future. –  MartyMacGyver Mar 3 '13 at 10:59
add comment

Your Answer


