altera/MainController/RAM9X8_Peripheral.vhd

292 lines
7.7 KiB
VHDL
Raw Normal View History

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;