altera/MainController/RAM9X8_Peripheral.vhd

292 lines
7.7 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.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity RAM9X8_Peripheral is
generic(
PER_BASE_ADDRESS : integer := 40;
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;
asyncline : out std_logic := '1';
divclk : out std_logic := '1';
error : in std_logic;
init : in std_logic
);
end entity;
architecture behavorial of RAM9X8_Peripheral is
signal PER_ACTIVE_DEVICE_LOWER : integer := PER_BASE_ADDRESS;
signal PER_ACTIVE_DEVICE_UPPER : integer := PER_BASE_ADDRESS + 1;
signal PER_REZERVED_1_LOWER : integer := PER_BASE_ADDRESS + 2;
signal PER_REZERVED_1_UPPER : integer := PER_BASE_ADDRESS + 3;
signal PER_REZERVED_2_LOWER : integer := PER_BASE_ADDRESS + 4;
signal PER_REZERVED_2_UPPER : integer := PER_BASE_ADDRESS + 5;
signal activeDeviceBuf : std_logic_vector(15 downto 0) := (others => '0');
signal rezerved1Buf : std_logic_vector(15 downto 0) := (others => '0');
signal rezerved2Buf : std_logic_vector(15 downto 0) := (others => '0');
signal divClkBuf : std_logic := '0';
signal divClkBufPWM : std_logic := '0';
signal addrBuf : std_logic_vector(3 downto 0) := (others => '0');
signal LedState : std_logic_vector(1 downto 0) := (others => '0');
type BusSt is (Waiting, A3, A2, A1, A0, Dt, Finish);
signal BusState : BusSt := Waiting;
signal countBuf : std_logic_vector(3 downto 0) := (others => '0');
signal countBufPWM : std_logic_vector(3 downto 0) := (others => '0');
begin
process (we, oe, ce)
variable addr : integer range 0 to 2**ADDRESS_BUS_WIDTH - 1 := 0;
begin
if (ce = '0') then -- Если микросхема выбрана
addr := conv_integer(address);
if (addr = PER_ACTIVE_DEVICE_UPPER or addr = PER_ACTIVE_DEVICE_LOWER
or addr = PER_REZERVED_1_UPPER or addr = PER_REZERVED_1_LOWER
or addr = PER_REZERVED_2_UPPER or addr = PER_REZERVED_2_LOWER) then
if (oe = '0' and we = '1') then -- Если сигнал чтения активен, а записи нет
case addr is
when PER_ACTIVE_DEVICE_UPPER =>
data <= activeDeviceBuf(15 downto 8);
when PER_ACTIVE_DEVICE_LOWER =>
data <= activeDeviceBuf(7 downto 0);
when PER_REZERVED_1_UPPER =>
data <= rezerved1Buf(15 downto 8);
when PER_REZERVED_1_LOWER =>
data <= rezerved1Buf(7 downto 0);
when PER_REZERVED_2_UPPER =>
data <= rezerved2Buf(15 downto 8);
when PER_REZERVED_2_LOWER =>
data <= rezerved2Buf(7 downto 0);
when others =>
data <= (others => 'Z'); -- Запретить запись на шину
end case;
elsif (oe = '1' and we = '0') then -- Если сигнал записи активен, а чтения нет
case addr is
when PER_ACTIVE_DEVICE_UPPER =>
activeDeviceBuf(15 downto 8) <= data;
when PER_ACTIVE_DEVICE_LOWER =>
activeDeviceBuf(7 downto 0) <= data;
when PER_REZERVED_1_UPPER =>
rezerved1Buf(15 downto 8) <= data;
when PER_REZERVED_1_LOWER =>
rezerved1Buf(7 downto 0) <= data;
when PER_REZERVED_2_UPPER =>
rezerved2Buf(15 downto 8) <= data;
when PER_REZERVED_2_LOWER =>
rezerved2Buf(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 count50000 : integer range 0 to 50000 := 0;
variable count50 : integer range 0 to 50 := 0;
begin
if rising_edge(clk) then
if count50000 < 50000 then
count50000 := count50000 + 1;
else
divClkBufPWM <= not divClkBufPWM;
count50000 := 0;
if count50 < 50 then
count50 := count50 + 1;
else
count50 := 0;
divClkBuf <= not divClkBuf;
end if;
end if;
end if;
end process;
process(divClkBufPWM) is
begin
if conv_integer(countBufPWM) < 15 then
countBufPWM <= conv_std_logic_vector(conv_integer(countBufPWM) + 1, 4);
else
countBufPWM <= (others => '0');
end if;
end process;
process(divClkBuf) is
variable direction : integer range 0 to 1 := 0;
begin
if direction = 0 then
if conv_integer(countBuf) < 15 then
countBuf <= conv_std_logic_vector(conv_integer(countBuf) + 1, 4);
else
direction := 1;
end if;
else
if conv_integer(countBuf) > 0 then
countBuf <= conv_std_logic_vector(conv_integer(countBuf) - 1, 4);
else
direction := 0;
end if;
end if;
end process;
process(divClkBuf) is
variable count15 : integer range 0 to 15 := 0;
begin
case LedState is
when b"00" =>
if count15 < 15 then
count15 := count15 + 1;
else
count15 := 0;
LedState <= b"01";
end if;
divclk <= '0';
when b"01" =>
if count15 < 7 then
count15 := count15 + 1;
else
count15 := 0;
LedState <= b"10";
end if;
divclk <= '1';
when b"10" =>
if count15 < 15 then
count15 := count15 + 1;
else
count15 := 0;
LedState <= b"11";
end if;
divclk <= '0';
when b"11" =>
if count15 < 4 then
count15 := count15 + 1;
else
count15 := 0;
LedState <= b"00";
end if;
divclk <= '1';
when others =>
LedState <= b"00";
end case;
end process;
process(clk) is
variable count50 : integer range 0 to 50 := 0;
variable count15 : integer range 0 to 15 := 15;
begin
if rising_edge(clk) then
if init = '0' then
case BusState is
when Waiting =>
if count50 < 38 then
count50 := count50 + 1;
else
if count15 < 15 then
count15 := count15 + 1;
else
count15 := 0;
end if;
if activeDeviceBuf(count15) = '1' then
addrBuf <= conv_std_logic_vector(count15, 4);
asyncline <= '0';
count50 := 0;
BusState <= A3;
end if;
end if;
when A3 =>
if count50 < 18 then
count50 := count50 + 1;
else
count50 := 0;
asyncline <= addrBuf(3);
BusState <= A2;
end if;
when A2 =>
if count50 < 38 then
count50 := count50 + 1;
else
count50 := 0;
asyncline <= addrBuf(2);
BusState <= A1;
end if;
when A1 =>
if count50 < 38 then
count50 := count50 + 1;
else
count50 := 0;
asyncline <= addrBuf(1);
BusState <= A0;
end if;
when A0 =>
if count50 < 38 then
count50 := count50 + 1;
else
count50 := 0;
asyncline <= addrBuf(0);
BusState <= Dt;
end if;
when Dt =>
if count50 < 38 then
count50 := count50 + 1;
else
count50 := 0;
asyncline <= divClkBuf;
BusState <= Finish;
end if;
when Finish =>
if count50 < 38 then
count50 := count50 + 1;
else
count50 := 0;
asyncline <= '1';
BusState <= Finish;
end if;
when others =>
BusState <= Waiting;
count50 := 0;
count15 :=15;
end case;
else
BusState <= Waiting;
count50 := 0;
count15 := 15;
if error = '0' then
if countBuf < countBufPWM then
asyncline <= '1';
else
asyncline <= '0';
end if;
else
asyncline <= '1';
end if;
end if;
end if;
end process;
end behavorial;