Vhdl 模拟期间modelsim中出现致命错误

Vhdl 模拟期间modelsim中出现致命错误,vhdl,simulation,Vhdl,Simulation,这是我用VHDL编写的主要代码: library ieee; USE ieee.std_logic_1164.all; use ieee.numeric_std.all; entity pid is port( error ,Kp, Ti, Td ,dt: in std_logic_vector(7 downto 0); reset : in std_logic; output :out std_logic_vector(31 downto 0) );

这是我用VHDL编写的主要代码:

library ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;

  entity pid is
    port( error ,Kp, Ti, Td ,dt: in std_logic_vector(7 downto 0);
      reset : in std_logic;
      output :out std_logic_vector(31 downto 0) );
    end pid;

    architecture pid_arch of pid is
    -------------------------------- functions
    function add_vec(num1,num2,num3: in std_logic_vector(15 downto 0)) return std_logic_vector is
    variable v_TEST_VARIABLE1: integer;
    variable v_TEST_VARIABLE2: integer;
    variable v_TEST_VARIABLE3: integer;
    variable n_times1: integer;
    variable n_times2: integer;
variable sum: integer;    
    begin
        v_TEST_VARIABLE1 := to_integer(unsigned(num1)) ; 
       v_TEST_VARIABLE2 := to_integer(unsigned(num2)) ;
       v_TEST_VARIABLE3 := to_integer(unsigned(num3 )); 

       --for n_times1 in 1 to v_TEST_VARIABLE2 loop
      --   v_TEST_VARIABLE1: = v_TEST_VARIABLE1 + '1';
     --  end loop;
     --  for n_times2 in 1 to v_TEST_VARIABLE3 loop
     --    v_TEST_VARIABLE1:= v_TEST_VARIABLE1 + '1';
      -- end loop;
      sum:= v_TEST_VARIABLE1+ v_TEST_VARIABLE2 + v_TEST_VARIABLE3;
       return std_logic_vector(to_unsigned(sum,32));
     end add_vec;
    -----------------------------------
    function sub(num1, num2: in std_logic_vector(7 downto 0)) return std_logic_vector is
    variable v_TEST_VARIABLE1: integer;
    variable v_TEST_VARIABLE2: integer;
    variable difference: integer;
    begin
       v_TEST_VARIABLE1 := to_integer(unsigned(num1)) ; 
       v_TEST_VARIABLE2 := to_integer(unsigned(num2)) ;
       difference := v_TEST_VARIABLE1 - v_TEST_VARIABLE2;
       return std_logic_vector(to_unsigned(difference,8));
     end sub;
    ------------------------------------
    function mul(num1,num2 : in std_logic_vector(7 DOWNTO 0)) return std_logic_vector is
    variable v_TEST_VARIABLE1 : integer;
    variable v_TEST_VARIABLE2 : integer;
    variable n_times: integer:=1;
    variable product: integer:=0;
    begin 
       v_TEST_VARIABLE1 := to_integer(unsigned(num1)) ; 
       v_TEST_VARIABLE2 := to_integer(unsigned(num2)) ;
      for n_times in 1 to v_TEST_VARIABLE2 loop
        product:=product + v_TEST_VARIABLE1;
      end loop;
    return std_logic_vector(to_unsigned(product,16));
  end mul;
  --------------------------------
    function div(num1, num2 : in std_logic_vector(7 DOWNTO 0)) return std_logic_vector is
             variable v_TEST_VARIABLE1 : integer;
             variable v_TEST_VARIABLE2 : integer;
             variable quotient :integer;
        --           begin 
      --P3: PROCESS(num1, num2)
       variable n_times: integer:=1;
     begin     
        if num1>num2 then
       v_TEST_VARIABLE1 := to_integer(unsigned(num1)) ; 
       v_TEST_VARIABLE2 := to_integer(unsigned(num2)) ;
       L1:loop
         n_times := n_times + 1;
        exit when ((v_TEST_VARIABLE2 -  v_TEST_VARIABLE1)>0);
        v_TEST_VARIABLE1 := v_TEST_VARIABLE1 - v_TEST_VARIABLE2;
       end loop L1;

    quotient := n_times-1;
   elsif num2>num1 then
      v_TEST_VARIABLE1 := to_integer(unsigned(num1)) ;  
       v_TEST_VARIABLE2 := to_integer(unsigned(num2)) ;
       L2:loop
        n_times:=n_times+1;
       exit when ((v_TEST_VARIABLE1 -  v_TEST_VARIABLE2)>0);
       v_TEST_VARIABLE2 := v_TEST_VARIABLE2 - v_TEST_VARIABLE1;

   quotient := n_times-1;

end loop L2;
    else
      quotient := 1;
    end if;
    return std_logic_vector(to_unsigned(quotient,16));
 -- end PROCESS P3;
      end div;

  ---------------------------------
  function derivative(error, previous_error, dt :in std_logic_vector(7 downto 0)) return std_logic_vector is
  variable derivative_val: std_logic_vector(15 downto 0);
  begin
      derivative_val := div(sub(error,previous_error),dt);
      return derivative_val;
  end derivative;
  --------------------------------------------

function integration(error,dt:in std_logic_vector(7 downto 0);current_integration :in std_logic_vector(15 downto 0);reset : in std_logic) return std_logic_vector is
       begin  
         if (reset='1') then
           return "0000000000000000";
      else  
         --current_integration := add_vec(current_integration, mul(error,dt),x"0000");
        -- return current_integration;
        return add_vec(current_integration, mul(error,dt),x"0000");
       end if;
end integration;
    -------------------------
     begin 
        P1:PROCESS (reset ,error , Kp, Ti, Td)
        variable proportional_term : std_logic_vector(15 downto 0):=x"0000";
        variable derivative1: std_logic_vector(15 downto 0) := x"0000";
       variable derivative_term: std_logic_vector(31 downto 0) ; 
       variable integration1: std_logic_vector(15 downto 0) :=x"0000";
       variable integration_term : std_logic_vector(15 downto 0) := x"0000";
       variable current_integration: std_logic_vector(15 downto 0) ;
       variable previous_error: std_logic_vector(7 downto 0) := "00000000";
       variable v1: std_logic_vector( 15 downto 0);
       variable v2 : std_logic_vector( 23 downto 0);
       variable v3 : std_logic_vector (7 downto 0);
       ------------------checked till here

        begin 
        if (reset='1') then
          --  output <= x"00000000";
            previous_error :="00000000";
            current_integration := x"0000";
      else  

         --output <= Kp*(error + integration/Ti + derivative*Td);
         current_integration := integration1;
         end if;
        -- proportional_term := mul(Kp,error);
           proportional_term := std_logic_vector(unsigned(Kp) * unsigned(error));
        -- derivative_term := mul(mul(Kp,Td), derivative(error, previous_error,dt));
        v1 :=std_logic_vector(unsigned(Kp)*unsigned(Td));
        derivative1 := derivative(error, previous_error,dt);
        derivative_term := std_logic_vector(unsigned(v1)*unsigned(derivative1));
        integration1 :=integration(error,dt,current_integration,reset);
        v2 :=std_logic_vector((unsigned(Kp)*unsigned(integration1)));
        v3 := std_logic_vector(resize(unsigned(v2),8));
         integration_term := div( v3, Ti);
               --   integration_term := div(mul(Kp, integration(error,dt,current_integration,reset)) , Ti);
         previous_error :=error;
      output <= add_vec(std_logic_vector(resize(unsigned(proportional_term),16)) , std_logic_vector(resize(unsigned(derivative_term),16)), std_logic_vector(resize(unsigned(integration_term),16)));
        --output <= x"0000";
        --Kp*(error + integration/Ti + derivative*Td);
      END PROCESS P1;
      end pid_arch;
ieee库;
使用ieee.std_logic_1164.all;
使用ieee.numeric_std.all;
实体pid为
端口(错误,Kp,Ti,Td,dt:std_逻辑_向量(7到0);
复位:在标准逻辑中;
输出:输出标准逻辑向量(31到0);
末端pid;
pid的体系结构是
--------------------------------功能
函数add_vec(num1、num2、num3:in std_logic_vector(15到0))返回std_logic_vector为
变量v_TEST_VARIABLE1:整数;
变量v_TEST_VARIABLE2:整数;
变量v_TEST_VARIABLE3:整数;
变量n_times1:整数;
变量n_times2:整数;
变量和:整数;
开始
v_TEST_VARIABLE1:=to_整数(无符号(num1));
v_TEST_VARIABLE2:=to_整数(无符号(num2));
v_TEST_VARIABLE3:=to_整数(无符号(num3));
--对于n_times1 in 1 to v_TEST_VARIABLE2循环
--v_测试_变量1:=v_测试_变量1+‘1’;
--端环;
--对于1到v_测试变量3循环中的n_时间2
--v_测试_变量1:=v_测试_变量1+‘1’;
--端环;
总和:=v_检验变量1+v_检验变量2+v_检验变量3;
返回标准逻辑向量(到无符号(和,32));
结束添加向量;
-----------------------------------
函数sub(num1,num2:in标准逻辑向量(7到0))返回标准逻辑向量
变量v_TEST_VARIABLE1:整数;
变量v_TEST_VARIABLE2:整数;
变量差:整数;
开始
v_TEST_VARIABLE1:=to_整数(无符号(num1));
v_TEST_VARIABLE2:=to_整数(无符号(num2));
差异:=v_检验变量1-v_检验变量2;
返回标准逻辑向量(到无符号向量(差,8));
末端接头;
------------------------------------
函数mul(num1,num2:in std_logic_vector(7到0))返回std_logic_vector为
变量v_TEST_VARIABLE1:整数;
变量v_TEST_VARIABLE2:整数;
变量n_次:整数:=1;
变量乘积:整数:=0;
开始
v_TEST_VARIABLE1:=to_整数(无符号(num1));
v_TEST_VARIABLE2:=to_整数(无符号(num2));
对于1到v_测试变量2循环中的n_次
产品:=产品+v_测试变量1;
端环;
返回标准逻辑向量(到无符号(乘积,16));
末端mul;
--------------------------------
函数div(num1,num2:in标准逻辑向量(7到0))返回标准逻辑向量
变量v_TEST_VARIABLE1:整数;
变量v_TEST_VARIABLE2:整数;
可变商:整数;
--开始
--P3:过程(num1,num2)
变量n_次:整数:=1;
开始
如果num1>num2,则
v_TEST_VARIABLE1:=to_整数(无符号(num1));
v_TEST_VARIABLE2:=to_整数(无符号(num2));
L1:循环
n次:=n次+1;
当((v_测试变量2-v_测试变量1)>0时退出;
v_检验变量1:=v_检验变量1-v_检验变量2;
端环L1;
商:=n_乘以-1;
如果num2>num1,则
v_TEST_VARIABLE1:=to_整数(无符号(num1));
v_TEST_VARIABLE2:=to_整数(无符号(num2));
L2:循环
n次:=n次+1;
当((v_测试变量1-v_测试变量2)>0时退出;
v_检验变量2:=v_检验变量2-v_检验变量1;
商:=n_乘以-1;
端环L2;
其他的
商:=1;
如果结束;
返回标准逻辑向量(到无符号(商,16));
--结束过程P3;
结束div;
---------------------------------
函数导数(错误,前一个错误,dt:in std_logic_vector(7到0))返回std_logic_vector为
变量导数值:标准逻辑向量(15到0);
开始
导数_val:=div(sub(误差,前一个_误差),dt);
返回导数值;
端导数;
--------------------------------------------
函数积分(错误,dt:标准逻辑矢量中(7向下至0);当前积分:标准逻辑矢量中(15向下至0);复位:标准逻辑中)返回标准逻辑矢量为
开始
如果(reset='1'),则
返回“0000000000000000”;
其他的
--当前_积分:=添加_向量(当前_积分,mul(误差,dt),x“0000”);
--返回电流积分;
返回add_vec(当前_积分,mul(错误,dt),x“0000”);
如果结束;
末端整合;
-------------------------
开始
P1:过程(重置、错误、Kp、Ti、Td)
变量比例项:标准逻辑向量(15到0):=x“0000”;
变量导数1:std_逻辑_向量(15到0):=x“0000”;
变量导数项:标准逻辑向量(31到0);
变量积分1:std_逻辑_向量(15到0):=x“0000”;
变量积分项:标准逻辑向量(15到0):=x“0000”;
可变电流积分:标准逻辑矢量(15至0);
变量先前错误:标准逻辑向量(7到0):=“00000000”;
变量v1:std_逻辑_向量(15到0);
变量v2:std_逻辑_向量(23向下至0);
变量v3:std_逻辑_向量(7到0);
------------------检查到这里
开始
如果(reset='1'),则
--输出Td,
dt=>dt,
重置=>重置,
输出=>输出
);       
clk_流程:流程
开始

错误您的进程P1连续在实体pid循环中。我可以想象Modelsim在某些东西连续旋转时使用一个保护计时器来引起异常

我通过分而治之找到了这一点:

ghdl-a pid.vhdl#analyze,还包含pid_2_tb实体/体系结构
ghdl-e pid_2_tb
ghdl-r pid_2_tb——停止时间=100ns#运行模拟(批处理模式)保护停止时间)

永远如此:

ghdl-e pid#仅详细说明组件
ghdl-r pid——停止时间=30ns#只运行组件
../../../src/ieee/n
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.numeric_std.all;

   ENTITY pid_2_tb IS 
END pid_2_tb;

ARCHITECTURE behavior OF pid_2_tb IS

    COMPONENT pid  --'test' is the name of the module needed to be tested.

    port(error ,Kp, Ti, Td ,dt: in std_logic_vector(7 downto 0);
      reset : in std_logic;
      output :out std_logic_vector(31 downto 0) );

    END COMPONENT;
   signal error : std_logic_vector(7 downto 0) := "00000000";
   signal Kp : std_logic_vector(7 downto 0) := "00001000";
   signal Ti : std_logic_vector(7 downto 0) := "00000001";
   signal Td : std_logic_vector(7 downto 0) := "00000001";
   signal dt : std_logic_vector(7 downto 0) := "00000001";
  signal reset : std_logic := '1';

   signal output : std_logic_vector(31 downto 0);

   constant clk_period : time := 1 ns;
BEGIN
   uut: pid PORT MAP (
         error => error,
          Kp => Kp,
          Ti => Ti,
          Td => Td,
          dt => dt,
          reset => reset,
          output => output
        );       

   clk_process :process
   begin
        error <= "00000001";
        reset <= '1';
        wait for clk_period/2;  
        error <= "00000010";
        reset <= '0';
        wait for clk_period/2;  --for next 0.5 ns signal is '1'.
   end process;
   -- Stimulus process
  stim_proc: process
   begin         

        wait for 17 ns;
        error <= "00000011";
        reset <= '0';
        wait for 1 ns;
        error <= "00000010";
        reset <= '0';
        wait;
  end process;

END;
function div(num1, num2 : in std_logic_vector(7 downto 0)) 
        return std_logic_vector is

    variable v_test_variable1: integer;
    variable v_test_variable2: integer;
    variable quotient:  integer;
    variable n_times:   integer:= 1;

begin     
    if num1 > num2 then
        v_test_variable1 := to_integer(unsigned(num1)) ; 
        v_test_variable2 := to_integer(unsigned(num2)) ;
    l1:
        loop
            n_times := n_times + 1;
            exit when ((v_test_variable2 -  v_test_variable1) > 0);
            v_test_variable1 := v_test_variable1 - v_test_variable2;
        end loop l1;

        quotient := n_times - 1;
    elsif num2 > num1 then
        v_test_variable1 := to_integer(unsigned(num1));  
        v_test_variable2 := to_integer(unsigned(num2));
    l2:
        loop
            n_times := n_times + 1;
            exit when ((v_test_variable1 -  v_test_variable2) > 0);
            v_test_variable2 := v_test_variable2 - v_test_variable1;
            quotient := n_times - 1;
        end loop l2;
    else
        quotient := 1;
    end if;
    return std_logic_vector(to_unsigned(quotient,16));
  end div;
elsif num2 > num1 then
  v_TEST_VARIABLE1 := to_integer(unsigned(num1));
  v_TEST_VARIABLE2 := to_integer(unsigned(num2));
  L2 : loop
    n_times          := n_times+1;
    exit when ((v_TEST_VARIABLE1 - v_TEST_VARIABLE2) > 0);
    v_TEST_VARIABLE2 := v_TEST_VARIABLE2 - v_TEST_VARIABLE1;
    quotient := n_times-1;
  end loop L2;