136 lines
5.1 KiB
VHDL
136 lines
5.1 KiB
VHDL
-- altera vhdl_input_version vhdl_2008
|
|
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
use ieee.math_real.all;
|
|
|
|
|
|
entity LCDAvalonMaster is
|
|
generic (
|
|
NWORDS_MAX : natural
|
|
);
|
|
port (
|
|
clk : in std_logic;
|
|
rst_n : in std_logic;
|
|
waitreq : in std_logic;
|
|
readdata : in std_logic_vector(31 downto 0);
|
|
readdatavalid : in std_logic;
|
|
address : out std_logic_vector(31 downto 0);
|
|
burstcount : out std_logic_vector(4 downto 0);
|
|
am_read : out std_logic;
|
|
refresh : in std_logic;
|
|
fifo_almost_empty : in std_logic;
|
|
fifo_data : out std_logic_vector(31 downto 0);
|
|
fifo_wr_req : out std_logic;
|
|
baseaddress : in std_logic_vector(31 downto 0);
|
|
nwords : in std_logic_vector(integer(ceil(log2(real(NWORDS_MAX)))) downto 0)
|
|
);
|
|
end LCDAvalonMaster;
|
|
|
|
architecture behavioral of LCDAvalonMaster is
|
|
-- Generic constants
|
|
constant BURST_COUNT : integer := 16;
|
|
constant BURST_COUNT_SLV : std_logic_vector(burstcount'left downto 0) := std_logic_vector(to_unsigned(BURST_COUNT, burstcount'length));
|
|
|
|
|
|
-- Type definitions
|
|
type State is (S_READY, S_BURSTREQ, S_BURSTRD, S_FIFOWAIT);
|
|
subtype BurstCounter is integer range 0 to BURST_COUNT;
|
|
subtype WordCounter is integer range 0 to NWORDS_MAX;
|
|
|
|
|
|
-- Inferred registers
|
|
signal rdaddr_reg, rdaddr_next : std_logic_vector(31 downto 0);
|
|
signal state_reg, state_next : State;
|
|
signal burstcnt_reg, burstcnt_next : BurstCounter; -- Counts # of words read during a single burst
|
|
signal wordcnt_reg, wordcnt_next : WordCounter; -- Counts # of words read during a refresh cycle
|
|
|
|
|
|
begin
|
|
-- PROCESS state machine
|
|
process(all) begin
|
|
state_next <= state_reg;
|
|
rdaddr_next <= rdaddr_reg;
|
|
burstcnt_next <= burstcnt_reg;
|
|
wordcnt_next <= wordcnt_reg;
|
|
|
|
-- Avalon master default output signals
|
|
burstcount <= BURST_COUNT_SLV;
|
|
am_read <= '0';
|
|
|
|
case state_reg is
|
|
when S_READY =>
|
|
-- ====================== AM STATE: READY ======================
|
|
if refresh = '1' then
|
|
wordcnt_next <= integer(to_integer(unsigned(nwords)));
|
|
state_next <= S_BURSTREQ;
|
|
end if;
|
|
when S_BURSTREQ =>
|
|
-- ================== AM STATE: BURST REQUEST ==================
|
|
am_read <= '1';
|
|
if waitreq = '0' then
|
|
-- Burst was accepted,
|
|
state_next <= S_BURSTRD;
|
|
|
|
-- Calculate the # of words we plan to read during this burst
|
|
-- and update counters accordingly.
|
|
if wordcnt_reg < BURST_COUNT then
|
|
burstcnt_next <= wordcnt_reg;
|
|
wordcnt_next <= 0;
|
|
else
|
|
burstcnt_next <= BURST_COUNT;
|
|
wordcnt_next <= wordcnt_reg - BURST_COUNT;
|
|
end if;
|
|
end if;
|
|
when S_BURSTRD =>
|
|
-- ==================== AM STATE: BURST READ ===================
|
|
if readdatavalid = '1' then
|
|
if burstcnt_reg = 1 then
|
|
-- Got last word, burst read finished
|
|
if wordcnt_reg = 0 then
|
|
-- All nwords read
|
|
state_next <= S_READY;
|
|
else
|
|
-- < nwords read
|
|
state_next <= S_FIFOWAIT;
|
|
end if;
|
|
else
|
|
burstcnt_next <= burstcnt_reg - 1;
|
|
end if;
|
|
end if;
|
|
|
|
when S_FIFOWAIT =>
|
|
-- ==================== AM STATE: FIFO WAIT ====================
|
|
-- Await the assertion of fifo_almost_empty until reinitiating a
|
|
-- burst read
|
|
if fifo_almost_empty = '1' then
|
|
state_next <= S_BURSTREQ;
|
|
end if;
|
|
end case;
|
|
end process;
|
|
|
|
|
|
-- FIFO data transfer routing
|
|
fifo_wr_req <= '1' when state_reg = S_BURSTRD and readdatavalid = '1' else '0';
|
|
fifo_data <= readdata when state_reg = S_BURSTRD else (others => 'Z');
|
|
address <= std_logic_vector(unsigned(baseaddress) + resize((unsigned(nwords) - wordcnt_reg) * 4, address'length)) when state_reg = S_BURSTREQ else (others => 'Z');
|
|
|
|
-- Clocking process/register inferrence
|
|
process(clk) begin
|
|
if rising_edge(clk) then
|
|
if rst_n = '0' then
|
|
rdaddr_reg <= (others => '0');
|
|
state_reg <= S_READY;
|
|
burstcnt_reg <= BURST_COUNT;
|
|
wordcnt_reg <= 0;
|
|
else
|
|
rdaddr_reg <= rdaddr_next;
|
|
state_reg <= state_next;
|
|
burstcnt_reg <= burstcnt_next;
|
|
wordcnt_reg <= wordcnt_next;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
|
|
end behavioral; |