mirror of
https://github.com/wfjm/w11.git
synced 2026-01-13 07:29:58 +00:00
add DEUNA device (xu) for ibus
This commit is contained in:
parent
64b8435719
commit
623639aa82
6
rtl/ibus/ibdr_deuna.vbom
Normal file
6
rtl/ibus/ibdr_deuna.vbom
Normal file
@ -0,0 +1,6 @@
|
||||
# libs
|
||||
../vlib/slvtypes.vhd
|
||||
iblib.vhd
|
||||
# components
|
||||
# design
|
||||
ibdr_deuna.vhd
|
||||
349
rtl/ibus/ibdr_deuna.vhd
Normal file
349
rtl/ibus/ibdr_deuna.vhd
Normal file
@ -0,0 +1,349 @@
|
||||
-- $Id: ibdr_deuna.vhd 874 2017-04-14 17:53:07Z mueller $
|
||||
--
|
||||
-- Copyright 2014-2017 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
--
|
||||
-- This program is free software; you may redistribute and/or modify it under
|
||||
-- the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 2, or at your option any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful, but
|
||||
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
-- for complete details.
|
||||
--
|
||||
------------------------------------------------------------------------------
|
||||
-- Module Name: ibdr_deuna - syn
|
||||
-- Description: ibus dev(rem): DEUNA
|
||||
--
|
||||
-- Dependencies: -
|
||||
-- Test bench: -
|
||||
-- Target Devices: generic
|
||||
-- Tool versions: ise 14.7; viv 2016.4; ghdl 0.33
|
||||
--
|
||||
-- Synthesized (xst):
|
||||
-- Date Rev ise Target flop lutl lutm slic t peri
|
||||
-- 2017-04-14 874 14.7 131013 xc6slx16-2 50 79 0 40 s 4.1
|
||||
-- 2017-01-29 847 14.7 131013 xc6slx16-2 42 70 0 36 s 4.1
|
||||
--
|
||||
-- Revision History:
|
||||
-- Date Rev Version Comment
|
||||
-- 2017-04-14 875 1.0 Initial version
|
||||
-- 2014-06-09 561 0.1 First draft
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
use work.slvtypes.all;
|
||||
use work.iblib.all;
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
entity ibdr_deuna is -- ibus dev(rem): DEUNA
|
||||
-- fixed address: 174510
|
||||
port (
|
||||
CLK : in slbit; -- clock
|
||||
BRESET : in slbit; -- ibus reset
|
||||
RB_LAM : out slbit; -- remote attention
|
||||
IB_MREQ : in ib_mreq_type; -- ibus request
|
||||
IB_SRES : out ib_sres_type; -- ibus response
|
||||
EI_REQ : out slbit; -- interrupt request
|
||||
EI_ACK : in slbit -- interrupt acknowledge
|
||||
);
|
||||
end ibdr_deuna;
|
||||
|
||||
architecture syn of ibdr_deuna is
|
||||
|
||||
constant ibaddr_deuna : slv16 := slv(to_unsigned(8#174510#,16));
|
||||
|
||||
constant ibaddr_pr0 : slv2 := "00"; -- pcsr0 address offset
|
||||
constant ibaddr_pr1 : slv2 := "01"; -- pcsr1 address offset
|
||||
constant ibaddr_pr2 : slv2 := "10"; -- pcsr2 address offset
|
||||
constant ibaddr_pr3 : slv2 := "11"; -- pcsr3 address offset
|
||||
|
||||
constant pr0_ibf_seri : integer := 15;
|
||||
constant pr0_ibf_pcei : integer := 14;
|
||||
constant pr0_ibf_rxi : integer := 13;
|
||||
constant pr0_ibf_txi : integer := 12;
|
||||
constant pr0_ibf_dni : integer := 11;
|
||||
constant pr0_ibf_rcbi : integer := 10;
|
||||
constant pr0_ibf_usci : integer := 8;
|
||||
constant pr0_ibf_intr : integer := 7;
|
||||
constant pr0_ibf_inte : integer := 6;
|
||||
constant pr0_ibf_rset : integer := 5;
|
||||
subtype pr0_ibf_pcmd is integer range 3 downto 0;
|
||||
-- additional rem view assignments
|
||||
subtype pr0_ibf_pcmdbp is integer range 15 downto 12;
|
||||
constant pr0_ibf_busy : integer := 9;
|
||||
constant pr0_ibf_pcwwb : integer := 8;
|
||||
constant pr0_ibf_brst : integer := 4;
|
||||
|
||||
constant pcmd_noop : slv4 := "0000"; -- pcmd: noop (DNI not set !)
|
||||
|
||||
constant pr1_ibf_xpwr : integer := 15;
|
||||
constant pr1_ibf_icab : integer := 14;
|
||||
subtype pr1_ibf_ecod is integer range 13 downto 8;
|
||||
constant pr1_ibf_pcto : integer := 7;
|
||||
constant pr1_ibf_deuna : integer := 4; -- id bit 0 (0=DEUNA;1=DELUA)
|
||||
subtype pr1_ibf_state is integer range 3 downto 0;
|
||||
|
||||
constant state_reset : slv4 := "0000"; -- state: reset
|
||||
constant state_ready : slv4 := "0010"; -- state: ready
|
||||
|
||||
type regs_type is record -- state registers
|
||||
ibsel : slbit; -- ibus select
|
||||
pr0seri : slbit; -- pr0: status error intr
|
||||
pr0pcei : slbit; -- pr0: port command error intr
|
||||
pr0rxi : slbit; -- pr0: receive ring intr
|
||||
pr0txi : slbit; -- pr0: transmit ring intr
|
||||
pr0dni : slbit; -- pr0: done interrupt
|
||||
pr0rcbi : slbit; -- pr0: receive buffer unavail intr
|
||||
pr0usci : slbit; -- pr0: unsolicited state change intr
|
||||
pr0intr : slbit; -- pr0: intr summary
|
||||
pr0inte : slbit; -- pr0: intr enable
|
||||
pr0rset : slbit; -- pr0: software reset
|
||||
pr0brst : slbit; -- pr0: BRESET reset
|
||||
pr0pcmd : slv4; -- pr0: port command
|
||||
pr1xpwr : slbit; -- pr1: transmitter power fail
|
||||
pr1icab : slbit; -- pr1: port/link cabling fail
|
||||
pr1pcto : slbit; -- pr1: port command time out
|
||||
pr1deuna : slbit; -- pr1: bit 0 of ID (0=DEUNA;1=DELUA)
|
||||
pr1state : slv4; -- pr1: port status
|
||||
pcbb : slv18_1; -- pr2+3: port conrol block base
|
||||
busy : slbit; -- busy
|
||||
pcmdwwb : slbit; -- pcmd written while busy
|
||||
pcmdbp : slv4; -- pcmd busy protected
|
||||
resreq : slbit; -- reset requested
|
||||
ireq : slbit; -- interrupt request flag
|
||||
end record regs_type;
|
||||
|
||||
constant regs_init : regs_type := (
|
||||
'0', -- ibsel
|
||||
'0','0','0','0', -- pr0seri,pr0pcei,pr0rxi,pr0txi
|
||||
'0','0','0', -- pr0dni,pr0rcbi,pr0usci
|
||||
'0','0', -- pr0intr,pr0inte
|
||||
'0','0', -- pr0rset,pr0brst
|
||||
(others=>'0'), -- pr0pcmd
|
||||
'1','1', -- pr1xpwr,pr1icab
|
||||
'0','0', -- pr1pcto,pr1deuna
|
||||
state_reset, -- pr1state
|
||||
(others=>'0'), -- pcbb
|
||||
'0','0', -- busy,pcmdwwb
|
||||
(others=>'0'), -- pcmdbp
|
||||
'0', -- resreq
|
||||
'0' -- ireq
|
||||
);
|
||||
|
||||
signal R_REGS : regs_type := regs_init;
|
||||
signal N_REGS : regs_type := regs_init;
|
||||
|
||||
begin
|
||||
|
||||
proc_regs: process (CLK)
|
||||
begin
|
||||
if rising_edge(CLK) then
|
||||
R_REGS <= N_REGS;
|
||||
end if;
|
||||
end process proc_regs;
|
||||
|
||||
proc_next : process (R_REGS, IB_MREQ, EI_ACK, BRESET)
|
||||
variable r : regs_type := regs_init;
|
||||
variable n : regs_type := regs_init;
|
||||
variable ibhold : slbit := '0';
|
||||
variable idout : slv16 := (others=>'0');
|
||||
variable ibrem : slbit := '0';
|
||||
variable ibreq : slbit := '0';
|
||||
variable ibrd : slbit := '0';
|
||||
variable ibw0 : slbit := '0';
|
||||
variable ibw1 : slbit := '0';
|
||||
variable ibwrem : slbit := '0';
|
||||
variable ilam : slbit := '0';
|
||||
|
||||
begin
|
||||
|
||||
r := R_REGS;
|
||||
n := R_REGS;
|
||||
|
||||
ibhold := '0';
|
||||
idout := (others=>'0');
|
||||
ibrem := IB_MREQ.racc;
|
||||
ibreq := IB_MREQ.re or IB_MREQ.we;
|
||||
ibrd := IB_MREQ.re;
|
||||
ibw0 := IB_MREQ.we and IB_MREQ.be0;
|
||||
ibw1 := IB_MREQ.we and IB_MREQ.be1;
|
||||
ibwrem := IB_MREQ.we and ibrem;
|
||||
ilam := '0';
|
||||
|
||||
-- ibus address decoder
|
||||
n.ibsel := '0';
|
||||
if IB_MREQ.aval = '1' and
|
||||
IB_MREQ.addr(12 downto 3)=ibaddr_deuna(12 downto 3) then
|
||||
n.ibsel := '1';
|
||||
end if;
|
||||
|
||||
-- ibus transactions
|
||||
|
||||
if r.ibsel='1' then -- selected
|
||||
|
||||
case IB_MREQ.addr(2 downto 1) is
|
||||
|
||||
when ibaddr_pr0 => -- PCSR0 - intr and pcmd -----------
|
||||
if ibrem = '0' then -- loc view of upper byte
|
||||
idout(pr0_ibf_seri) := r.pr0seri;
|
||||
idout(pr0_ibf_pcei) := r.pr0pcei;
|
||||
idout(pr0_ibf_rxi) := r.pr0rxi;
|
||||
idout(pr0_ibf_txi) := r.pr0txi;
|
||||
idout(pr0_ibf_dni) := r.pr0dni;
|
||||
idout(pr0_ibf_rcbi) := r.pr0rcbi;
|
||||
idout(pr0_ibf_usci) := r.pr0usci;
|
||||
else -- rem view of upper byte
|
||||
idout(pr0_ibf_pcmdbp) := r.pcmdbp;
|
||||
idout(pr0_ibf_busy) := r.busy;
|
||||
idout(pr0_ibf_pcwwb) := r.pcmdwwb;
|
||||
end if;
|
||||
idout(pr0_ibf_intr) := r.pr0intr;
|
||||
idout(pr0_ibf_inte) := r.pr0inte;
|
||||
if ibrem = '1' then
|
||||
idout(pr0_ibf_rset) := r.pr0rset; -- only seen from rem side
|
||||
idout(pr0_ibf_brst) := r.pr0brst; -- only seen from rem side
|
||||
end if;
|
||||
idout(pr0_ibf_pcmd) := r.pr0pcmd;
|
||||
|
||||
if IB_MREQ.we = '1' then
|
||||
if ibrem = '1' then -- rem write
|
||||
if IB_MREQ.din(pr0_ibf_seri) = '1' then n.pr0seri := '1'; end if;
|
||||
if IB_MREQ.din(pr0_ibf_pcei) = '1' then n.pr0pcei := '1'; end if;
|
||||
if IB_MREQ.din(pr0_ibf_rxi) = '1' then n.pr0rxi := '1'; end if;
|
||||
if IB_MREQ.din(pr0_ibf_txi) = '1' then n.pr0txi := '1'; end if;
|
||||
if IB_MREQ.din(pr0_ibf_dni) = '1' then n.pr0dni := '1'; end if;
|
||||
if IB_MREQ.din(pr0_ibf_rcbi) = '1' then n.pr0rcbi := '1'; end if;
|
||||
if IB_MREQ.din(pr0_ibf_usci) = '1' then n.pr0usci := '1'; end if;
|
||||
if IB_MREQ.din(pr0_ibf_rset) = '1' then n.pr0rset := '0'; end if;
|
||||
if IB_MREQ.din(pr0_ibf_brst) = '1' then n.pr0brst := '0'; end if;
|
||||
if IB_MREQ.din(pr0_ibf_dni) = '1' or
|
||||
IB_MREQ.din(pr0_ibf_pcei) = '1' or
|
||||
IB_MREQ.din(pr0_ibf_busy) = '1' or
|
||||
IB_MREQ.din(pr0_ibf_rset) = '1' or
|
||||
IB_MREQ.din(pr0_ibf_brst) = '1' then
|
||||
n.busy := '0';
|
||||
end if;
|
||||
else -- loc write
|
||||
if IB_MREQ.be1 = '1' then
|
||||
if IB_MREQ.din(pr0_ibf_seri) = '1' then n.pr0seri := '0'; end if;
|
||||
if IB_MREQ.din(pr0_ibf_pcei) = '1' then n.pr0pcei := '0'; end if;
|
||||
if IB_MREQ.din(pr0_ibf_rxi) = '1' then n.pr0rxi := '0'; end if;
|
||||
if IB_MREQ.din(pr0_ibf_txi) = '1' then n.pr0txi := '0'; end if;
|
||||
if IB_MREQ.din(pr0_ibf_dni) = '1' then n.pr0dni := '0'; end if;
|
||||
if IB_MREQ.din(pr0_ibf_rcbi) = '1' then n.pr0rcbi := '0'; end if;
|
||||
if IB_MREQ.din(pr0_ibf_usci) = '1' then n.pr0usci := '0'; end if;
|
||||
end if;
|
||||
if IB_MREQ.be0 = '1' then
|
||||
if IB_MREQ.din(pr0_ibf_rset) = '1' then -- RESET requested ?
|
||||
n.resreq := '1';
|
||||
n.pr0rset := '1';
|
||||
elsif IB_MREQ.din(pr0_ibf_inte) /= r.pr0inte then -- INTE change?
|
||||
n.pr0inte := IB_MREQ.din(pr0_ibf_inte);
|
||||
n.pr0dni := '1';
|
||||
elsif r.pr1state /= state_reset then -- not in reset
|
||||
n.pr0pcmd := IB_MREQ.din(pr0_ibf_pcmd);
|
||||
if r.busy = '0' then -- if not busy execute
|
||||
n.pcmdbp := IB_MREQ.din(pr0_ibf_pcmd);
|
||||
if IB_MREQ.din(pr0_ibf_pcmd) /= pcmd_noop then
|
||||
n.busy := '1'; -- signal busy
|
||||
ilam := '1'; -- rri lam
|
||||
end if;
|
||||
else -- if busy set pcmdwwf flag
|
||||
n.pcmdwwb := '1';
|
||||
end if;
|
||||
end if;
|
||||
end if; -- if IB_MREQ.be0 = '1'
|
||||
end if; -- else ibrem = '1'
|
||||
end if; -- if IB_MREQ.we = '1'
|
||||
|
||||
if IB_MREQ.re = '1' and ibrem = '1' then -- for rem pr0 reads
|
||||
n.pcmdwwb := '0'; -- clear pcmdwwb
|
||||
end if;
|
||||
|
||||
when ibaddr_pr1 => -- PCSR1 - status ------------------
|
||||
idout(pr1_ibf_xpwr) := r.pr1xpwr;
|
||||
idout(pr1_ibf_icab) := r.pr1icab;
|
||||
idout(pr1_ibf_pcto) := r.pr1pcto;
|
||||
idout(pr1_ibf_deuna) := r.pr1deuna;
|
||||
idout(pr1_ibf_state) := r.pr1state;
|
||||
if IB_MREQ.we = '1' then
|
||||
if ibrem = '1' then
|
||||
n.pr1xpwr := IB_MREQ.din(pr1_ibf_xpwr);
|
||||
n.pr1icab := IB_MREQ.din(pr1_ibf_icab);
|
||||
n.pr1pcto := IB_MREQ.din(pr1_ibf_pcto);
|
||||
n.pr1deuna := IB_MREQ.din(pr1_ibf_deuna);
|
||||
n.pr1state := IB_MREQ.din(pr1_ibf_state);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when ibaddr_pr2 => -- PCSR2 - pcbb low order ----------
|
||||
idout(15 downto 1) := r.pcbb(15 downto 1);
|
||||
if IB_MREQ.we = '1' then
|
||||
n.pcbb(15 downto 1) := IB_MREQ.din(15 downto 1);
|
||||
end if;
|
||||
|
||||
when ibaddr_pr3 => -- PCSR2 - pcbb high order ---------
|
||||
idout( 1 downto 0) := r.pcbb(17 downto 16);
|
||||
if IB_MREQ.we = '1' then
|
||||
n.pcbb(17 downto 16) := IB_MREQ.din( 1 downto 0);
|
||||
end if;
|
||||
|
||||
when others => null;
|
||||
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if BRESET = '1' then
|
||||
n.resreq := '1';
|
||||
n.pr0brst := '1';
|
||||
end if;
|
||||
|
||||
if r.resreq = '1' then
|
||||
n.pr0seri := '0';
|
||||
n.pr0pcei := '0';
|
||||
n.pr0rxi := '0';
|
||||
n.pr0txi := '0';
|
||||
n.pr0dni := '0';
|
||||
n.pr0rcbi := '0';
|
||||
n.pr0usci := '0';
|
||||
n.pr1pcto := '0';
|
||||
n.pr0inte := '0';
|
||||
n.pr1state := state_reset;
|
||||
n.pcbb := (others => '0');
|
||||
n.resreq := '0';
|
||||
-- send lam on soft or bus reset only when not in state_reset
|
||||
-- the startup default is state_reset, so without active backend
|
||||
-- this device will not send lam's on bus resets
|
||||
if r.pr1state /= state_reset then
|
||||
n.busy := '1'; -- signal busy
|
||||
ilam := '1'; -- rri lam unless reset handling pending
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
n.pr0intr := r.pr0seri or r.pr0pcei or r.pr0rxi or r.pr0txi or
|
||||
r.pr0dni or r.pr0rcbi or r.pr0usci;
|
||||
|
||||
if r.pr0inte = '1' then
|
||||
n.ireq := r.pr0intr;
|
||||
else
|
||||
n.ireq := '0';
|
||||
end if;
|
||||
|
||||
N_REGS <= n;
|
||||
|
||||
IB_SRES.dout <= idout;
|
||||
IB_SRES.ack <= r.ibsel and ibreq;
|
||||
IB_SRES.busy <= ibhold and ibreq;
|
||||
|
||||
RB_LAM <= ilam;
|
||||
EI_REQ <= r.ireq;
|
||||
|
||||
end process proc_next;
|
||||
|
||||
|
||||
end syn;
|
||||
Loading…
x
Reference in New Issue
Block a user