当前位置: 动力学知识库 > 问答 > 编程问答 >

vhdl - Unable to compare part of a std_logic_vector to a constant

问题描述:

So in VHDL, I have a signal that's a std_logic_vector called A (let's say it's 32 bits). I want to look at bits 31...28 of A, check if it's 0001, and then do something if it is. So I have an if statement set up like this:

if (A(3 downto 0) = "0001") then:

--do something

The problem I'm having is that I'm getting errors related it, but I'm not being told exactly what the error is:

ERROR:HDLCompiler:806 - "/home/csmajs/jchio001/Desktop/bcd_alu/bcd_alu.vhd" Line 104: Syntax error near "when".

ERROR:HDLCompiler:806 - "/home/csmajs/jchio001/Desktop/bcd_alu/bcd_alu.vhd" Line 108: Syntax error near "when".

ERROR:HDLCompiler:806 - "/home/csmajs/jchio001/Desktop/bcd_alu/bcd_alu.vhd" Line 110: Syntax error near "case".

(I have the if statement in a case statement)

As you can see, I'm being told the there's an error with the code around it, rather than being told that there's an error with this if statement. If I remove the if statement from my code, everything's fine, so I know that it's the if statement that's invalid. So what's wrong with this if statement?

Full code:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using

-- arithmetic functions with Signed or Unsigned values

use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating

-- any Xilinx primitives in this code.

--library UNISIM;

--use UNISIM.VComponents.all;

entity my_bcd_alu is

Port ( A : in STD_LOGIC_VECTOR(31 downto 0);

B : in STD_LOGIC_VECTOR(31 downto 0);

Opcode : in STD_LOGIC_VECTOR(3 downto 0);

Result : out STD_LOGIC_VECTOR(35 downto 0);

Carry_out : out STD_LOGIC;

Overflow : out STD_LOGIC;

Zero : out STD_LOGIC);

end my_bcd_alu;

architecture Behavioral of my_bcd_alu is

signal temp: std_logic_vector(35 downto 0);

signal sig_A: std_logic_vector(31 downto 0);

signal sig_B: std_logic_vector(31 downto 0);

Variable tempA: INTEGER;

Variable tempB: INTEGER;

Variable decA: INTEGER;

Variable decB: INTEGER;

begin

process(A, B, Opcode, temp, sig_A, sig_B)

begin

decA := 0;

decB := 0;

tempA := TO_INTEGER(unsigned(A(3 downto 0)));

decA := decA + tempA;

tempA := TO_INTEGER(unsigned(A(7 downto 4)));

decA := decA + tempA;

tempA := TO_INTEGER(unsigned(A(11 downto 8)));

decA := decA + tempA;

tempA := TO_INTEGER(unsigned(A(15 downto 12)));

decA := decA + tempA;

tempA := TO_INTEGER(unsigned(A(19 downto 16)));

decA := decA + tempA;

tempA := TO_INTEGER(unsigned(A(23 downto 20)));

decA := decA + tempA;

tempA := TO_INTEGER(unsigned(A(27 downto 24)));

decA := decA + tempA;

tempB := TO_INTEGER(unsigned(B(3 downto 0)));

decB := decB + tempB;

tempB := TO_INTEGER(unsigned(B(7 downto 4)));

decB := decB + tempB;

tempB := TO_INTEGER(unsigned(B(11 downto 8)));

decA := decB + tempB;

tempB := TO_INTEGER(unsigned(B(15 downto 12)));

decB := decB + tempB;

tempB := TO_INTEGER(unsigned(B(19 downto 16)));

decB := decB + tempB;

tempB := TO_INTEGER(unsigned(B(23 downto 20)));

decB := decB + tempB;

tempB := TO_INTEGER(unsigned(B(27 downto 24)));

decB := decB + tempB;

case Opcode is

when "1000" =>

tempA := TO_INTEGER(unsigned(A(31 downto 28)));

decA := decA + tempA;

tempB := TO_INTEGER(unsigned(B(31 downto 28)));

decB := decB + tempB;

temp <= std_logic_vector(TO_UNSIGNED(decA + decB, 35));

when "1001" =>

tempA := TO_INTEGER(unsigned(A(31 downto 28)));

decA := decA + tempA;

tempB := TO_INTEGER(unsigned(B(31 downto 28)));

decB := decB + tempB;

temp <= std_logic_vector(TO_UNSIGNED(decA - decB, 35));

when "1100" =>

sig_A <= std_logic_vector(TO_SIGNED(tempA, 32));

if (A(31 downto 28) = "0001") then --ERRORS HERE

sig_A <= std_logic_vector(TO_SIGNED(tempA, 32));

sig_A <= NOT(sig_A);

end if;

when "1101" =>

if (A(31 downto 28) = "0001") then

sig_A <= std_logic_vector(TO_SIGNED(tempA - 1, 32));

sig_A <= NOT(sig_A);

end if;

when others =>

temp <= "0000"&A;

end case;

end process;

end Behavioral;

EDIT: Adding end if removed the errors, but now I get:

Line 48: Variable outside of subprogram or process must be 'shared'

网友答案:

You can't have variables in the architecture's declaration part:

architecture Behavioral of my_bcd_alu is
    signal temp: std_logic_vector(35 downto 0);
    signal sig_A: std_logic_vector(31 downto 0);
    signal sig_B: std_logic_vector(31 downto 0);
    Variable tempA: INTEGER; -- Invalid
    Variable tempB: INTEGER; -- Invalid
    Variable decA: INTEGER;  -- Invalid
    Variable decB: INTEGER;  -- Invalid
begin

Either use signal instead (and modify your logic appropriately), or put the variable inside the process declarations:

process(A, B, Opcode, temp, sig_A, sig_B)
    Variable tempA: INTEGER;
    Variable tempB: INTEGER;
    Variable decA: INTEGER;
    Variable decB: INTEGER;
begin

As a free bonus, I'll give you some advice on your code, that you really should heed!

  • Do not use unconstrained integers. By the VHDL standard, they are 32 bits signed. The synthesis tool may optimized them to a smaller size, but you shouldn't count on it. Figure the max values yourself, and use integer range min to max to ensure no bigger than necessary usage.
  • In a combinational process (without clock, like yours), any output set by that process has to be set in every path through the process. For instance, sigA has no value when Opcode is "1000" or "1001", and temp is not set in the other two cases. Failure to set them in every path result in a latch, which will cause undesirable problem in your implementation. You do not have to do this for variables, as long as you do not rely on the variables keeping it's value between process' executions.
分享给朋友:
您可能感兴趣的文章:
随机阅读: