altera/MainController/RAM9X8_PWM.vhd

208 lines
8.3 KiB
VHDL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

entity RAM9X8_PWM is
generic(
REG_ADDR_MODE_CONTROL_UPPER_BYTE : integer := 14;
REG_ADDR_MODE_CONTROL_LOWER_BYTE : integer := 15;
REG_ADDR_MASK_2_UPPER_BYTE : integer := 16;
REG_ADDR_MASK_2_LOWER_BYTE : integer := 17;
REG_ADDR_MASK_1_UPPER_BYTE : integer := 18;
REG_ADDR_MASK_1_LOWER_BYTE : integer := 19;
REG_ADDR_DIRECT_CONTROL_2_UPPER_BYTE : integer := 20;
REG_ADDR_DIRECT_CONTROL_2_LOWER_BYTE : integer := 21;
REG_ADDR_DIRECT_CONTROL_1_UPPER_BYTE : integer := 22;
REG_ADDR_DIRECT_CONTROL_1_LOWER_BYTE : integer := 23;
REG_ADDR_PERIOD_UPPER_BYTE : integer := 24;
REG_ADDR_PERIOD_LOWER_BYTE : integer := 25;
REG_ADDR_DIRECTION_UPPER_BYTE : integer := 26;
REG_ADDR_DIRECTION_LOWER_BYTE : integer := 27;
REG_ADDR_CHANNEL_UPPER_BYTE : integer := 28;
REG_ADDR_CHANNEL_LOWER_BYTE : integer := 29;
REG_ADDR_TIMING_UPPER_BYTE : integer := 30;
REG_ADDR_TIMING_LOWER_BYTE : integer := 31;
REG_ADDR_CMD_UPPER_BYTE : integer := 32;
REG_ADDR_CMD_LOWER_BYTE : integer := 33;
REG_ADDR_CONTROL_UPPER_BYTE : integer := 34;
REG_ADDR_CONTROL_LOWER_BYTE : integer := 35;
DATA_BUS_WIDTH : integer := 8;
ADDRESS_BUS_WIDTH : integer := 9
);
port(
clk : in std_logic;
data : inout std_logic_vector(DATA_BUS_WIDTH - 1 downto 0);
address : in std_logic_vector(ADDRESS_BUS_WIDTH - 1 downto 0);
we : in std_logic;
oe : in std_logic;
ce : in std_logic;
tk : out std_logic_vector(31 downto 0) := (others => '1');
interrupt : out std_logic := '1';
pwm : in std_logic_vector(5 downto 0)
);
end entity;
architecture behavorial of RAM9X8_PWM is
signal modeBuf : std_logic_vector(15 downto 0) := (others => '0');
signal maskBuf : std_logic_vector(31 downto 0) := (others => '1');
signal directControlBuf : std_logic_vector(31 downto 0) := (others => '1');
signal periodBuf : std_logic_vector(15 downto 0) := (others => '0');
signal directionBuf : std_logic_vector(15 downto 0) := (others => '0');
signal channelBuf : std_logic_vector(15 downto 0) := (others => '0');
signal cmdBuf : std_logic_vector(15 downto 0) := (others => '0');
signal controlBuf : std_logic_vector(15 downto 0) := (others => '0');
type mem is array (15 downto 0) of std_logic_vector(15 downto 0);
signal memory : mem;
signal lineBusy : std_logic := '1';
signal start : std_logic := '0';
signal startPrev : std_logic := '0';
begin
process (we, oe, ce)
variable addr : integer range 0 to 2**ADDRESS_BUS_WIDTH - 1 := 0;
variable position : integer range 0 to ARRAY_LENGTH - 1 := 0;
begin
if (ce = '0') then -- Если микросхема выбрана
addr := conv_integer(address);
if (addr = REG_ADDR_MODE_CONTROL_UPPER_BYTE or addr = REG_ADDR_MODE_CONTROL_LOWER_BYTE
or addr = REG_ADDR_MASK_2_UPPER_BYTE or addr = REG_ADDR_MASK_2_LOWER_BYTE or addr = REG_ADDR_MASK_1_UPPER_BYTE or addr = REG_ADDR_MASK_1_LOWER_BYTE
or addr = REG_ADDR_DIRECT_CONTROL_2_UPPER_BYTE or addr = REG_ADDR_DIRECT_CONTROL_2_LOWER_BYTE or addr = REG_ADDR_DIRECT_CONTROL_1_UPPER_BYTE or addr = REG_ADDR_DIRECT_CONTROL_1_LOWER_BYTE
or addr = REG_ADDR_PERIOD_UPPER_BYTE or addr = REG_ADDR_PERIOD_LOWER_BYTE or addr = REG_ADDR_DIRECTION_UPPER_BYTE or addr = REG_ADDR_DIRECTION_LOWER_BYTE
or addr = REG_ADDR_CHANNEL_UPPER_BYTE or addr = REG_ADDR_CHANNEL_LOWER_BYTE or addr = REG_ADDR_TIMING_UPPER_BYTE or addr = REG_ADDR_TIMING_LOWER_BYTE
or addr = REG_ADDR_CMD_UPPER_BYTE or addr = REG_ADDR_CMD_LOWER_BYTE or addr = REG_ADDR_CONTROL_UPPER_BYTE or addr = REG_ADDR_CONTROL_LOWER_BYTE) then
if (oe = '0' and we = '1') then -- Если сигнал чтения активен, а записи нет
case addr is
when REG_ADDR_MODE_CONTROL_UPPER_BYTE =>
data <= modeBuf(15 downto 8);
when REG_ADDR_MODE_CONTROL_LOWER_BYTE =>
data <= modeBuf(7 downto 0);
when REG_ADDR_MASK_2_UPPER_BYTE =>
data <= maskBuf(31 downto 24);
when REG_ADDR_MASK_2_LOWER_BYTE =>
data <= maskBuf(23 downto 16);
when REG_ADDR_MASK_1_UPPER_BYTE =>
data <= maskBuf(15 downto 8);
when REG_ADDR_MASK_1_LOWER_BYTE =>
data <= maskBuf(7 downto 0);
when REG_ADDR_DIRECT_CONTROL_2_UPPER_BYTE =>
data <= directControlBuf(31 downto 24);
when REG_ADDR_DIRECT_CONTROL_2_LOWER_BYTE =>
data <= directControlBuf(23 downto 16);
when REG_ADDR_DIRECT_CONTROL_1_UPPER_BYTE =>
data <= directControlBuf(15 downto 8);
when REG_ADDR_DIRECT_CONTROL_1_LOWER_BYTE =>
data <= directControlBuf(7 downto 0);
when REG_ADDR_PERIOD_UPPER_BYTE =>
data <= periodBuf(15 downto 8);
when REG_ADDR_PERIOD_LOWER_BYTE =>
data <= periodBuf(7 downto 0);
when REG_ADDR_DIRECTION_UPPER_BYTEE =>
data <= directionBuf(15 downto 8);
when REG_ADDR_DIRECTION_LOWER_BYTE =>
data <= directionBuf(7 downto 0);
when REG_ADDR_CHANNEL_UPPER_BYTE =>
data <= channelBuf(15 downto 8);
when REG_ADDR_CHANNEL_LOWER_BYTE =>
data <= channelBuf(7 downto 0);
when REG_ADDR_TIMING_UPPER_BYTE =>
data <= memory(conv_integer(channelBuf)(15 downto 8));
when REG_ADDR_TIMING_LOWER_BYTE =>
data <= memory(conv_integer(channelBuf)(7 downto 0);
when REG_ADDR_CMD_UPPER_BYTE =>
data <= cmdBuf(15 downto 8);
when REG_ADDR_CMD_LOWER_BYTE =>
data <= cmdBuf(7 downto 0);
when REG_ADDR_CONTROL_UPPER_BYTE =>
data <= controlBuf(15 downto 8);
when REG_ADDR_CONTROL_LOWER_BYTE =>
data <= controlBuf(7 downto 0);
when others =>
data <= (others => 'Z'); -- Запретить запись на шину
end case;
elsif (oe = '1' and we = '0') then -- Если сигнал записи активен, а чтения нет
case addr is
when REG_ADDR_MODE_CONTROL_UPPER_BYTE =>
modeBuf(15 downto 8) <= data;
when REG_ADDR_MODE_CONTROL_LOWER_BYTE =>
modeBuf(7 downto 0) <= data;
when REG_ADDR_MASK_2_UPPER_BYTE =>
maskBuf(31 downto 24) <= data;
when REG_ADDR_MASK_2_LOWER_BYTE =>
maskBuf(23 downto 16) <= data;
when REG_ADDR_MASK_1_UPPER_BYTE =>
maskBuf(15 downto 8) <= data;
when REG_ADDR_MASK_1_LOWER_BYTE =>
maskBuf(7 downto 0) <= data;
when REG_ADDR_DIRECT_CONTROL_2_UPPER_BYTE =>
directControlBuf(31 downto 24) <= data;
when REG_ADDR_DIRECT_CONTROL_2_LOWER_BYTE =>
directControlBuf(23 downto 16) <= data;
when REG_ADDR_DIRECT_CONTROL_1_UPPER_BYTE =>
directControlBuf(15 downto 8) <= data;
when REG_ADDR_DIRECT_CONTROL_1_LOWER_BYTE =>
directControlBuf(7 downto 0) <= data;
when REG_ADDR_PERIOD_UPPER_BYTE =>
periodBuf(15 downto 8) <= data;
when REG_ADDR_PERIOD_LOWER_BYTE =>
periodBuf(7 downto 0) <= data;
when REG_ADDR_DIRECTION_UPPER_BYTEE =>
directionBuf(15 downto 8) <= data;
when REG_ADDR_DIRECTION_LOWER_BYTE =>
directionBuf(7 downto 0) <= data;
when REG_ADDR_CHANNEL_UPPER_BYTE =>
channelBuf(15 downto 8) <= data;
when REG_ADDR_CHANNEL_LOWER_BYTE =>
channelBuf(7 downto 0) <= data;
when REG_ADDR_TIMING_UPPER_BYTE =>
memory(conv_integer(channelBuf)(15 downto 8)) <= data;
when REG_ADDR_TIMING_LOWER_BYTE =>
memory(conv_integer(channelBuf)(7 downto 0) <= data;
when REG_ADDR_CMD_UPPER_BYTE =>
cmdBuf(15 downto 8) <= data;
when REG_ADDR_CMD_LOWER_BYTE =>
cmdBuf(7 downto 0) <= data;
when REG_ADDR_CONTROL_UPPER_BYTE =>
controlBuf(15 downto 8) <= data;
when REG_ADDR_CONTROL_LOWER_BYTE =>
controlBuf(7 downto 0) <= data;
when others =>
data <= (others => 'Z'); -- Запретить запись на шину
end case;
else
data <= (others => 'Z'); -- Запретить запись на шину
end if;;
else
data <= (others => 'Z'); -- Запретить запись на шину
end if;
else
data <= (others => 'Z'); -- Запретить запись на шину
end if;
end process;
process(clk) is
variable counter : integer range 0 to 65666 := 0;
begin
if(rising_edge clk) then
if(conv_integer(memory(0)) > counter) then
if(directionBuf(0) = '0') then
pwm3level(0) <= '0';
else
pwm3level(0) <= '1';
end if;
else
if(directionBuf(0) = '0') then
pwm3level(0) <= '1';
else
pwm3level(0) <= '0';
end if;
end if;
end process;
end behavorial;