library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; USE ieee.std_logic_unsigned.all; entity ATAmem is port( clk: in std_logic; -- master clock input rst: in std_logic; -- active-high reset done: in std_logic; -- operation complete from ATAcntl dIn: in std_logic_vector(15 downto 0); -- data from ATAcntl rd: out std_logic; -- read control signal to ATAcntl wr: out std_logic; -- write control signal to ATAcntl abort: out std_logic; -- read/write sector abort to ATAcntl lba_mode : out std_logic; sector_number : out std_logic_vector(27 downto 0); dOut: out std_logic_vector(15 downto 0); -- data to ATAcntl busy : out std_logic_vector(7 downto 0); sector_wanted : in std_logic_vector(27 downto 0); lba_mode_wanted : std_logic; init_read : in std_logic; init_write : in std_logic; addr: in std_logic_vector(8 downto 0); -- Atmel access to buffer Qmem : in std_logic_vector(7 downto 0); Dmem : out std_logic_vector(7 downto 0); wren : in std_logic ); end ATAmem; architecture arch of ATAmem is component sector_buff PORT ( data_a : IN STD_LOGIC_VECTOR (15 DOWNTO 0); wren_a : IN STD_LOGIC := '1'; address_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0); data_b : IN STD_LOGIC_VECTOR (7 DOWNTO 0); address_b : IN STD_LOGIC_VECTOR (8 DOWNTO 0); wren_b : IN STD_LOGIC := '1'; clock : IN STD_LOGIC ; q_a : OUT STD_LOGIC_VECTOR (15 DOWNTO 0); q_b : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) ); end component; -- states of the memory tester state machine type testState is ( IDLE, READ_SECTOR, WRITE_SECTOR ); signal state_r: testState; -- state register and next state signal wren_buffer, intern_rd: std_logic; signal addr_r: std_logic_vector(7 downto 0); -- address register begin sector_buff_inst : sector_buff PORT MAP ( clock => clk, address_a => addr_r, wren_a => wren_buffer, data_a => dIn, q_a => dOut, address_b => addr, wren_b => wren, data_b => Qmem, q_b => Dmem ); rd <= intern_rd; wren_buffer <= intern_rd and done; sector_number <= sector_wanted; lba_mode <= lba_mode_wanted; -- state machine operations state_machine: process(state_r,addr_r,done, init_read, init_write, rst, clk) begin if rst = '1' then intern_rd <= '0'; wr <= '0'; abort <= '1'; addr_r <= x"00"; busy <= x"00"; state_r <= IDLE; elsif rising_edge(clk) then case state_r is when IDLE => addr_r <= x"00"; intern_rd <= '0'; wr <= '0'; abort <= '0'; busy <= x"00"; if init_read = '1' then state_r <= READ_SECTOR; elsif init_write = '1' then state_r <= WRITE_SECTOR; else state_r <= IDLE; end if; when READ_SECTOR => busy <= dIn(6 downto 0)&'1'; wr <= '0'; if done = '0' then intern_rd <= '1'; -- la lecture n'est pas encore faite, on change rien abort <= '0'; else intern_rd <= '0'; addr_r <= addr_r + "00000001"; if addr_r = x"FF" then state_r <= IDLE; -- on vient de lire la dernière, c'est fini abort <= '1'; else state_r <= READ_SECTOR; abort <= '0'; end if; end if; when WRITE_SECTOR => busy <= addr_r(6 downto 0)&'1'; intern_rd <= '0'; if done = '0' then wr <= '1'; -- l'écriture n'est pas encore faite, on change rien abort <= '0'; else wr <= '0'; addr_r <= addr_r + "00000001"; if addr_r = x"FF" then abort <= '1'; state_r <= IDLE; else abort <= '0'; state_r <= WRITE_SECTOR; end if; end if; end case; end if; end process; end arch;