VHDL:使用二维数组

时间:2015-08-24 05:19:33

标签: arrays vhdl

我有一个二维数组,我称之为记忆。

type mem is array (0 to 79) of integer range 0 to 255;      -- 80 times by 8 bit 
type dataArray is array (0 to 7) of mem;                    -- 8 arrays of 640bit 
variable Memory: dataArray;                                 -- Here they are

我有一个SLV,回答了一些请求,并由该数组中的整数表示

inAnsw  :   in STD_LOGIC_VECTOR(7 downto 0);        -- the incoming bus
inVALID :   in STD_LOGIC                            -- the signal

在一些输入信号上,表示我有14个新字节的数据,我必须以特殊的顺序收集我的数组中传入的12个字节的数据。代码如下所示:

    if falling_edge(inVALID) then   -- 14 signals will come         
        bytenum := bytenum + 1;     -- count them to know we 
        if (bytenum = 14) then      -- start every new session with
            bytenum := 0;           -- a zero position
            answmem := answmem + 1; -- increment the array position for  
            if (answmem = 8) then answmem := 0; end if;     -- the next answer
        end if;

-- And here comes the huge problem. i am working with this 
-- huge CASE, that puts a significant answer to the needed place 
-- of my array. it works fine, but it takes more than 1500 logic 
-- cells of my FPGA. 

        case bytenum is
            when 0 => Memory(answmem)(0) := TO_INTEGER(unsigned(inAnsw));               
            when 1 => Memory(answmem)(7) := TO_INTEGER(unsigned(inAnsw));
            when 2 => Memory(answmem)(9) := TO_INTEGER(unsigned(inAnsw));
            when 3 => Memory(answmem)(10) := TO_INTEGER(unsigned(inAnsw));
            when 4 => Memory(answmem)(17) := TO_INTEGER(unsigned(inAnsw));
            when 5 => Memory(answmem)(19) := TO_INTEGER(unsigned(inAnsw));
            when 6 => Memory(answmem)(20) := TO_INTEGER(unsigned(inAnsw));
            when 7 => Memory(answmem)(27) := TO_INTEGER(unsigned(inAnsw));
            when 8 => Memory(answmem)(30) := TO_INTEGER(unsigned(inAnsw));
            when 9 => Memory(answmem)(37) := TO_INTEGER(unsigned(inAnsw));
            when 10 => Memory(answmem)(40) := TO_INTEGER(unsigned(inAnsw));
            when 11 => Memory(answmem)(47) := TO_INTEGER(unsigned(inAnsw));
            when others => Memory(answmem)(67) := TO_INTEGER(unsigned(inAnsw));
        end case;
    end if; 

因此,如果我尝试使用IF / ELSIF语句替换使用其他一些结构(如以下或任何其他结构)写入数据的代码

if (bytenum <12) then
    Memory (answmem)(bytenum+whatever) := TO_INTEGER(UNSIGNED(inAnsw));
end if;

符号编译工作正常,它需要大约100-200个逻辑单元格,但是当我开始编译一个完整的项目时,我有一个庞大的编译错误列表

Error (10821): HDL error at MyModule.vhd(217): can't infer register for "Memory[7][25][0]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(199): can't infer register for "Memory[7][25][0]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(217): can't infer register for "Memory[7][25][1]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(199): can't infer register for "Memory[7][25][1]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(217): can't infer register for "Memory[7][25][2]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(199): can't infer register for "Memory[7][25][2]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(217): can't infer register for "Memory[7][25][3]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(199): can't infer register for "Memory[7][25][3]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(217): can't infer register for "Memory[7][25][4]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(199): can't infer register for "Memory[7][25][4]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(217): can't infer register for "Memory[7][25][5]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(199): can't infer register for "Memory[7][25][5]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(217): can't infer register for "Memory[7][25][6]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(199): can't infer register for "Memory[7][25][6]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(217): can't infer register for "Memory[7][25][7]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(199): can't infer register for "Memory[7][25][7]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(203): can't infer register for "Memory[7][18][0]" because its behavior does not match any supported register model
Error (10820): Netlist error at MyModule.vhd(199): can't infer register for Memory[7][18][0] because its behavior depends on the edges of multiple distinct clocks
Error (10821): HDL error at MyModule.vhd(203): can't infer register for "Memory[7][18][1]" because its behavior does not match any supported register model

并且列表总是相同的,有关行为的一些错误,以及关于不同时钟边缘的错误

1 个答案:

答案 0 :(得分:2)

所有这些错误都表明您使用代码描述的行为无法使用目标的硬件资源实现。

...because its behavior does not match any supported register model

说合成工具识别了一种寄存器,但不是它可以实现的那种。

...because its behavior depends on the edges of multiple distinct clocks

告诉你更多:你描述了一个多时钟寄存器,这是不支持的。由于Memory是您的流程的本地变量,因此您的问题来自您未发布的相同流程的行。例如,如果您的代码包含在:

process(clk,inVALID)
begin
  if rising_edge(clk) then
    if falling_edge(inVALID) then   -- 14 signals will come
      ... your code ...
    end if;
  end if;
end process;

然后您的Memory注册银行有两个时钟:clkinVALIDMemory的每个位都应该在有上升沿时更新clk,同时也是inVALID的下降边缘。

它也可以是代码之前或之后的某些代码,仍然在同一个进程中。例如,如果您的代码前面或类似于:

  if rising_edge(another_signal) then
    ...
    Memory(x)(y) := value;
    ...
  end if;
  if falling_edge(inVALID) then   -- 14 signals will come
    ... your code ...
  end if;

然后,您的Memory注册银行还有两个时钟:another_signalinVALIDMemory的每个位都应该在有another_signal时更新上升沿为inVALID或/和inVALID的下降沿,优先级为 if ($object != null && !$this->supportsClass(get_class($object))) { return self::ACCESS_ABSTAIN; }

对于我所知道的所有合成器来说,这太过分了。