⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 multiio_apb.vhd

📁 free hardware ip core about sparcv8,a soc cpu in vhdl
💻 VHD
📖 第 1 页 / 共 2 页
字号:
--------------------------------------------------------------------
--  Entity:         MultiIO_APB
--  File:           MultiIO_APB.vhd
--  Author:         Thomas Ameseder, Gleichmann Electronics
--  Based on an orginal version by Manfred.Helzle@embedd.it
--  
--  Description:    APB Multiple digital I/O for minimal User Interface
--------------------------------------------------------------------
--  Functionality:
--  8 LEDs,         active low or high, r/w
--  dual 7Segment,  active low or high, w only
--  8 DIL Switches, active low or high, r only
--  8 Buttons,      active low or high, r only, with IRQ enables
--------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;

library grlib;
use grlib.amba.all;
use grlib.stdlib.all;
use grlib.devices.all;

library gleichmann;
use gleichmann.spi.all;
use gleichmann.i2c.all;
use gleichmann.miscellaneous.all;
use gleichmann.multiio.all;

--  pragma translate_off
use std.textio.all;
--  pragma translate_on


entity MultiIO_APB is
  generic (
    pindex : integer := 0;              -- Leon-Index
    paddr  : integer := 0;              -- Leon-Address
    pmask  : integer := 16#FFF#;        -- Leon-Mask
    pirq   : integer := 0;              -- Leon-IRQ

    clk_freq_in : integer := 25_000_000;  -- Leons clock to calculate timings

    led7act   : std_logic := '0';       -- active level for 7Segment
    ledact    : std_logic := '0';       -- active level for LEDs
    switchact : std_logic := '1';       -- active level for LED's
    buttonact : std_logic := '1';       -- active level for LED's

    n_switches  : integer := 8;   -- number of switches that are driven
    n_leds      : integer := 8    -- number of LEDs that are driven

    );

  port (
    rst_n       : in  std_ulogic;        -- global Reset, active low
    clk         : in  std_ulogic;        -- global Clock
    apbi        : in  apb_slv_in_type;   -- APB-Input
    apbo        : out apb_slv_out_type;  -- APB-Output
    MultiIO_in  : in  MultiIO_in_type;   -- MultIO-Inputs
    MultiIO_out : out MultiIO_out_type   -- MultiIO-Outputs
    );
end entity;


architecture Implementation of MultiIO_APB is  ----------------------

  constant VERSION  : std_logic_vector(31 downto 0) := x"EA_04_04_06";
  constant REVISION : integer                       := 2;
  constant MUXMAX   : integer                       := 5;

  constant VCC : std_logic_vector(31 downto 0) := (others => '1');
  constant GND : std_logic_vector(31 downto 0) := (others => '0');

  signal Enable1ms  : boolean;
  signal MUXCounter : integer range 0 to MUXMAX;

  signal clkgen_mclk   : std_ulogic;
  signal clkgen_bclk   : std_ulogic;
  signal clkgen_sclk   : std_ulogic;
  signal clkgen_lrclk : std_ulogic;

  type state_t is (WAIT_FOR_SYNC,READY,WAIT_FOR_ACK);
  signal state,next_state : state_t;
  signal Strobe,next_Strobe                        : std_ulogic;

  -- status signals of the i2s core for upper-level state machine
  signal SampleAck, WaitForSample : std_ulogic;
  signal samplereg : std_ulogic_vector(N_CODECI2SBITS-1 downto 0);

  constant pconfig : apb_config_type := (
    0 => ahb_device_reg (VENDOR_GLEICHMANN, GLEICHMANN_HIFC, 0, REVISION, pirq),
    1 => apb_iobar(paddr, pmask)
    );

  type MultiIOregisters is
    record
      ledreg  : std_logic_vector(31 downto 0);    -- LEDs
      led7reg : std_logic_vector(31 downto 0);    -- Dual 7Segment LEDs
      codecreg : std_logic_vector(31 downto 0);
      codecreg2 : std_logic_vector(31 downto 0);

      -- Switches in
      sw_inreg  : std_logic_vector(31 downto 0);
      -- ASCII value of input button
      btn_inreg : std_logic_vector(31 downto 0);

      irqenareg : std_logic_vector(31 downto 0);  -- IRQ enables for Buttons
      btn_irqs  : std_logic_vector(31 downto 0);  -- IRQs from each Button

      new_data : std_ulogic;
      serviced : std_ulogic;
      lcdreg : std_logic_vector(31 downto 0);  -- LCD instruction

      exp_in_reg : std_logic_vector(31 downto 0);
      exp_out_reg : std_logic_vector(31 downto 0);
    end record;

  signal r, rin : MultiIOregisters;     -- register sets

  signal Key           : std_logic_vector(7 downto 0);  -- ASCII value of button
  -- character representation of the key (for simulation purposes)
  signal KeyVal        : character;

  signal OldColumnRow1 : std_logic_vector(6 downto 0);  -- for key debounce
  signal OldColumnRow2 : std_logic_vector(6 downto 0);  -- for key debounce

begin

  reg_rw : process(MUXCounter, MultiIO_in, apbi, key, r, rst_n)
    variable readdata : std_logic_vector(31 downto 0);  -- system bus width
    variable irqs     : std_logic_vector(31 downto 0);  -- system IRQs width
    variable v        : MultiIOregisters;               -- register set
--    variable new_data : std_ulogic;
  begin
    v := r;

    --  reset registers
    if rst_n = '0' then
      -- lower half of LEDs on
      v.ledreg := (others => '0');
      v.ledreg(3 downto 0) := "1111";

      v.led7reg := (others => '0');
      v.led7reg(15 downto 0) := X"38_4F";            -- show "L3" Leon3 on 7Segments

      v.codecreg := (others => '0');
      v.codecreg2 := (others => '0');
      v.irqenareg := (others => '0');   -- IRQs disable
      v.btn_inreg := (others => '0');
      v.sw_inreg  := (others => '0');

      -- new data flag off
      v.new_data := '0';
      v.serviced := '0';
      v.lcdreg := (others => '0');

      v.exp_in_reg := (others => '0');
      v.exp_out_reg := (others => '0');
    end if;

    --  get switches and buttons
    if switchact = '1' then
      v.sw_inreg(N_SWITCHES-1 downto 0) := MultiIO_in.switch_in;
    else
      v.sw_inreg(N_SWITCHES-1 downto 0) := not MultiIO_in.switch_in;
    end if;

    v.btn_inreg(7 downto 0) := key;

    v.btn_irqs := (others => '0');

    ---------------------------------------------------------------------------
    -- TO BE ALTERED
    ---------------------------------------------------------------------------
    --  set local button-IRQs
    for i in 0 to v.btn_irqs'left loop
      -- detect low-to-high transition
      if (v.btn_inreg(i) = '1') and (r.btn_inreg(i) = '0') then
        -- set local IRQs if IRQ enabled
        v.btn_irqs(i) := v.btn_inreg(i) and r.irqenareg(i);
      else
        -- clear local IRQs
        v.btn_irqs(i) := '0';
      end if;
    end loop;
    ---------------------------------------------------------------------------

    --  read registers
    readdata := (others => 'X');

    case conv_integer(apbi.paddr(5 downto 2)) is
      when 0 => readdata := r.ledreg;   -- LEDs
      when 1 => readdata := r.led7reg;  -- seven segment
      when 2 => readdata := r.codecreg;  -- codec command register
      when 3 => readdata := r.codecreg2;  -- codec i2s register
      when 4 => readdata := r.sw_inreg;   -- switches
      when 5 => readdata := r.btn_inreg;  -- buttons
      when 6 => readdata := r.irqenareg;  -- IRQ enables
      when 7 => readdata := conv_std_logic_vector(pirq, 32);  -- IRQ#
      when 8 => readdata := version;      -- version
      when 9 => readdata := r.lcdreg;   -- LCD data
      when 10 => readdata := r.exp_out_reg;  -- expansion connector out
      when 11 => readdata := r.exp_in_reg;  -- expansion connector in
      when others => null;
    end case;


    --  write registers
    if (apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1' then
      case conv_integer(apbi.paddr(5 downto 2)) is
        when 0 => v.ledreg :=
                    GND(31 downto N_LEDS) &
                    apbi.pwdata(N_LEDS-1 downto 0);        -- write LEDs
        when 1 => v.led7reg :=
                    GND(31 downto N_SEVSEGBITS) &
                    apbi.pwdata(N_SEVSEGBITS-1 downto 0);  -- write 7Segment
        when 2 => v.codecreg :=
                    GND(31 downto N_CODECBITS) &
                    apbi.pwdata(N_CODECBITS-1 downto 0);
        when 3 => v.codecreg2 :=
                    GND(31 downto N_CODECI2SBITS) &
                    apbi.pwdata(N_CODECI2SBITS-1 downto 0);
        when 6 => v.irqenareg :=
                    GND(31 downto N_BUTTONS) &
                    apbi.pwdata(N_BUTTONS-1 downto 0);
        when 9 => v.lcdreg :=
                    GND(31 downto N_LCDBITS) &
                    apbi.pwdata(N_LCDBITS-1 downto 0);
                  -- signal that new data has arrived
                  v.serviced := '0';
                  v.new_data := '1';
        when 10 => v.exp_out_reg :=
                    GND(31 downto N_EXPBITS/2) &
                    -- bit(N_EXPBITS) holds enable signal
                    apbi.pwdata(N_EXPBITS/2-1 downto 0);
        when others => null;
      end case;
    end if;

    irqs := (others => '0');

    --  set PIRQ
    for i in 0 to v.btn_irqs'left loop
      -- set IRQ if button-i pressed and IRQ enabled
      irqs(pirq) := irqs(pirq) or r.btn_irqs(i);
    end loop;


    if ledact = '1' then
      MultiIO_out.led_out <= r.ledreg(N_LEDS-1 downto 0);      -- not inverted
    else
      MultiIO_out.led_out <= not r.ledreg(N_LEDS-1 downto 0);  -- inverted
    end if;

    -- disable seven segment and LC display by default
--    MultiIO_out.lcd_enable <= '0';
    MultiIO_out.led_ca_out <= "00" xnor (led7act & led7act);

    case MUXCounter is
      when 0 | 1 =>
        -- output logical value according to active level of the 7segment display
        MultiIO_out.led_a_out  <= r.led7reg(MUXCounter*8 + 0) xnor led7act;
        MultiIO_out.led_b_out  <= r.led7reg(MUXCounter*8 + 1) xnor led7act;
        MultiIO_out.led_c_out  <= r.led7reg(MUXCounter*8 + 2) xnor led7act;
        MultiIO_out.led_d_out  <= r.led7reg(MUXCounter*8 + 3) xnor led7act;
        MultiIO_out.led_e_out  <= r.led7reg(MUXCounter*8 + 4) xnor led7act;
        MultiIO_out.led_f_out  <= r.led7reg(MUXCounter*8 + 5) xnor led7act;
        MultiIO_out.led_g_out  <= r.led7reg(MUXCounter*8 + 6) xnor led7act;
        MultiIO_out.led_dp_out <= r.led7reg(MUXCounter*8 + 7) xnor led7act;

        -- selectively enable the current digit

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -