您如何在VHDL中适当地乘以std_logic:vector?

问题描述 投票:0回答:1

因此,我正在尝试做一个模块来操纵sg90伺服电机。但是我在架构的一部分上遇到了问题。该模块有一个6位的条目,其中控制着我希望伺服电机位于的位置,但是使用16位矢量来控制电机。我这样做的方法是将6位变量(与条目具有相同的值)相乘,然后将其放在16位输出向量上,如下所示:

case position is
                    when "000000" =>
                        value:= X"0ccc";
                    when "111111" =>
                        value := X"1999";
                    when others =>
                        value:=std_logic_vector((control*52)+3276);

                end case; 

例如,如果我输入“ 000000”,输出将为“ 0ccc”,从而将伺服电动机置于其起始位置。 “ 111111”应为“ 1999”,或者该表达式应考虑的其他位置之间的结束位置。但是,我收到以下错误:Error (10327): VHDL error at ServomotorF.vhd(46): can't determine definition of operator ""*"" -- found 0 possible definitions

如果有帮助,我正在使用的库是

use ieee.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

我也尝试使用numeric_std,但这只会给我带来更多错误。我能想到的唯一其他解决方案是使用大型案例结构一个接一个地进行。

如果我使用“ unsigned”,则会出现多个unsigned的错误。

vhdl quartus intel-fpga
1个回答
-1
投票

它的数学很简单:

value_out <= value_in * STEP_SIZE + MIN_VALUE_OUT;

但是从本质上讲,VHDL需要更多的努力:

constant MIN_VALUE_OUT: natural := 3276;
constant MAX_VALUE_OUT: natural := 7696;
constant MIN_VALUE_IN: natural := 0;
constant MAX_VALUE_IN: natural := 63;
constant STEP_SIZE: natural := natural(real(MAX_VALUE_OUT - MIN_VALUE_OUT) / real(MAX_VALUE_OUT));
signal std_in, std_out: std_logic_vector(5 downto 0);
signal value_in, value_out: natural;

value_in <= to_integer(unsigned(std_in));
value_out <= value_in * STEP_SIZE + MIN_VALUE_OUT;
std_out <= std_logic_vector(to_unsigned(value_out, std_out'length));

下面是VHDL中缩放器的完整实现。

比例

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

entity Scale is
    generic
    (
        MIN_VALUE_IN: natural := 0;
        MAX_VALUE_IN: natural := 63;
        MIN_VALUE_OUT: natural := 3276;
        MAX_VALUE_OUT: natural := 7696
    );
    port
    (
        value_in: in natural range MIN_VALUE_IN to MAX_VALUE_IN;
        value_out: out natural range MIN_VALUE_OUT to MAX_VALUE_OUT
    );
end entity;

architecture V1 of Scale is

    constant STEP_SIZE: natural := natural(real(MAX_VALUE_OUT - MIN_VALUE_OUT) / real(MAX_VALUE_OUT));

begin

    value_out <= value_in * STEP_SIZE + MIN_VALUE_OUT;

end architecture;

测试台

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

entity Scale_TB is
end entity;

architecture V1 of Scale_TB is

    constant SYS_CLOCK_FREQ: real := 100000000.0;  -- Hz
    constant SYS_CLOCK_PERIOD: time := 1.0 sec / SYS_CLOCK_FREQ;

    signal halt_sys_clock: boolean := false;
    signal sys_clock: std_logic := '0';

    constant MIN_VALUE_OUT: natural := 3276;
    constant MAX_VALUE_OUT: natural := 7696;
    constant MIN_VALUE_IN: natural := 0;
    constant MAX_VALUE_IN: natural := 63;
    signal position: natural range MIN_VALUE_IN to MAX_VALUE_IN;
    signal servo_pos: natural;

    component Scale is
        generic
        (
            MIN_VALUE_IN: natural := 0;
            MAX_VALUE_IN: natural := 63;
            MIN_VALUE_OUT: natural := 3276;
            MAX_VALUE_OUT: natural := 7696
        );
        port
        (
            value_in: in natural range 0 to 63;
            value_out: out natural range MIN_VALUE_OUT to MAX_VALUE_OUT
        );
    end component;

begin

    SysClockGenerator: process
    begin
        while not halt_sys_clock loop
            sys_clock <= '1';
            wait for SYS_CLOCK_PERIOD / 2.0;
            sys_clock <= '0';
            wait for SYS_CLOCK_PERIOD / 2.0;
        end loop;
        wait;
    end process SysClockGenerator;

    StimulusProcess: process
    begin
        for i in MIN_VALUE_IN to MAX_VALUE_IN loop
            position <= i;
            wait for SYS_CLOCK_PERIOD;
        end loop;

        wait for SYS_CLOCK_PERIOD;
        halt_sys_clock <= true;

        wait;
    end process;

    DUT: Scale
        generic map
        (
            MIN_VALUE_IN => MIN_VALUE_IN,
            MAX_VALUE_IN => MAX_VALUE_IN,
            MIN_VALUE_OUT => MIN_VALUE_OUT,
            MAX_VALUE_OUT => MAX_VALUE_OUT
        )
        port map
        (
            value_in => position,
            value_out => servo_pos
        );

end architecture;

模拟

enter image description here

RTL

enter image description here

发布映射

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.