请问FPGA如何用verilog文件调用VHDL的程序并用modelsim仿真?

2019-07-15 20:33发布

问题描述:DE10-nano板提供的工程顶层文件是verilog写的,自己编写了一个PID程序是用VHDL写的。现在要把PID放到工程中编译并使用modelsim仿真。如何操作?

工程顶层文件

顶层文件DE10_Standard_GHRD.v:
  1. `define ENABLE_HPS
  2. //`define ENABLE_HSMC

  3. module DE10_Standard_GHRD(


  4.       ///////// CLOCK /////////
  5.       input              CLOCK2_50,
  6.       input              CLOCK3_50,
  7.       input              CLOCK4_50,
  8.       input              CLOCK_50,

  9.       ///////// KEY /////////
  10.       input    [ 3: 0]   KEY,

  11. ......

  12.   wire  hps_FPGA_reset_n;
  13.   wire [3:0] fpga_debounced_buttons;
  14.   wire [8:0]  fpga_led_internal;
  15.   wire [2:0]  hps_reset_req;
  16.   wire        hps_cold_reset;
  17.   wire        hps_wARM_reset;

  18.   //ram_driver3_0
  19.      //input
  20.          
  21.   wire         FCLK_5M;
  22.   wire         CHANNEL1_RAM_LOAD;        
  23.   wire [15:0]  RAM_MS_A;
  24.   wire [7:0]   RAM_S_A;
  25.   wire [7:0]   RAM_MIN_A;
  26.   wire [7:0]   RAM_HOUR_A;

  27.      //output
  28.   wire [15:0]  CHANNEL1_RAM_DATA;
  29.   wire         CHANNEL1_RAM1_WR_CLK;
  30.   wire [7:0]   CHANNEL1_RAM1_WR_ADDR;
  31.   
  32. // connection of internal logics
  33.   assign LEDR[9:1] = fpga_led_internal;
  34.   assign stm_hw_events    = {{4{1'b0}}, SW, fpga_led_internal, fpga_debounced_buttons};
  35.   assign fpga_clk_50=CLOCK_50;
  36. ......
  37. //外加ram  1
  38. RAM_2P RAM_2P_inst(

  39.    .data       ( CHANNEL1_RAM_DATA ),
  40.         .wraddress  ( CHANNEL1_RAM1_WR_ADDR ),
  41.         .wrclock    ( CHANNEL1_RAM1_WR_CLK ),
  42.         .wren       ( 1'b1 ),
  43.         
  44.         .rdaddress  (ram_out_address),
  45.         .rdclock    (ram_out_rdclock),
  46.         .q          (ram_out_readdata)
  47. );
  48. ......
  49. reg [25:0] counter;  
  50. reg  led_level;
  51. always @(posedge fpga_clk_50 or negedge hps_fpga_reset_n)
  52. begin
  53. if(~hps_fpga_reset_n)
  54. begin
  55.                 counter<=0;
  56.                 led_level<=0;
  57. end

  58. else if(counter==24999999)
  59.         begin
  60.                 counter<=0;
  61.                 led_level<=~led_level;
  62.         end
  63. else
  64.                 counter<=counter+1'b1;
  65. end

  66. assign LEDR[0]=led_level;
  67. endmodule
复制代码

代码太长,选择了关键部分截取。

要调用的pid_controller.vhd
  1. library IEEE;
  2. use IEEE.STD_LOGIC_1164.ALL;
  3. use IEEE.STD_LOGIC_ARITH.ALL;
  4. use IEEE.STD_LOGIC_UNSIGNED.ALL;

  5. entity pid_controller is

  6.    generic
  7.       (
  8.             -- size of input and output data --
  9.             iDataWidith    : integer range 8 to 32 := 8;
  10.             -- proportionally gain --
  11.             iKP            : integer range 0 to 7  := 3;  -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256
  12.             -- integral gain --
  13.             iKI            : integer range 0 to 7  := 2;  -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256
  14.             -- differential gain --
  15.             iKD            : integer range 0 to 7  := 2;  -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256
  16.             -- master gain --
  17.             iKM            : integer range 0 to 7  := 1;  -- 0 - /1, 1 - /2, 2 - /4, 3 - /8 , 4 - /16, 5 - /32, 6 - /64 , 7 - /128
  18.             -- delay between samples of error --
  19.             iDelayD        : integer range 1 to 16 := 10;
  20.             -- 0 - controller use derivative of PATERN_I and PATERN_ESTIMATION_I, 1 - controller use error to work --
  21.             iWork          : integer range 0 to 1  := 1   
  22.             );

  23.    port
  24.       (
  25.             CLK_I               : in  std_logic;
  26.             RESET_I             : in  std_logic;
  27.             -- error  --
  28.             ERROR_I             : in  std_logic_vector(iDataWidith - 1 downto 0);
  29.             -- threshold --
  30.             PATERN_I            : in  std_logic_vector(iDataWidith - 1 downto 0);
  31.             -- current sample --
  32.             PATERN_ESTIMATION_I : in  std_logic_vector(iDataWidith - 1 downto 0);
  33.             -- correction --
  34.             CORRECT_O           : out std_logic_vector(iDataWidith - 1 downto 0)
  35.             );
  36.    
  37. end entity pid_controller;

  38. architecture rtl of pid_controller is
  39. ---------------------------------------------------------------------------
  40. -- purpose: make a std_logic_vector of size c_size and build from c_value --
  41.    function f_something ( constant c_size : integer; signal c_value : std_logic) return std_logic_vector is

  42.       variable var_temp : std_logic_vector(c_size - 1 downto 0);
  43.       
  44.    begin  -- function f_something --

  45.       var_temp := (others => c_value);

  46.       return var_temp;
  47.       
  48.    end function f_something;

  49. -------------------------------------------------------------------------------
  50.    -- delay register --
  51.    type type_sr is array (0 to iDelayD - 1) of std_logic_vector(iDataWidith - 1 downto 0);
  52.    
  53. -------------------------------------------------------------------------------
  54. -- signals --
  55. -------------------------------------------------------------------------------
  56.    signal v_error    : std_logic_vector(iDataWidith - 1 downto 0);
  57.    signal v_error_KM : std_logic_vector(iDataWidith - 1 downto 0);
  58.    signal v_error_KP : std_logic_vector(iDataWidith - 1 downto 0);
  59.    signal v_error_KD : std_logic_vector(iDataWidith - 1 downto 0);
  60.    signal v_error_KI : std_logic_vector(iDataWidith - 1 downto 0);
  61.    signal t_div_late : type_sr;
  62.    signal v_div      : std_logic_vector(iDataWidith - 1 downto 0);
  63.    signal v_acu_earl : std_logic_vector(iDataWidith - 1 downto 0);
  64.    signal v_acu      : std_logic_vector(iDataWidith - 1 downto 0);
  65.    signal v_sum      : std_logic_vector(iDataWidith - 1 downto 0);
  66.    
  67. begin  -- architecture rtl --

  68. -- choice source of input data --
  69.    v_error <= ERROR_I                                                                             when iWork = 1 else
  70.               conv_std_logic_vector(signed(PATERN_I) - signed(PATERN_ESTIMATION_I) , iDataWidith) when iWork = 0 else
  71.               (others => '0');
  72. -- master gain execute by shift of iKM bits to the right --
  73.    v_error_KM <= v_error                                                                                                when iKM = 0 else
  74.                  f_something(c_size => iKM , c_value => v_error(iDataWidith - 1)) & v_error(iDataWidith - 1 downto iKM) when iKM > 0 else
  75.                  (others => '0');
  76.    
  77. -- proportionally gain execute by shift of (iKP - 1) bits to the right --
  78.    v_error_KP <= f_something(c_size => iKP + 1 , c_value => v_error_KM(iDataWidith - 1)) & v_error_KM(iDataWidith - 1 downto iKP + 1);
  79.    
  80. -- derivative gain execute by shift of (iKD - 1) bits to the right --
  81.    v_error_KD <= f_something(c_size => iKD + 1 , c_value => v_error_KM(iDataWidith - 1)) & v_error_KM(iDataWidith - 1 downto iKD + 1);
  82.    
  83. -- integral gain execute by shift of (iKI + 1) bits to the right --
  84.    v_error_KI <= f_something(c_size => iKI + 1 , c_value => v_error_KM(iDataWidith - 1)) & v_error_KM(iDataWidith - 1 downto iKI + 1);

  85.    DI00: process (CLK_I) is
  86.    begin  -- process DI00

  87.       if rising_edge(CLK_I) then

  88.          -- synchronous reset --
  89.          if RESET_I = '1' then

  90.             t_div_late <= (others => (others => '0'));
  91.             v_div      <= (others => '0');
  92.             v_acu      <= (others => '0');
  93.             v_acu_earl <= (others => '0');

  94.          else

  95.             -- delay register --
  96.             t_div_late <= v_error_KD & t_div_late(0 to iDelayD - 2);

  97.             -- difference between samples --
  98.             v_div <= conv_std_logic_vector(signed(v_error_KD) - signed(t_div_late(iDelayD - 1)) , iDataWidith);

  99.             -- integration of error --
  100.             v_acu <= conv_std_logic_vector(signed(v_error_KI) + signed(v_acu_earl) , iDataWidith);
  101.             -- sum of N - 1 samples of error --
  102.             v_acu_earl <= v_acu;
  103.             
  104.             
  105.          end if;
  106.          
  107.       end if;
  108.       
  109.    end process DI00;

  110.    -- first stage of adder --
  111.    v_sum <= conv_std_logic_vector(signed(v_acu) + signed(v_div) , iDataWidith);
  112.    -- correction and second stage of adder --
  113.    CORRECT_O <= conv_std_logic_vector(signed(v_error_KP) + signed(v_sum) , iDataWidith) when RESET_I  = '0' else
  114.                 (others => '0');
  115.    
  116. end architecture rtl;
复制代码

已经试过的方法:在顶层文件中用 `include 调用,但是两种语言语法有差别未成功。

最终目的:在工程编译成功的前提下,实现在modelsim中的仿真(需能编写test bench文件)。

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。