|
发表于 2011-5-25 22:35:26
|
显示全部楼层
ENTITY can_ctrl IS
port(
clk : in std_logic;
reset : in std_logic;
--15个io,还有一个中断io自己控制
data :inout std_logic_vector(7 downto 0);
ale :out std_logic:='0';
nrd :out std_logic:='1';
nwr :out std_logic:='1';
ncs :out std_logic:='1';
rst :out std_logic:='0';
data_dir :out std_logic:='0';
noe :out std_logic;
--下面的是和你的控制逻辑交互的
r_state_in :in std_logic;
r_state_out :out std_logic;
w_state_in :in std_logic;
w_state_out :out std_logic;
rw_addr :in std_logic_vector(7 downto 0);
rw_data_in :in std_logic_vector(7 downto 0);
rw_data_out :out std_logic_vector(7 downto 0);
);
END ENTITY can_ctrl;
ARCHITECTURE active OF can_ctrl IS
signal data_out :std_logic_vector(7 downto 0);
signal data_in :std_logic_vector(7 downto 0);
signal data_out_en :std_logic;
signal data_temp :std_logic_vector(7 downto 0);
signal av_r_state_out,av_w_state_out : std_logic;
signal av_addr :std_logic_vector(7 downto 0);
type states is(idle,read,write);
signal current_state:states;
signal next_state : states;
signal count :std_logic_vector(3 downto 0);
BEGIN
r_state_out <= av_r_state_out;
w_state_out <= av_w_state_out;
rst <= reset;
data_in <= data;
data <= data_out when data_out_en = '1' else (others => 'Z');
process(clk,reset)
begin
if reset = '0' then
current_state <= idle;
else
if rising_edge(clk) then
current_state <= next_state;
end if;
end if;
end process;
process(r_state_in,w_state_in,count)
begin
case current_state is
when idle =>
if r_state_in = '1' then
next_state <= read;
elsif w_state_in = '1' then
next_state <= write;
else
next_state <= idle;
end if;
when read =>
if count = "1111" then
next_state <= idle;
else
next_state <= read;
end if;
when write =>
if count = "1111" then
next_state <= idle;
else
next_state <= write;
end if;
when others => next_state <= idle;
end case;
end process;
process(clk,reset)
begin
if rising_edge(clk) then
if reset = '0' then
ale <= '0';
nrd <= '1';
nwr <= '1';
ncs <= '1';
data_dir <= '0';
noe <= '1';
data_out_en <= '0';
av_r_state_out <= '0';
av_w_state_out <= '0';
count <= "0000";
else
case current_state is
when idle =>
ale <= '0';
nrd <= '1';
nwr <= '1';
ncs <= '1';
data_dir <= '0';
noe <= '1';
data_out_en <= '0';
count <= "0000";
when read =>
noe <= '0';
nwr <= '1';
case count is
when "0000" =>
data_out <= rw_addr;
data_out_en <= '1';
data_dir <= '1';
nrd <= '1';
ncs <= '0';
count <= count + "0001";
when "0001" | "0010" | "0011" | "0100" =>
ale <= '1';
count <= count + "0001";
when "0101" =>
ale <= '0';
count <= count + "0001";
when "0110" =>
count <= count + "0001";
data_out_en <= '0';
data_dir <= '0';
when "0111"|"1000"|"1001"|"1010" =>
count <= count + "0001";
nrd <= '0';
when "1011" =>
rw_data_out <= data_in;
count <= count + "0001";
when "1100" =>
nrd <= '1';
count <= count + "0001";
when "1101"| "1110" =>
ncs <= '1';
count <= count + "0001";
when "1111" =>
av_r_state_out <= '1';
when others =>
null;
end case;
when write =>
noe <= '0';
nrd <= '1';
case count is
when "0000" =>
data_out <= rw_addr;
data_out_en <= '1';
data_dir <= '1';
nwr <= '1';
ncs <= '0';
count <= count + "0001";
when "0001" | "0010" | "0011" | "0100" =>
ale <= '1';
count <= count + "0001";
when "0101" =>
ale <= '0';
count <= count + "0001";
when "0110" =>
data_out_en <= '0';
count <= count + "0001";
when "0111"|"1000"|"1001"|"1010" =>
nwr <= '0';
data_out <= rw_data_in;
data_out_en <= '1';
count <= count + "0001";
when "1011" =>
nwr <= '1';
count <= count + "0001";
when "1100" =>
ncs <= '1';
count <= count + "0001";
when "1101" =>
data_out_en <= '0';
count <= count + "0001";
when "1110" =>
count <= count + "0001";
when "1111" =>
av_w_state_out <= '1';
when others =>
null;
end case;
when others =>
null;
end case;
if av_r_state_out = '1' then
av_r_state_out <= '0';
end if;
if av_w_state_out = '1' then
av_w_state_out <= '0';
end if;
end if; --end reset
end if;--end clk
end process;
END ARCHITECTURE active; |
|