因此,我正在尝试做一个模块来操纵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的错误。
它的数学很简单:
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;