1
0
SEm-Labos/Libs/Memory/hdl/flashController_RTL.vhd

141 lines
4.3 KiB
VHDL
Raw Permalink Normal View History

2024-02-23 13:01:05 +00:00
ARCHITECTURE RTL OF flashController IS
signal addressReg: unsigned(flashAddr'range);
signal dataOutReg: std_ulogic_vector(flashDataOut'range);
signal dataInReg: std_ulogic_vector(flashDataIn'range);
type sequenceStateType is (
idle,
waitForBus1, waitForBus0,
startAccess, waitAcccessEnd
);
signal sequenceState: sequenceStateType;
signal read: std_ulogic;
signal startCounter: std_ulogic;
signal sequenceCounter: unsigned(3 downto 0);
signal endOfCount: std_ulogic;
signal readDataValid: std_ulogic;
signal flashCE: std_ulogic;
BEGIN
------------------------------------------------------------------------------
-- memory reset
memRst_n <= not '0';
------------------------------------------------------------------------------
-- address
storeAddress: process(reset, clock)
begin
if reset = '1' then
addressReg <= (others => '0');
elsif rising_edge(clock) then
if (flashRd = '1') or (flashWr = '1') then
addressReg <= shift_left(flashAddr, 1);
end if;
end if;
end process storeAddress;
memAddress <= std_ulogic_vector(addressReg);
------------------------------------------------------------------------------
-- data out
storeDataOut: process(reset, clock)
begin
if reset = '1' then
dataOutReg <= (others => '0');
elsif rising_edge(clock) then
if flashWr = '1' then
dataOutReg <= flashDataOut;
end if;
end if;
end process storeDataOut;
memDataOut <= flashDataOut;
------------------------------------------------------------------------------
-- data in
readDataValid <= '1' when (read = '1') and (endOfCount = '1') else '0';
storeDataIn: process(reset, clock)
begin
if reset = '1' then
dataInReg <= (others => '0');
elsif rising_edge(clock) then
if readDataValid = '1' then
dataInReg <= memDataIn;
end if;
end if;
end process storeDataIn;
flashDataIn <= dataInReg when readDataValid = '0' else memDataIn;
------------------------------------------------------------------------------
-- read/write sequence
busAccessFsm: process(reset, clock)
begin
if reset = '1' then
read <= '0';
sequenceState <= idle;
elsif rising_edge(clock) then
case sequenceState is
when idle =>
if flashRd = '1' then
read <= '1';
sequenceState <= waitForBus1;
elsif flashWr = '1' then
read <= '0';
sequenceState <= waitForBus1;
end if;
when waitForBus1 =>
if memBusEn_n = '1' then
sequenceState <= waitForBus0;
end if;
when waitForBus0 =>
if memBusEn_n = '0' then
sequenceState <= startAccess;
end if;
when startAccess =>
sequenceState <= waitAcccessEnd;
when waitAcccessEnd =>
if endOfCount = '1' then
sequenceState <= idle;
end if;
end case;
end if;
end process busAccessFsm;
startCounter <= '1' when sequenceState = startAccess else '0';
endOfCount <= '1'
when ( (sequenceCounter = rdWaitState) and (read = '1') ) or
( (sequenceCounter = wrWaitState) and (read = '0') )
else '0';
countSequence: process(reset, clock)
begin
if reset = '1' then
sequenceCounter <= (others => '0');
elsif rising_edge(clock) then
if sequenceCounter = 0 then
if startCounter = '1' then
sequenceCounter <= sequenceCounter + 1;
end if;
else
if endOfCount = '1' then
sequenceCounter <= (others => '0');
else
sequenceCounter <= sequenceCounter + 1;
end if;
end if;
end if;
end process countSequence;
flashCE <= '0' when sequenceCounter = 0 else '1';
flashCE_n <= not flashCE;
memWR_n <= not '1' when (read = '0') and (flashCE = '1') and (endOfCount = '0')
else not '0';
memOE_n <= not '1' when (read = '1') and (flashCE = '1') else not '0';
flashDataValid <= endOfCount;
END ARCHITECTURE RTL;