问题描述:DE10-nano板提供的工程顶层文件是verilog写的,自己编写了一个PID程序是用VHDL写的。现在要把PID放到工程中编译并使用modelsim
仿真。如何操作?
顶层文件DE10_Standard_GHRD.v:
- `define ENABLE_HPS
- //`define ENABLE_HSMC
- module DE10_Standard_GHRD(
- ///////// CLOCK /////////
- input CLOCK2_50,
- input CLOCK3_50,
- input CLOCK4_50,
- input CLOCK_50,
- ///////// KEY /////////
- input [ 3: 0] KEY,
- ......
- wire hps_FPGA_reset_n;
- wire [3:0] fpga_debounced_buttons;
- wire [8:0] fpga_led_internal;
- wire [2:0] hps_reset_req;
- wire hps_cold_reset;
- wire hps_wARM_reset;
-
- //ram_driver3_0
- //input
-
- wire FCLK_5M;
- wire CHANNEL1_RAM_LOAD;
- wire [15:0] RAM_MS_A;
- wire [7:0] RAM_S_A;
- wire [7:0] RAM_MIN_A;
- wire [7:0] RAM_HOUR_A;
- //output
- wire [15:0] CHANNEL1_RAM_DATA;
- wire CHANNEL1_RAM1_WR_CLK;
- wire [7:0] CHANNEL1_RAM1_WR_ADDR;
-
- // connection of internal logics
- assign LEDR[9:1] = fpga_led_internal;
- assign stm_hw_events = {{4{1'b0}}, SW, fpga_led_internal, fpga_debounced_buttons};
- assign fpga_clk_50=CLOCK_50;
- ......
- //外加ram 1
- RAM_2P RAM_2P_inst(
- .data ( CHANNEL1_RAM_DATA ),
- .wraddress ( CHANNEL1_RAM1_WR_ADDR ),
- .wrclock ( CHANNEL1_RAM1_WR_CLK ),
- .wren ( 1'b1 ),
-
- .rdaddress (ram_out_address),
- .rdclock (ram_out_rdclock),
- .q (ram_out_readdata)
- );
- ......
- reg [25:0] counter;
- reg led_level;
- always @(posedge fpga_clk_50 or negedge hps_fpga_reset_n)
- begin
- if(~hps_fpga_reset_n)
- begin
- counter<=0;
- led_level<=0;
- end
- else if(counter==24999999)
- begin
- counter<=0;
- led_level<=~led_level;
- end
- else
- counter<=counter+1'b1;
- end
- assign LEDR[0]=led_level;
- endmodule
复制代码
代码太长,选择了关键部分截取。
要调用的pid_controller.vhd
- library IEEE;
- use IEEE.STD_LOGIC_1164.ALL;
- use IEEE.STD_LOGIC_ARITH.ALL;
- use IEEE.STD_LOGIC_UNSIGNED.ALL;
- entity pid_controller is
- generic
- (
- -- size of input and output data --
- iDataWidith : integer range 8 to 32 := 8;
- -- proportionally gain --
- iKP : integer range 0 to 7 := 3; -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256
- -- integral gain --
- iKI : integer range 0 to 7 := 2; -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256
- -- differential gain --
- iKD : integer range 0 to 7 := 2; -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256
- -- master gain --
- iKM : integer range 0 to 7 := 1; -- 0 - /1, 1 - /2, 2 - /4, 3 - /8 , 4 - /16, 5 - /32, 6 - /64 , 7 - /128
- -- delay between samples of error --
- iDelayD : integer range 1 to 16 := 10;
- -- 0 - controller use derivative of PATERN_I and PATERN_ESTIMATION_I, 1 - controller use error to work --
- iWork : integer range 0 to 1 := 1
- );
- port
- (
- CLK_I : in std_logic;
- RESET_I : in std_logic;
- -- error --
- ERROR_I : in std_logic_vector(iDataWidith - 1 downto 0);
- -- threshold --
- PATERN_I : in std_logic_vector(iDataWidith - 1 downto 0);
- -- current sample --
- PATERN_ESTIMATION_I : in std_logic_vector(iDataWidith - 1 downto 0);
- -- correction --
- CORRECT_O : out std_logic_vector(iDataWidith - 1 downto 0)
- );
-
- end entity pid_controller;
- architecture rtl of pid_controller is
- ---------------------------------------------------------------------------
- -- purpose: make a std_logic_vector of size c_size and build from c_value --
- function f_something ( constant c_size : integer; signal c_value : std_logic) return std_logic_vector is
- variable var_temp : std_logic_vector(c_size - 1 downto 0);
-
- begin -- function f_something --
- var_temp := (others => c_value);
- return var_temp;
-
- end function f_something;
- -------------------------------------------------------------------------------
- -- delay register --
- type type_sr is array (0 to iDelayD - 1) of std_logic_vector(iDataWidith - 1 downto 0);
-
- -------------------------------------------------------------------------------
- -- signals --
- -------------------------------------------------------------------------------
- signal v_error : std_logic_vector(iDataWidith - 1 downto 0);
- signal v_error_KM : std_logic_vector(iDataWidith - 1 downto 0);
- signal v_error_KP : std_logic_vector(iDataWidith - 1 downto 0);
- signal v_error_KD : std_logic_vector(iDataWidith - 1 downto 0);
- signal v_error_KI : std_logic_vector(iDataWidith - 1 downto 0);
- signal t_div_late : type_sr;
- signal v_div : std_logic_vector(iDataWidith - 1 downto 0);
- signal v_acu_earl : std_logic_vector(iDataWidith - 1 downto 0);
- signal v_acu : std_logic_vector(iDataWidith - 1 downto 0);
- signal v_sum : std_logic_vector(iDataWidith - 1 downto 0);
-
- begin -- architecture rtl --
- -- choice source of input data --
- v_error <= ERROR_I when iWork = 1 else
- conv_std_logic_vector(signed(PATERN_I) - signed(PATERN_ESTIMATION_I) , iDataWidith) when iWork = 0 else
- (others => '0');
- -- master gain execute by shift of iKM bits to the right --
- v_error_KM <= v_error when iKM = 0 else
- f_something(c_size => iKM , c_value => v_error(iDataWidith - 1)) & v_error(iDataWidith - 1 downto iKM) when iKM > 0 else
- (others => '0');
-
- -- proportionally gain execute by shift of (iKP - 1) bits to the right --
- v_error_KP <= f_something(c_size => iKP + 1 , c_value => v_error_KM(iDataWidith - 1)) & v_error_KM(iDataWidith - 1 downto iKP + 1);
-
- -- derivative gain execute by shift of (iKD - 1) bits to the right --
- v_error_KD <= f_something(c_size => iKD + 1 , c_value => v_error_KM(iDataWidith - 1)) & v_error_KM(iDataWidith - 1 downto iKD + 1);
-
- -- integral gain execute by shift of (iKI + 1) bits to the right --
- v_error_KI <= f_something(c_size => iKI + 1 , c_value => v_error_KM(iDataWidith - 1)) & v_error_KM(iDataWidith - 1 downto iKI + 1);
- DI00: process (CLK_I) is
- begin -- process DI00
- if rising_edge(CLK_I) then
- -- synchronous reset --
- if RESET_I = '1' then
- t_div_late <= (others => (others => '0'));
- v_div <= (others => '0');
- v_acu <= (others => '0');
- v_acu_earl <= (others => '0');
- else
- -- delay register --
- t_div_late <= v_error_KD & t_div_late(0 to iDelayD - 2);
- -- difference between samples --
- v_div <= conv_std_logic_vector(signed(v_error_KD) - signed(t_div_late(iDelayD - 1)) , iDataWidith);
- -- integration of error --
- v_acu <= conv_std_logic_vector(signed(v_error_KI) + signed(v_acu_earl) , iDataWidith);
- -- sum of N - 1 samples of error --
- v_acu_earl <= v_acu;
-
-
- end if;
-
- end if;
-
- end process DI00;
- -- first stage of adder --
- v_sum <= conv_std_logic_vector(signed(v_acu) + signed(v_div) , iDataWidith);
- -- correction and second stage of adder --
- CORRECT_O <= conv_std_logic_vector(signed(v_error_KP) + signed(v_sum) , iDataWidith) when RESET_I = '0' else
- (others => '0');
-
- end architecture rtl;
复制代码
已经试过的方法:在顶层文件中用 `include 调用,但是两种语言语法有差别未成功。
最终目的:在工程编译成功的前提下,实现在modelsim中的仿真(需能编写test bench文件)。
一周热门 更多>