在函数中使用VHDL生成语句

时间:2015-06-02 14:16:00

标签: case vhdl

我想使用生成语句但在我的代码中我有一个只接受顺序语句的case语句。

然后我想我会在一个包中使用它,我可以定义一个函数,这样我也会收到错误:'非法顺序语句'。

那么可以做些什么。有什么建议?

代码块:

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE work.my_package.all;

-- Entity for ALU component
-- Use this Entity for your C&A project

ENTITY ALU_E IS
  PORT(
    reset_n     : in std_logic;
    clk         : in std_logic;
    OperandA    : in std_logic_vector(3 downto 0);
    OperandB    : in std_logic_vector(3 downto 0);
    Operation   : in std_logic_vector(2 downto 0);
    Start       : in std_logic;
    Result_Low  : out std_logic_vector(3 downto 0);
    Result_High : out std_logic_vector(3 downto 0);
    Ready   : out std_logic;
    Errorsig    : out std_Logic);
END ALU_E;

architecture Behavioral_ALU of ALU_E is 
signal c : std_logic_vector(7 downto 0);
signal carry_internal :std_logic_vector(4 downto 0);

COMPONENT fulladder IS
  PORT(
    a: IN std_logic;
    b: IN std_logic;
    cin : IN std_logic;
    cout: OUT std_logic;
    s: OUT std_logic );
END component fulladder;

begin

adders: for N in 0 to 3 generate
            ff1:fulladder
            port map
            (a => OperandA(N),b => OperandB(N),cin => carry_internal(N),cout => carry_internal(N+1),s => c(N));
            end generate adders;            
            c(4) <= carry_internal(4);


process(clk,reset_n)
begin

if reset_n = '0' then
    if (clk'event) then
        case Operation is 
            when "000" =>   --no operation
            NULL;

            when "001" =>   --Rotate left logical operator ?0000?&A by B steps
            c <= rotlef (OperandA,OperandB);

            when "010" =>   --Rotate right logical operator ?0000?&A by B steps (result width is 8 bit)
            c <= rotrig (OperandA,OperandB);

            when "011" =>   --Bitwise XOR operation
            Result_Low <= OperandA xor OperandB;

            when "100" =>   --Sum of A and B
            --here i want to use a statement such that i can call the gatelevel      --add function
--I have already all functions gatelevel defined when i try to use portmap or ----generate it gives an error illegal sequential statement 
            when Others =>
            NULL;
        end case;
    end if;
end if;
end process;
end Behavioral_ALU;

2 个答案:

答案 0 :(得分:0)

这个问题存在一些误解。

首先是标题:实际代码中没有任何功能。您使用for ... generate语句所做的是生成一个单独的硬件,与主进程并行运行。它将始终运行,并始终用总和驱动信号'c',就好像您已经用c <= a + b;代替for ... generate。它始终是,持续工作,而不是只有你想要时才能打电话的功能。

其次,这意味着加法器和时钟进程一直驱动c,具有不同的值。这样做不会很好......实际上你应该在模拟中看到信号c上的“XXXX”。

我认为你想要做的是为加法器的输出创建一个名为sum的新信号,并在sum中为c而不是for ... generate加载。然后,在Case语句中,将sum分配给c将完成Add操作。

答案 1 :(得分:0)

就您收到错误消息的原因而言,组件实例化语句或生成语句是并发语句,而案例选择或函数体由顺序语句组成。

你不需要一个函数,你需要求和并从generate语句中实现四个fulladder s。 Ø 为fulladder假装实体/架构对:

library ieee;
use ieee.std_logic_1164.all;

entity fulladder is
    port (
        a:    in  std_logic;
        b:    in  std_logic;
        cin:  in  std_logic;
        cout: out std_logic;
        s:    out std_logic 
    );
end entity;

architecture foo of fulladder is

begin
    s <= a xor b xor cin;
    cout <= (a and b) or (a and cin) or (b and cin);
end architecture;

假装无功能my_package

library ieee;
use ieee.std_logic_1164.all;
package my_package is
    function rotlef (a, b: std_logic_vector)  return std_logic_vector;
    function rotrig (a, b: std_logic_vector) return std_logic_vector;
end package;
package body my_package is
    function rotlef (a, b: std_logic_vector)  return std_logic_vector is
        variable ret_val: std_logic_vector (a'range);
    begin
        return ret_val;
    end function;
    function rotrig (a, b: std_logic_vector) return std_logic_vector is
        variable ret_val: std_logic_vector (a'range);
    begin
        return ret_val;
    end function;
end package body;

(注意函数返回值长度与左操作数长度匹配)

为生成的fulladder的输出添加新声明:

architecture changed of alu_e is 
    signal c:               std_logic_vector(7 downto 0);
    signal carry_internal:  std_logic_vector(4 downto 0);

    signal s:               std_logic_vector(3 downto 0); -- added

更改generate语句以使用新信号作为总和:

adders: 
    for n in 0 to 3 generate
ff1:
        fulladder
            port map (
                a => operanda(n),
                b => operandb(n),
                cin => carry_internal(n),
                cout => carry_internal(n+1),
                s => s(n)  -- was c(n)
            );
    end generate;            

    -- c(4) <= carry_internal(4);

(取消对c(4)的分配)

并更改选项“100”的语句顺序:

                    when "100" =>   --sum of a and b
                        result_low <= s; -- added
                        result_high(0) <= carry_internal(4); --(un)signed? 

您的设计分析,详细说明和模拟(虽然没有做太多 - 当others未被驱动且所有operation时,案例U的过程中没有任何分配,我没有编写一个测试平台来驱动operation或为其提供默认值。

请注意c的声明长度为8,而两个函数的返回值与a输入(长度4)相匹配。

如果您要执行operation s "001""010"的虚拟函数,则由于右侧长度不匹配而导致模拟错误。我原样离开了这个问题,但没有确定您的rotlefrotrig函数是否实际返回的长度更长。

通常,您只需要8位乘法结果。 c的长度及其分配给result_lowresult_high的方式并不明显(至今)。

在没有更多细节的情况下,无法辨别您是在进行有符号算术还是无符号算术。而不是:

                        result_high(0) <= carry_internal(4); --(un)signed? 

签名的加号可能如下所示:

                        result_high <= (others => carry_internal(4)); --sign extended 

请注意,在实例化乘数时,您还需要为8位结果使用新的信号声明。修改轮播操作以分配result_lowresult_high将允许c用于实例化的乘法,但您可以选择重命名。

将流程语句中的case语句想象为实例化多路复用器,在某些情况下,您恰好也在输入上表达逻辑。 xor或符号扩展或函数调用(表达式)是示例。

当您实例化提供功能的组件时,您希望将其输出连接到多路复用器输入。