?? ioport.vhd
字號:
------------------------------------------------------------------------------ This file is a part of the LEON VHDL model-- Copyright (C) 1999 European Space Agency (ESA)---- This library is free software; you can redistribute it and/or-- modify it under the terms of the GNU Lesser General Public-- License as published by the Free Software Foundation; either-- version 2 of the License, or (at your option) any later version.---- See the file COPYING.LGPL for the full details of the license.------------------------------------------------------------------------------- Entity: ioport-- File: ioport.vhd-- Author: Jiri Gaisler - Gaisler Research-- Description: Parallel I/O port. On reset, all port are programmed as-- inputs and remaning registers are unknown. This means-- that the interrupt configuration registers must be-- written before I/O port interrputs are unmasked in the-- interrupt controller.------------------------------------------------------------------------------library IEEE;use IEEE.std_logic_1164.all;use IEEE.std_logic_signed."-";use work.config.all;use work.iface.all;use work.macro.genmux;use work.amba.all; entity ioport is port ( rst : in rst_type; clk : in clk_type; apbi : in apb_slv_in_type; apbo : out apb_slv_out_type; uart1o : in uart_out_type; uart2o : in uart_out_type; mctrlo : in mctrl_out_type; ioi : in io_in_type; pioo : out pio_out_type );end; architecture rtl of ioport istype irq_ctrl_type is record isel : std_logic_vector(4 downto 0); pol : std_logic; edge : std_logic; enable : std_logic;end record;type irq_conf_type is array (3 downto 0) of irq_ctrl_type;type pioregs is record irqout : std_logic_vector(3 downto 0); irqlat : std_logic_vector(3 downto 0); pin1 : std_logic_vector(15 downto 0); pin2 : std_logic_vector(31 downto 0); pdir : std_logic_vector(17 downto 0); pout : std_logic_vector(15 downto 0); iconf : irq_conf_type;end record;signal r, rin : pioregs;begin pioop : process(rst, r, apbi, mctrlo, ioi, uart1o, uart2o) variable rdata : std_logic_vector(31 downto 0); variable v : pioregs; variable wrio : std_logic; begin v := r; wrio := '0';-- synchronise port inputs. Low 16 bits are latched twice while high 16 bits-- are allready latched once in the memory controller and therefore only-- latched once here. v.pin1 := ioi.piol; v.pin2 := mctrlo.pioh & r.pin1;-- read/write registers rdata := (others => '0'); case apbi.paddr(3 downto 2) is when "00" => rdata(31 downto 0) := r.pin2; when "01" => rdata(17 downto 0) := r.pdir; when "10" => rdata(31 downto 0) := r.iconf(3).enable & r.iconf(3).edge & r.iconf(3).pol & r.iconf(3).isel & r.iconf(2).enable & r.iconf(2).edge & r.iconf(2).pol & r.iconf(2).isel & r.iconf(1).enable & r.iconf(1).edge & r.iconf(1).pol & r.iconf(1).isel & r.iconf(0).enable & r.iconf(0).edge & r.iconf(0).pol & r.iconf(0).isel; when others => rdata := (others => '-'); end case; if (apbi.psel and apbi.penable and apbi.pwrite) = '1' then case apbi.paddr(3 downto 2) is when "00" => v.pout := apbi.pwdata(15 downto 0); wrio := '1'; when "01" => v.pdir := apbi.pwdata(17 downto 0); when "10" => v.iconf(3).enable := apbi.pwdata(31); v.iconf(3).edge := apbi.pwdata(30); v.iconf(3).pol := apbi.pwdata(29); v.iconf(3).isel := apbi.pwdata(28 downto 24); v.iconf(2).enable := apbi.pwdata(23); v.iconf(2).edge := apbi.pwdata(22); v.iconf(2).pol := apbi.pwdata(21); v.iconf(2).isel := apbi.pwdata(20 downto 16); v.iconf(1).enable := apbi.pwdata(15); v.iconf(1).edge := apbi.pwdata(14); v.iconf(1).pol := apbi.pwdata(13); v.iconf(1).isel := apbi.pwdata(12 downto 8); v.iconf(0).enable := apbi.pwdata(7); v.iconf(0).edge := apbi.pwdata(6); v.iconf(0).pol := apbi.pwdata(5); v.iconf(0).isel := apbi.pwdata(4 downto 0); when others => null; end case; end if; -- override I/O port settings if UARTs are enabled if uart1o.txen = '1' then v.pout(15) := uart1o.txd; end if; if uart1o.flow = '1' then v.pout(13) := uart1o.rtsn; end if; if uart2o.txen = '1' then v.pout(11) := uart2o.txd; end if; if uart2o.flow = '1' then v.pout(9) := uart2o.rtsn; end if;-- interrupt generation for i in 0 to 3 loop -- select and latch interrupt source v.irqlat(i) := genmux(r.iconf(i).isel, r.pin2); if r.iconf(i).enable = '1' then if r.iconf(i).edge = '1' then v.irqout(i) := (v.irqlat(i) xor r.irqlat(i)) and (v.irqlat(i) xor not r.iconf(i).pol); else v.irqout(i) := (v.irqlat(i) xor not r.iconf(i).pol); end if; else v.irqout(i) := '0'; end if; end loop;-- reset operation if rst.syncrst = '0' then v.pdir := (others => '0'); v.iconf(0).enable := '0'; v.iconf(1).enable := '0'; v.iconf(2).enable := '0'; v.iconf(3).enable := '0'; end if;-- drive signals rin <= v; -- update registers apbo.prdata <= rdata; -- drive data bus pioo.irq <= r.irqout; pioo.piodir <= not r.pdir; pioo.io8lsb <= r.pin2(7 downto 0); pioo.rxd(0) <= r.pin2(14); pioo.ctsn(0) <= r.pin2(12); pioo.rxd(1) <= r.pin2(10); pioo.ctsn(1) <= r.pin2(8); pioo.piol <= apbi.pwdata(31 downto 16) & r.pout(15 downto 0); pioo.wrio <= wrio; end process;-- registers regs : process(clk,rst) begin if rising_edge(clk) then r <= rin; end if; if rst.rawrst = '0' then r.pdir <= (others => '0'); end if; end process;end;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -