Created
May 11, 2015 17:45
-
-
Save atnon/891d0b79ec26b78c7451 to your computer and use it in GitHub Desktop.
APB Slave, just something random.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library ieee; | |
use ieee.std_logic_1164.all; | |
use ieee.numeric_std.all; | |
library grlib; | |
use grlib.amba.all; | |
use grlib.stdlib.all; | |
use grlib.devices.all; | |
library work; | |
entity lcd_apb is | |
generic( | |
pindex : integer := 0; | |
paddr : integer := 0; | |
pmask : integer := 16#fff#; | |
pirq : integer := 0; | |
cpu_freq : integer := 100000 -- CPU Frequency in kHz. | |
); | |
port( | |
clk : in std_logic; | |
rstn : in std_logic; | |
apbi : in apb_slv_in_type; | |
apbo : out apb_slv_out_type; | |
); | |
end entity lcd_apb; | |
architecture RTL of lcd_apb is | |
constant pconfig : apb_config_type := ( | |
0 => ahb_device_reg(VENDOR_OPENCORES, GAISLER_GPREG, 0, 0, pirq), | |
1 => apb_iobar(paddr, pmask) | |
); | |
type stateType is (IDLE, HOLD); | |
signal state : stateType := IDLE; | |
begin | |
APB_Ctrl_Write : process(clk, rstn) is | |
begin | |
apbo.pirq(pirq) <= '0'; -- Interrupt is normally not triggered. | |
if rstn = '0' then | |
elsif rising_edge(clk) then | |
if (apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1' then -- triggers when new data. | |
-- APB is byte addressed, so we cannot use the two lower bits. | |
case apbi.paddr(4 downto 2) is | |
when "000" => -- Base address | |
SomeReg1 <= apbi.pwdata(31 downto 0); -- Latch data from bus. | |
when "001" => -- Base address + 0x4 | |
SomeReg2 <= apbi.pwdata(31 downto 0); -- Latch data from bus. | |
when others => | |
null; | |
end case; | |
end if; | |
apbo.pirq(pirq) <= '1'; -- Trigger interrupt | |
end if; | |
end process APB_Ctrl_Write; | |
-- APB read process, we need not worry about signals since the APB master | |
-- arbitrates what is read. | |
APB_Ctrl_Read : process(rstn, apbi) is | |
begin | |
if rstn = '0' then | |
apbo.prdata <= (others => '0'); | |
elsif rising_edge(clk) then | |
case apbi.paddr(4 downto 2) is | |
when "000" => | |
apbo.prdata <= SomeReg1; | |
when "001" => | |
apbo.prdata <= SomeReg2; | |
when others => | |
apbo.prdata <= (others => '0'); | |
end case; | |
end if; | |
end process APB_Ctrl_Read; | |
-- IRQ implementation will probably differ a lot depending on what | |
-- triggers the IRQ. The important thing is that the IRQ is not high | |
-- longer than one clock cycle. | |
APB_Ctrl_IRQ : process(clk, rstn) is | |
begin | |
if rstn = '0' then | |
apbo.pirq(pirq) <= '0'; | |
state <= IDLE; | |
elsif rising_edge(clk) then | |
apbo.pirq(pirq) <= '0'; | |
case state is | |
when IDLE => | |
-- Waiting for trigger signal to go high. | |
if triggerSignal = '1' then | |
state <= HOLD; | |
apbo.pirq(pirq) = '1'; | |
end if; | |
when HOLD => | |
-- Waiting for tigger signal to go low. | |
if triggerSignal = '0' then | |
state <= IDLE; | |
end if; | |
end case; | |
end if; | |
end process APB_Ctrl_IRQ; | |
-- Set APB bus signals. | |
apbo.pindex <= pindex; -- VHDL Generic | |
apbo.pconfig <= pconfig; -- VHDL Constant | |
--pragma translate_off | |
bootmsg : report_version | |
generic map("apbvgreport_versiona" & tost(pindex) & ": My APB Slave"); | |
--pragma translate_on | |
end architecture RTL; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment