Vhdl 我怎样才能知道乘法运算何时完成?

Vhdl 我怎样才能知道乘法运算何时完成?,vhdl,Vhdl,我试图在VHDL中对两个std\u logic\u vectors进行乘法,我正在努力找到一种方法来确定乘法运算何时完成。到目前为止,我已经尝试了以下方法: 将结果信号设置为0,并检查任一输入是否为零:如果为真,则结果为零,否则等待结果变为非零。 我认为这种方法非常昂贵,而且可扩展性差,因此我更愿意找到一种不同的解决方案 我希望,由于同一进程中的语句是按顺序执行的,因此,将控制信号相乘并在相乘之后设置为“1”,这样,只有在相乘完成时,控制信号才会设置为“1”。不幸的是,情况并非如此,据我所知,

我试图在VHDL中对两个
std\u logic\u vector
s进行乘法,我正在努力找到一种方法来确定乘法运算何时完成。到目前为止,我已经尝试了以下方法:

  • 将结果信号设置为0,并检查任一输入是否为零:如果为真,则结果为零,否则等待结果变为非零。 我认为这种方法非常昂贵,而且可扩展性差,因此我更愿意找到一种不同的解决方案

  • 我希望,由于同一进程中的语句是按顺序执行的,因此,将控制信号相乘并在相乘之后设置为“1”,这样,只有在相乘完成时,控制信号才会设置为“1”。不幸的是,情况并非如此,据我所知,这是由于信号分配不是连续的

  • 创建一个单独的进程,其灵敏度列表中仅包含结果,以便该进程仅在乘法完成时“激活”,然后将控制信号设置为“1”。我认为这不起作用,因为结果是
    std\u logic\u vector
    ,因此进程无法确定其值何时更新

  • 下面是方法2的完整代码

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.numeric_std.all;
    
    entity multiplier is
        Port ( input_1 : in STD_LOGIC_VECTOR (8 downto 0); --max input = 128 (9 bit)
               input_2 : in STD_LOGIC_VECTOR (8 downto 0);
               start   : in STD_LOGIC;
               reset   : in STD_LOGIC;
               result  : out STD_LOGIC_VECTOR (15 downto 0); --max output = 128*128 = 16384 (16 bit)
               done    : out STD_LOGIC;
               clk     : in STD_LOGIC);
    end multiplier;
    
    architecture Behavioral of multiplier is
    
    signal working : STD_LOGIC := '0';
    signal temp : STD_LOGIC_VECTOR (17 downto 0);
    
    begin
        process (start,clk,reset)
            begin
            if(reset = '0') then
                if start = '1' then
                    if rising_edge(clk) then
                        if working = '0' then
                            working <= '1';
                            temp <= std_logic_vector(unsigned(input_1)*unsigned(input_2));
                            result <= temp(15 downto 0); --ugly workaround for bit truncation
                            done <= '1';
                            working <= '0';
                        end if;
                    end if;
                end if;            
            else --reset
                result <= (others => '0');
                temp <= (others => '0');
                working <= '0';
                done <= '0';
            end if;
        end process;
        
        
    end Behavioral;
    
    IEEE库;
    使用IEEE.STD_LOGIC_1164.ALL;
    使用IEEE.numeric_std.all;
    实体乘数是
    端口(输入1:标准逻辑向量(8到0);--最大输入=128(9位)
    输入2:标准逻辑向量(8到0);
    启动:在标准逻辑中;
    复位:在标准逻辑中;
    结果:输出标准逻辑向量(15到0);--最大输出=128*128=16384(16位)
    完成:输出标准逻辑;
    时钟:在标准逻辑中);
    末端倍增器;
    乘法器的结构是
    信号工作:标准逻辑:='0';
    信号温度:标准逻辑向量(17至0);
    开始
    过程(启动、时钟、复位)
    开始
    如果(重置='0'),则
    如果start='1',则
    如果上升沿(clk),则
    如果工作='0',则
    
    工作正如我在评论中提到的,这个乘法应该在一个时钟周期后完成。下面是一段代码片段,我还没有对其进行测试,但它应该适合您:

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.numeric_std.all;
    
    entity multiplier is
        Port ( input_1 : in STD_LOGIC_VECTOR (8 downto 0); --max input = 128 (9 bit)
               input_2 : in STD_LOGIC_VECTOR (8 downto 0);
               start   : in STD_LOGIC;
               reset   : in STD_LOGIC;
               result  : out STD_LOGIC_VECTOR (15 downto 0); --max output = 128*128 = 16384 (16 bit)
               done    : out STD_LOGIC;
               clk     : in STD_LOGIC);
    end multiplier;
    
    architecture Behavioral of multiplier is
    
    signal temp : STD_LOGIC_VECTOR (17 downto 0);
    signal MultResult, NxMultResult : STD_LOGIC_VECTOR (15 downto 0);
    signal MultDone, NxMultDone : STD_LOGIC;
    
    begin
    
    -- reg
    process (clk, reset)
        begin
        if(reset = '1') then
            Result <= (others => '0');
            Done   <= '0';
        elsif (rising_edge(clk)) then
            Result <= NxResult;
            Done   <= NxDone;
        end if;
    end process;
    
    -- comb
    process (input_1, input_2, start)
        begin
        
        if start = '1' then
            temp <= std_logic_vector(unsigned(input_1) * unsigned(input_2));
            NxMultResult <= temp(15 downto 0); -- truncation
            NxMultDone <= '1';
        else
            NxMultResult <= '0';
            NxMultDone <= '0';
        end if;
    end process;
    
    -- assign outputs
    done   <= MultDone;
    result <= MultResult;
        
        
    end Behavioral;
    
    IEEE库;
    使用IEEE.STD_LOGIC_1164.ALL;
    使用IEEE.numeric_std.all;
    实体乘数是
    端口(输入1:标准逻辑向量(8到0);--最大输入=128(9位)
    输入2:标准逻辑向量(8到0);
    启动:在标准逻辑中;
    复位:在标准逻辑中;
    结果:输出标准逻辑向量(15到0);--最大输出=128*128=16384(16位)
    完成:输出标准逻辑;
    时钟:在标准逻辑中);
    末端倍增器;
    乘法器的结构是
    信号温度:标准逻辑向量(17至0);
    信号MultResult,NxMultResult:STD_逻辑_向量(15到0);
    信号多通,NxMultDone:标准逻辑;
    开始
    --注册
    过程(时钟、复位)
    开始
    如果(重置='1'),则
    结果“0”);
    
    请注意,VHDL并不像C或ADA那样是一种(顺序)编程语言,它是一种(并行)描述语言。
    工作
    的两项任务同时完成,但后者“获胜”。你需要重新阅读你的VHDL教程。不幸的是,我得到的学习资源很少,你能建议一个好的起点吗?你认为这是我的问题的原因吗,或者只是一个次要的问题?乘法是在所有组合运算完成之后进行的。您可以使用合成环境的工具计算估算值。请注意,温度和电压随时间变化,某些特定的组合会给出最长的值。好吧,所以不是推荐的地方。请使用您最喜欢的web搜索引擎。方法1是否适用,或者评估是解决此问题的唯一方法?如果它是在一个时钟周期内完成的,为什么我要为“完成”信号烦恼呢?另外,如果在时钟上升沿之前将“start”信号设置为1会怎么样?那么乘法运算就不可能“按时”完成。我是否遗漏了一些明显的东西?因为您通常使用同步设计,并将所有输入信号同步到您的时钟,所有信号都会随着时钟的变化而变化,也会像击键一样从“外部”输入。我不知道你的代码是用于FPGA还是用于合成,但在FPGA上你有DSP块,它可以实现乘法。正如您所知道的,您的合成工具会告诉您这些DSP块是否违反了时序。由于DSP块速度非常快,因此它们没有计时问题。但值得注意的是,这些DSP模块很少可用,因此“珍贵”。