OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /w11/tags/w11a_V0.7/rtl/ibus
    from Rev 32 to Rev 33
    Reverse comparison

Rev 32 → Rev 33

/ibdr_tm11.vhd
0,0 → 1,423
-- $Id: ibdr_tm11.vhd 690 2015-06-07 18:23:51Z mueller $
--
-- Copyright 2015- 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_tm11 - syn
-- Description: ibus dev(rem): TM11
--
-- Dependencies: -
-- Test bench: -
-- Target Devices: generic
-- Tool versions: ise 14.7; viv 2014.4; ghdl 0.31
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2015-06-04 686 14.7 131013 xc6slx16-2 79 144 0 53 s 4.4
-- 2015-05-15 682 14.7 131013 xc6slx16-2 117 209 0 76 s 3.7
--
-- Revision History:
-- Date Rev Version Comment
-- 2015-06-04 686 1.0 Initial version
-- 2015-05-15 682 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_tm11 is -- ibus dev(rem): TM11
-- fixed address: 172520
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_tm11;
 
architecture syn of ibdr_tm11 is
 
constant ibaddr_tm11 : slv16 := slv(to_unsigned(8#172520#,16));
 
constant ibaddr_sr : slv3 := "000"; -- sr address offset
constant ibaddr_cr : slv3 := "001"; -- cr address offset
constant ibaddr_bc : slv3 := "010"; -- bc address offset
constant ibaddr_ba : slv3 := "011"; -- ba address offset
constant ibaddr_db : slv3 := "100"; -- db address offset
constant ibaddr_rl : slv3 := "101"; -- rl address offset
constant sr_ibf_icmd : integer := 15;
constant sr_ibf_eof : integer := 14;
constant sr_ibf_pae : integer := 12;
constant sr_ibf_eot : integer := 10;
constant sr_ibf_rle : integer := 9;
constant sr_ibf_bte : integer := 8;
constant sr_ibf_nxm : integer := 7;
constant sr_ibf_onl : integer := 6;
constant sr_ibf_bot : integer := 5;
constant sr_ibf_wrl : integer := 2;
constant sr_ibf_rew : integer := 1;
constant sr_ibf_tur : integer := 0;
 
constant cr_ibf_err : integer := 15;
subtype cr_ibf_den is integer range 14 downto 13;
constant cr_ibf_ini : integer := 12;
constant cr_ibf_pevn : integer := 11;
constant cr_ibf_unit2 : integer := 10;
subtype cr_ibf_unit is integer range 9 downto 8;
constant cr_ibf_rdy : integer := 7;
constant cr_ibf_ie : integer := 6;
subtype cr_ibf_ea is integer range 5 downto 4;
subtype cr_ibf_func is integer range 3 downto 1;
constant cr_ibf_go : integer := 0;
 
subtype ba_ibf_ba is integer range 15 downto 1;
subtype db_ibf_db is integer range 7 downto 0;
 
constant rl_ibf_reof : integer := 10;
constant rl_ibf_reot : integer := 9;
constant rl_ibf_ronl : integer := 8;
constant rl_ibf_rbot : integer := 7;
constant rl_ibf_rwrl : integer := 6;
constant rl_ibf_rrew : integer := 5;
subtype rl_ibf_runit is integer range 2 downto 1;
constant func_unload : slv3 := "000"; -- func: unload
constant func_read : slv3 := "001"; -- func: read
constant func_write : slv3 := "010"; -- func: write
constant func_weof : slv3 := "011"; -- func: write eof
constant func_sforw : slv3 := "100"; -- func: space forward
constant func_sback : slv3 := "101"; -- func: space backward
constant func_wrteg : slv3 := "110"; -- func: write extend interrec gap
constant func_rewind : slv3 := "111"; -- func: rewind
 
constant rfunc_wunit : slv3 := "001"; -- rem func: write runit
constant rfunc_done : slv3 := "010"; -- rem func: done (set rdy)
 
-- cs1 usage for rem functions
subtype cr_ibf_runit is integer range 5 downto 4; -- new runit (_wunit)
constant cr_ibf_ricmd : integer := 15; -- new icmd (_done)
constant cr_ibf_rpae : integer := 12; -- new pae (_done)
constant cr_ibf_rrle : integer := 9; -- new rle (_done)
constant cr_ibf_rbte : integer := 8; -- new bte (_done)
constant cr_ibf_rnxm : integer := 7; -- new nxm (_done)
constant cr_ibf_reaena : integer := 6; -- ena ea (_done)
subtype cr_ibf_rea is integer range 5 downto 4; -- new ea (_done)
 
type regs_type is record -- state registers
ibsel : slbit; -- ibus select
sricmd : slbit; -- sr: invalid command
srpae: slbit; -- sr: parity error
srrle: slbit; -- sr: record length error
srbte: slbit; -- sr: bad tape error
srnxm: slbit; -- sr: non-existent memory
sreof: slv4; -- sr: eof-of-file
sreot: slv4; -- sr: eof-of-tape
sronl: slv4; -- sr: online
srbot: slv4; -- sr: begin-of-tape
srwrl: slv4; -- sr: write-locked
srrew: slv4; -- sr: rewinding
crden: slv2; -- cr: density
crpevn: slbit; -- cr: even oarity
crunit2: slbit; -- cr: unit[2]
crunit: slv2; -- cr: unit[1:0]
crrdy: slbit; -- cr: controller ready
crie: slbit; -- cr: interrupt enable
crea: slv2; -- cr: address extension
crfunc: slv3; -- cr: func code
bc : slv16; -- bc: byte count
ba : slv16_1; -- ba: bus address
runit : slv2; -- rem access unit
resreq : slbit; -- reset requested
ireq : slbit; -- interrupt request flag
end record regs_type;
 
constant regs_init : regs_type := (
'0', -- ibsel
'0','0','0','0','0', -- sricmd,srpae,srrle,srbte,srnxm
(others=>'0'), -- sreof
(others=>'0'), -- sreot
(others=>'0'), -- sronl
(others=>'0'), -- srbot
(others=>'0'), -- srwrl
(others=>'0'), -- srrew
(others=>'0'), -- crden
'0','0', -- crpevn,crunit2
(others=>'0'), -- crunit
'1','0', -- crrdy, crie
(others=>'0'), -- crea
(others=>'0'), -- crfunc
(others=>'0'), -- bc
(others=>'0'), -- ba
(others=>'0'), -- runit
'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)
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 4)=ibaddr_tm11(12 downto 4) and
unsigned(IB_MREQ.addr(3 downto 1)) <= unsigned(ibaddr_rl) then
n.ibsel := '1';
end if;
 
-- ibus transactions
if r.ibsel='1' then -- selected
case IB_MREQ.addr(3 downto 1) is
 
when ibaddr_sr => -- SR -- status register ----------
idout(sr_ibf_icmd) := r.sricmd;
idout(sr_ibf_pae) := r.srpae;
idout(sr_ibf_rle) := r.srrle;
idout(sr_ibf_bte) := r.srbte;
idout(sr_ibf_nxm) := r.srnxm;
idout(sr_ibf_tur) := r.crrdy; -- FIXME: is this correct ??
-- only units 0,..3 supported, for unit 4,..,7 return 0 --> ONL=0
if r.crunit2 = '0' then
idout(sr_ibf_eof) := r.sreof(to_integer(unsigned(r.crunit)));
idout(sr_ibf_eot) := r.sreot(to_integer(unsigned(r.crunit)));
idout(sr_ibf_onl) := r.sronl(to_integer(unsigned(r.crunit)));
idout(sr_ibf_bot) := r.srbot(to_integer(unsigned(r.crunit)));
idout(sr_ibf_wrl) := r.srwrl(to_integer(unsigned(r.crunit)));
idout(sr_ibf_rew) := r.srrew(to_integer(unsigned(r.crunit)));
end if;
when ibaddr_cr => -- CR -- control register ---------
idout(cr_ibf_err) := r.sricmd or
r.sreof(to_integer(unsigned(r.crunit))) or
r.srpae or
r.sreot(to_integer(unsigned(r.crunit))) or
r.srrle or
r.srnxm;
idout(cr_ibf_den) := r.crden;
idout(cr_ibf_pevn) := r.crpevn;
idout(cr_ibf_unit2) := r.crunit2;
idout(cr_ibf_unit) := r.crunit;
idout(cr_ibf_rdy) := r.crrdy;
idout(cr_ibf_ie) := r.crie;
idout(cr_ibf_ea) := r.crea;
idout(cr_ibf_func) := r.crfunc;
 
if IB_MREQ.we = '1' then
if ibrem = '0' then
 
if r.crrdy = '1' then
if IB_MREQ.be1 = '1' then
n.crden := IB_MREQ.din(cr_ibf_den);
if IB_MREQ.din(cr_ibf_ini) = '1' then
n.resreq := '1';
end if;
n.crpevn := IB_MREQ.din(cr_ibf_pevn);
n.crunit2 := IB_MREQ.din(cr_ibf_unit2);
n.crunit := IB_MREQ.din(cr_ibf_unit);
end if;
if IB_MREQ.be0 = '1' then
n.crie := IB_MREQ.din(cr_ibf_ie);
if n.crie = '0' then -- if IE set to 0
n.ireq := '0'; -- cancel pending interrupt
end if;
n.crea := IB_MREQ.din(cr_ibf_ea);
n.crfunc := IB_MREQ.din(cr_ibf_func);
if IB_MREQ.din(cr_ibf_go) = '1' then
n.sricmd := '0'; -- clear errors
n.srpae := '0';
n.srrle := '0';
n.srbte := '0';
n.srnxm := '0';
n.sreof := (others=>'0'); -- clear position status flags
n.sreot := (others=>'0');
n.srbot := (others=>'0');
n.srrew := (others=>'0');
n.crrdy := '0'; -- mark busy
ilam := '1'; -- rri lam
else
if r.crie='0' and n.crie='1' then -- if IDE 0->1 transition
n.ireq := '1'; -- issue software interrupt
end if;
end if;
end if;
else
n.sricmd := '1';
end if;
else -- rem write access. GO not checked
-- always treated as remote function
case IB_MREQ.din(cr_ibf_func) is
when rfunc_wunit => -- rfunc: wunit -----------------
n.runit := IB_MREQ.din(cr_ibf_runit);
when rfunc_done => -- rfunc: done ------------------
n.sricmd := IB_MREQ.din(cr_ibf_ricmd);
n.srpae := IB_MREQ.din(cr_ibf_rpae);
n.srrle := IB_MREQ.din(cr_ibf_rrle);
n.srbte := IB_MREQ.din(cr_ibf_rbte);
n.srnxm := IB_MREQ.din(cr_ibf_rnxm);
if IB_MREQ.din(cr_ibf_reaena) = '1' then
n.crea := IB_MREQ.din(cr_ibf_rea);
end if;
n.crrdy := '1';
if r.crie = '1' then
n.ireq := '1';
end if;
when others => null; -- <>
end case;
 
end if; -- if ibrem
 
end if; -- if IB_MREQ.we='1'
 
when ibaddr_bc => -- BC -- byte count register -------
idout := r.bc;
if ibw1 = '1' then
n.bc(15 downto 8) := IB_MREQ.din(15 downto 8);
end if;
if ibw0 = '1' then
n.bc( 7 downto 0) := IB_MREQ.din( 7 downto 0);
end if;
when ibaddr_ba => -- BA -- bus address register ------
idout(ba_ibf_ba) := r.ba;
if ibw1 = '1' then
n.ba(15 downto 8) := IB_MREQ.din(15 downto 8);
end if;
if ibw0 = '1' then
n.ba( 7 downto 1) := IB_MREQ.din( 7 downto 1);
end if;
 
when ibaddr_db => -- DB -- data buffer ---------------
null;
when ibaddr_rl => -- RL -- read lines ----------------
if ibrem = '0' then
null;
else
idout(rl_ibf_reof) := r.sreof(to_integer(unsigned(r.runit)));
idout(rl_ibf_reot) := r.sreot(to_integer(unsigned(r.runit)));
idout(rl_ibf_ronl) := r.sronl(to_integer(unsigned(r.runit)));
idout(rl_ibf_rbot) := r.srbot(to_integer(unsigned(r.runit)));
idout(rl_ibf_rwrl) := r.srwrl(to_integer(unsigned(r.runit)));
idout(rl_ibf_rrew) := r.srrew(to_integer(unsigned(r.runit)));
idout(rl_ibf_runit) := r.runit;
if IB_MREQ.we = '1' then
n.sreof(to_integer(unsigned(r.runit))) := IB_MREQ.din(rl_ibf_reof);
n.sreot(to_integer(unsigned(r.runit))) := IB_MREQ.din(rl_ibf_reot);
n.sronl(to_integer(unsigned(r.runit))) := IB_MREQ.din(rl_ibf_ronl);
n.srbot(to_integer(unsigned(r.runit))) := IB_MREQ.din(rl_ibf_rbot);
n.srwrl(to_integer(unsigned(r.runit))) := IB_MREQ.din(rl_ibf_rwrl);
n.srrew(to_integer(unsigned(r.runit))) := IB_MREQ.din(rl_ibf_rrew);
end if;
end if;
when others => -- doesn't happen, ibsel only for
-- subrange up to rl, and all regs are
-- decoded above
null;
end case;
end if;
 
if BRESET = '1' then
n.resreq := '1';
end if;
if r.resreq = '1' then
n.sricmd := '0';
n.srpae := '0';
n.srrle := '0';
n.srbte := '0';
n.srnxm := '0';
n.sreof := (others=>'0');
n.sreot := (others=>'0');
n.crden := (others=>'0');
n.crpevn := '0';
n.crunit2 := '0';
n.crunit := (others=>'0');
n.crrdy := '1';
n.crie := '0';
n.crea := (others=>'0');
n.crfunc := (others=>'0');
n.bc := (others=>'0');
n.ba := (others=>'0');
n.resreq := '0';
n.ireq := '0';
end if;
if EI_ACK = '1' or n.crie = '0' then -- interrupt executed or ie disabled
n.ireq := '0'; -- cancel request
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;
/ibdr_rhrp.vhd
0,0 → 1,1462
-- $Id: ibdr_rhrp.vhd 692 2015-06-21 11:53:24Z mueller $
--
-- Copyright 2015- 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_rhrp - syn
-- Description: ibus dev(rem): RHRP
--
-- Dependencies: ram_1swar_gen
-- Test bench: -
-- Target Devices: generic
-- Tool versions: ise 14.7; viv 2014.4; ghdl 0.31
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2015-06-20 692 14.7 131013 xc6slx16-2 212 406 8 142 s 8.7
-- 2015-05-14 680 14.7 131013 xc6slx16-2 211 408 8 131 s 8.8
-- 2015-04-06 664 14.7 131013 xc6slx16-2 177 331 8 112 s 8.7
--
-- Revision History:
-- Date Rev Version Comment
-- 2015-06-20 692 1.0.3 BUGFIX: fix func-go when drive/init busy checks
-- 2015-06-05 690 1.0.2 use 'not unit' for lsb of rpsn to avoid SI detect
-- BUGFIX: set rmr only for write to busy unit
-- 2015-05-15 682 1.0.1 correct ibsel range select logic
-- 2015-05-14 680 1.0 Initial version
-- 2015-03-15 658 0.1 First draft
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
use work.memlib.all;
use work.iblib.all;
 
-- ----------------------------------------------------------------------------
entity ibdr_rhrp is -- ibus dev(rem): RH+RP
-- fixed address: 176700
port (
CLK : in slbit; -- clock
CE_USEC : in slbit; -- usec pulse
BRESET : in slbit; -- ibus reset
ITIMER : in slbit; -- instruction timer
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
);
 
-- by default xst uses a binary encoding for the main fsm.
-- that give quite sub-optimal results, so force one-hot
attribute fsm_encoding : string;
attribute fsm_encoding of ibdr_rhrp : entity is "one-hot";
end entity ibdr_rhrp;
 
architecture syn of ibdr_rhrp is
 
constant ibaddr_rhrp : slv16 := slv(to_unsigned(8#176700#,16));
 
-- nam rw mb rp rm storage
constant ibaddr_cs1 : slv5 := "00000"; -- cs1 rw 0 rpcs1 rmcs1 m d,6+r
constant ibaddr_wc : slv5 := "00001"; -- wc rw - rpwc rmwc m 0,7
constant ibaddr_ba : slv5 := "00010"; -- ba rw - rpba rmba m 1,7
constant ibaddr_da : slv5 := "00011"; -- da rw 5 rpda rmda m d,0
constant ibaddr_cs2 : slv5 := "00100"; -- cs2 rw - rpcs2 rmcs2 r cs2*
constant ibaddr_ds : slv5 := "00101"; -- ds r- 1 rpds rmds r ds*
constant ibaddr_er1 : slv5 := "00110"; -- er1 rw 2 rper1 rmer1 r er1*
constant ibaddr_as : slv5 := "00111"; -- as rw 4 rpas rmas r as*
constant ibaddr_la : slv5 := "01000"; -- la r- 7 rpla rmla r sc
constant ibaddr_db : slv5 := "01001"; -- db r? - rpdb rmdb m 2,7
constant ibaddr_mr1 : slv5 := "01010"; -- mr1 rw 3 rpmr1 rmmr1 m d,3
constant ibaddr_dt : slv5 := "01011"; -- dt r- 6 rpdt rmdt r dt*+map
constant ibaddr_sn : slv5 := "01100"; -- sn r- 10 rpsn rmsn <map>
constant ibaddr_of : slv5 := "01101"; -- of rw 11 rpof rmof m d,1
constant ibaddr_dc : slv5 := "01110"; -- dc rw 12 rpdc rmdc m d,2
constant ibaddr_m13 : slv5 := "01111"; -- m13 rw 13 rpcc m =dc!
-- rw 13 rmhr m d,4
constant ibaddr_m14 : slv5 := "10000"; -- m14 rw 14 rper2 =0
-- rw 14 rmmr2 m d,5
constant ibaddr_m15 : slv5 := "10001"; -- m15 rw 15 rper3 =0
-- rw 15 rmer2 =0
constant ibaddr_ec1 : slv5 := "10010"; -- ec1 r- 16 rpec1 rmec1 =0
constant ibaddr_ec2 : slv5 := "10011"; -- ec1 r- 17 rpec2 rmec2 =0
constant ibaddr_bae : slv5 := "10100"; -- bae rw - rpbae rmbae r bae
constant ibaddr_cs3 : slv5 := "10101"; -- cs3 rw - rpcs3 rmcs3 r cs3*
 
constant omux_cs1 : slv4 := "0000";
constant omux_cs2 : slv4 := "0001";
constant omux_ds : slv4 := "0010";
constant omux_er1 : slv4 := "0011";
constant omux_as : slv4 := "0100";
constant omux_la : slv4 := "0101";
constant omux_dt : slv4 := "0110";
constant omux_sn : slv4 := "0111";
constant omux_bae : slv4 := "1000";
constant omux_cs3 : slv4 := "1001";
constant omux_mem : slv4 := "1010";
constant omux_zero : slv4 := "1111";
 
constant amapc_da : slv3 := "000";
constant amapc_mr1 : slv3 := "011";
constant amapc_of : slv3 := "001";
constant amapc_dc : slv3 := "010";
constant amapc_hr : slv3 := "100";
constant amapc_mr2 : slv3 := "101";
constant amapc_cs1 : slv3 := "110";
constant amapc_ext : slv3 := "111";
 
constant amapr_wc : slv2 := "00";
constant amapr_ba : slv2 := "01";
constant amapr_db : slv2 := "10";
 
subtype amap_f_unit is integer range 4 downto 3; -- unit part
subtype amap_f_reg is integer range 2 downto 0; -- reg part
 
constant clrmode_breset : slv2 := "00";
constant clrmode_cs2clr : slv2 := "01";
constant clrmode_fdclr : slv2 := "10";
constant clrmode_fpres : slv2 := "11";
constant cs1_ibf_sc : integer := 15; -- special condition
constant cs1_ibf_tre : integer := 14; -- transfer error
constant cs1_ibf_dva : integer := 11; -- drive available
subtype cs1_ibf_bae is integer range 9 downto 8; -- bus addr ext (1:0)
constant cs1_ibf_rdy : integer := 7; -- controller ready
constant cs1_ibf_ie : integer := 6; -- interrupt enable
subtype cs1_ibf_func is integer range 5 downto 1; -- function code
constant cs1_ibf_go : integer := 0; -- interrupt enable
 
constant func_noop : slv5 := "00000"; -- func: noop
constant func_unl : slv5 := "00001"; -- func: unload
constant func_seek : slv5 := "00010"; -- func: seek
constant func_recal : slv5 := "00011"; -- func: recalibrate
constant func_dclr : slv5 := "00100"; -- func: drive clear
constant func_pore : slv5 := "00101"; -- func: port release
constant func_offs : slv5 := "00110"; -- func: offset
constant func_retc : slv5 := "00111"; -- func: return to center
constant func_pres : slv5 := "01000"; -- func: readin preset
constant func_pack : slv5 := "01001"; -- func: pack acknowledge
constant func_sear : slv5 := "01100"; -- func: search
constant func_xfer : slv5 := "10100"; -- used to check for xfer type funcs
constant func_wcd : slv5 := "10100"; -- func: write check data
constant func_wchd : slv5 := "10101"; -- func: write check header&data
constant func_write : slv5 := "11000"; -- func: write
constant func_whd : slv5 := "11001"; -- func: write header&data
constant func_read : slv5 := "11100"; -- func: read
constant func_rhd : slv5 := "11101"; -- func: read header&data
 
constant rfunc_wunit : slv5 := "00001"; -- rem func: write runit
constant rfunc_cunit : slv5 := "00010"; -- rem func: copy funit->runit
constant rfunc_done : slv5 := "00011"; -- rem func: done (set rdy)
constant rfunc_widly : slv5 := "00100"; -- rem func: write idly
 
-- cs1 usage for rem functions
subtype cs1_ibf_runit is integer range 9 downto 8; -- new runit (_wunit)
constant cs1_ibf_rata : integer := 8; -- use ata (_done)
subtype cs1_ibf_ridly is integer range 15 downto 8; -- new idly (_widly)
 
subtype da_ibf_ta is integer range 12 downto 8; -- track addr
subtype da_ibf_sa is integer range 5 downto 0; -- sector addr
 
constant cs2_ibf_rwco : integer := 15; -- rem: write check odd word
constant cs2_ibf_wce : integer := 14; -- write check error
constant cs2_ibf_ned : integer := 12; -- non-existent drive
constant cs2_ibf_nem : integer := 11; -- non-existent memory
constant cs2_ibf_pge : integer := 10; -- programming error
constant cs2_ibf_mxf : integer := 9; -- missed transfer
constant cs2_ibf_or : integer := 7; -- output ready
constant cs2_ibf_ir : integer := 6; -- input ready
constant cs2_ibf_clr : integer := 5; -- clear controller
constant cs2_ibf_pat : integer := 4; -- parity test
constant cs2_ibf_bai : integer := 3; -- bus address inhibit
constant cs2_ibf_unit2 : integer := 2; -- unit select msb
subtype cs2_ibf_unit is integer range 1 downto 0; -- unit select
 
constant ds_ibf_ata : integer := 15; -- attention
constant ds_ibf_erp : integer := 14; -- any errors in er1 or er2
constant ds_ibf_pip : integer := 13; -- positioning in progress
constant ds_ibf_mol : integer := 12; -- medium online (ATTACHED)
constant ds_ibf_wrl : integer := 11; -- write locked
constant ds_ibf_lbt : integer := 10; -- last block transfered
constant ds_ibf_dpr : integer := 8; -- drive present (ENABLED)
constant ds_ibf_dry : integer := 7; -- drive ready
constant ds_ibf_vv : integer := 6; -- volume valid
constant ds_ibf_om : integer := 0; -- offset mode
 
constant er1_ibf_uns : integer := 14; -- drive unsafe
constant er1_ibf_wle : integer := 11; -- write lock error
constant er1_ibf_iae : integer := 10; -- invalid address error
constant er1_ibf_aoe : integer := 9; -- address overflow error
constant er1_ibf_rmr : integer := 2; -- register modification refused
constant er1_ibf_ilf : integer := 0; -- illegal function
 
subtype la_ibf_sc is integer range 11 downto 6; -- current sector
 
constant dt_ibf_rm : integer := 2; -- rm cntl
constant dt_ibf_e1 : integer := 1; -- encoded type bit 1
constant dt_ibf_e0 : integer := 0; -- encoded type bit 0
 
constant dte_rp04 : slv3 := "000"; -- encoded dt for rp04 rm=0
constant dte_rp06 : slv3 := "001"; -- encoded dt for rp06 rm=0
constant dte_rm03 : slv3 := "100"; -- encoded dt for rm03 rm=1
constant dte_rm80 : slv3 := "101"; -- encoded dt for rm80 rm=1
constant dte_rm05 : slv3 := "110"; -- encoded dt for rm05 rm=1
constant dte_rp07 : slv3 := "111"; -- encoded dt for rp07 rm=1
 
subtype dc_ibf_ca is integer range 9 downto 0; -- cyclinder addr
 
subtype bae_ibf_bae is integer range 5 downto 0; -- bus addr ext.
 
constant cs3_ibf_wco : integer := 12; -- write check odd
constant cs3_ibf_wce : integer := 11; -- write check even
constant cs3_ibf_ie : integer := 6; -- interrupt enable
constant cs3_ibf_rseardone : integer := 3; -- rem: sear done flag
constant cs3_ibf_rpackdone : integer := 2; -- rem: pack done flag
constant cs3_ibf_rporedone : integer := 1; -- rem: pore done flag
constant cs3_ibf_rseekdone : integer := 0; -- rem: seek done flag
 
-- RP controller type disks
constant rp04_dtyp : slv6 := slv(to_unsigned( 8#20#, 6));
constant rp04_camax : slv10 := slv(to_unsigned( 411-1, 10));
constant rp04_tamax : slv5 := slv(to_unsigned( 19-1, 5));
constant rp04_samax : slv6 := slv(to_unsigned( 22-1, 6));
constant rp06_dtyp : slv6 := slv(to_unsigned( 8#22#, 6));
constant rp06_camax : slv10 := slv(to_unsigned( 815-1, 10));
constant rp06_tamax : slv5 := slv(to_unsigned( 19-1, 5));
constant rp06_samax : slv6 := slv(to_unsigned( 22-1, 6));
-- RM controller type disks (Note: rp07 has a RM stype controller!)
constant rm03_dtyp : slv6 := slv(to_unsigned( 8#24#, 6));
constant rm03_camax : slv10 := slv(to_unsigned( 823-1, 10));
constant rm03_tamax : slv5 := slv(to_unsigned( 5-1, 5));
constant rm03_samax : slv6 := slv(to_unsigned( 32-1, 6));
constant rm80_dtyp : slv6 := slv(to_unsigned( 8#26#, 6));
constant rm80_camax : slv10 := slv(to_unsigned( 559-1, 10));
constant rm80_tamax : slv5 := slv(to_unsigned( 14-1, 5));
constant rm80_samax : slv6 := slv(to_unsigned( 31-1, 6));
constant rm05_dtyp : slv6 := slv(to_unsigned( 8#27#, 6));
constant rm05_camax : slv10 := slv(to_unsigned( 823-1, 10));
constant rm05_tamax : slv5 := slv(to_unsigned( 19-1, 5));
constant rm05_samax : slv6 := slv(to_unsigned( 32-1, 6));
constant rp07_dtyp : slv6 := slv(to_unsigned( 8#42#, 6));
constant rp07_camax : slv10 := slv(to_unsigned( 630-1, 10));
constant rp07_tamax : slv5 := slv(to_unsigned( 32-1, 5));
constant rp07_samax : slv6 := slv(to_unsigned( 50-1, 6));
 
type state_type is (
s_idle, -- idle: handle ibus
s_wcs1, -- wcs1: write cs1
s_wcs2, -- wcs2: write cs2
s_wcs3, -- wcs3: write cs3
s_wer1, -- wer1: write er1 (rem only)
s_was, -- was: write as
s_wdt, -- wdt: write dt (rem only)
s_wds, -- wdt: write ds (rem only)
s_wbae, -- wbae: write bae
s_wmem, -- wmem: write mem (DA,MR1,OF,DC,MR2)
s_wmembe, -- wmem: write mem with be (WC,BA,DB)
s_whr, -- whr: write hr (holding reg only)
s_funcchk, -- funcchk: check function go
s_funcgo, -- funcgo: handle function go
s_chkdc, -- chkdc: handle dc check
s_chkda, -- chksa: handle da check
s_chkdo, -- chkdo: execute function
s_read, -- read: all register reads
s_setrmr, -- set rmr flag
s_oot_clr0, -- OOT clr0: state 0
s_oot_clr1, -- OOT clr1: state 1
s_oot_clr2 -- OOT clr2: state 2
);
 
type regs_type is record -- state registers
ibsel : slbit; -- ibus select
state : state_type; -- state
amap : slv5; -- mem mapped address
omux : slv4; -- omux select
dinmsk : slv16; -- mbreq.din masked
dtrm : slv4; -- dt: drive rm controller
dte1 : slv4; -- dt: drive type bit 1
dte0 : slv4; -- dt: drive type bit 0
bae : slv6; -- bae: bus addr extension (in cs1&bae)
cs1sc : slbit; -- cs1: special condition
cs1tre : slbit; -- cs1: transfer error
cs1rdy : slbit; -- cs1: controller ready
cs1ie : slbit; -- cs1: interrupt enable
ffunc : slv5; -- func code (frozen on ext func go)
fxfer : slbit; -- func is xfer
cs2wce : slbit; -- cs2: write check error
cs2ned : slbit; -- cs2: non-existent drive
cs2nem : slbit; -- cs2: non-existent memory
cs2pge : slbit; -- cs2: programming error
cs2mxf : slbit; -- cs2: missed transfer
cs2pat : slbit; -- cs2: parity test
cs2bai : slbit; -- cs2: bus address inhibit
cs2unit2: slbit; -- cs2: unit lsb
cs2unit : slv2; -- unit (ibus view)
funit : slv2; -- unit (frozen on ext func go)
runit : slv2; -- unit (remote view)
eunit : slv2; -- unit (effective)
dsata : slv4; -- ds: attention
dserp : slv4; -- ds: error summary (or of er1+er2)
dspip : slv4; -- ds: positioning in progress
dsmol : slv4; -- ds: medium online (ATTACHED)
dswrl : slv4; -- ds: write locked
dslbt : slv4; -- ds: last block transfered
dsdpr : slv4; -- ds: drive present (ENABLED)
dsvv : slv4; -- ds: volume valid
dsom : slv4; -- ds: offset mode
er1uns : slv4; -- er1: dive unsafe
er1wle : slv4; -- er1: write lock error
er1iae : slv4; -- er1: invalid address error
er1aoe : slv4; -- er1: address overflow error
er1rmr : slv4; -- er1: register modificaton refused
er1ilf : slv4; -- er1: illegal function
cs3wco : slbit; -- cs3: write check odd word
idlyval : slv8; -- int delay value
idlycnt : slv8; -- int delay counter
seekdone: slbit; -- cs3 rem: seek done
poredone: slbit; -- cs3 rem: port rel done
packdone: slbit; -- cs3 rem: pack ack done
seardone: slbit; -- cs3 rem: search done
ned : slbit; -- current drive non-existent
cerm : slbit; -- current eff. drive rm controller
dtyp : slv6; -- current drive type (5:0)
camax : slv10; -- current max cylinder address
tamax : slv5; -- current max track address
samax : slv6; -- current max sector address
uscnt : slv7; -- usec counter
sc : slv6; -- current sector counter
clrmode : slv2; -- clear: mode
clrreg : slv3; -- clear: register counter
ireq : slbit; -- interrupt request flag
end record regs_type;
 
constant regs_init : regs_type := (
'0', -- ibsel
s_idle, -- state
(others=>'0'), -- amap,
(others=>'0'), -- omux,
(others=>'0'), -- dinmsk,
(others=>'0'), -- dtrm
(others=>'0'), -- dte1
(others=>'0'), -- dte0
(others=>'0'), -- bae,
'0','0','1','0', -- cs1sc,cs1tre,cs1rdy,cs1ie
(others=>'0'), -- ffunc
'0', -- fxfer
'0','0','0','0', -- cs2wce,cs2ned,cs2nem,cs2pge
'0','0','0', -- cs2mxf,cs2pat,cs2bai
'0', -- cs2unit2
(others=>'0'), -- cs2unit
(others=>'0'), -- funit
(others=>'0'), -- runit
(others=>'0'), -- eunit
(others=>'0'), -- dsata
(others=>'0'), -- dserp
(others=>'0'), -- dspip
(others=>'0'), -- dsmol
(others=>'0'), -- dswrl
(others=>'0'), -- dslbt
(others=>'0'), -- dsdpr
(others=>'0'), -- dsvv
(others=>'0'), -- dsom
(others=>'0'), -- er1uns
(others=>'0'), -- er1wle
(others=>'0'), -- er1iae
(others=>'0'), -- er1aoe
(others=>'0'), -- er1rmr
(others=>'0'), -- er1ilf
'0', -- cs3wco
x"0a", -- idlyval (default delay=10)
(others=>'0'), -- idlycnt
'0','0','0','0', -- seekdone,poredone,packdone,seardone
'0','0', -- ned,cerm
(others=>'0'), -- dtyp
(others=>'0'), -- camax
(others=>'0'), -- tamax
(others=>'0'), -- samax
(others=>'0'), -- uscnt
(others=>'0'), -- sc
(others=>'0'), -- clrmode
(others=>'0'), -- clrreg
'0' -- ireq
);
 
signal R_REGS : regs_type := regs_init;
signal N_REGS : regs_type := regs_init;
 
signal MEM_1_WE : slbit := '0';
signal MEM_0_WE : slbit := '0';
signal MEM_ADDR : slv5 := (others=>'0');
signal MEM_DIN : slv16 := (others=>'0');
signal MEM_DOUT : slv16 := (others=>'0');
 
-- the following is unfortunately not accepted by xst:
-- attribute fsm_encoding : string;
-- attribute fsm_encoding of R_REGS.state : signal is "one-hot";
begin
MEM_1 : ram_1swar_gen
generic map (
AWIDTH => 5,
DWIDTH => 8)
port map (
CLK => CLK,
WE => MEM_1_WE,
ADDR => MEM_ADDR,
DI => MEM_DIN(ibf_byte1),
DO => MEM_DOUT(ibf_byte1));
 
MEM_0 : ram_1swar_gen
generic map (
AWIDTH => 5,
DWIDTH => 8)
port map (
CLK => CLK,
WE => MEM_0_WE,
ADDR => MEM_ADDR,
DI => MEM_DIN(ibf_byte0),
DO => MEM_DOUT(ibf_byte0));
 
proc_regs: process (CLK)
begin
-- BRESET handled in main fsm, not here !!
if rising_edge(CLK) then
R_REGS <= N_REGS;
end if;
end process proc_regs;
 
proc_next : process (R_REGS, CE_USEC, BRESET, ITIMER, IB_MREQ, MEM_DOUT,
EI_ACK)
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';
variable iei_req : slbit := '0';
 
variable imem_we0 : slbit := '0';
variable imem_we1 : slbit := '0';
variable imem_addr : slv5 := (others=>'0');
variable imem_din : slv16 := (others=>'0');
 
variable ieunit : slv2 := (others=>'0');
 
variable iomux : slv4 := (others=>'0'); -- omux select
variable iamap : slv5 := (others=>'0'); -- mem mapped address
variable imask : slv16 := (others=>'0'); -- implemented bits mask
variable imbreg : slbit := '0'; -- massbus register
variable inormr : slbit := '0'; -- inhibit rmr protect
 
variable idte : slv3 := (others=>'0'); -- encoded drive type
variable idtyp : slv6 := (others=>'0'); -- drive type (5:0)
variable icamax : slv10 := (others=>'0'); -- max cylinder address
variable itamax : slv5 := (others=>'0'); -- max track address
variable isamax : slv6 := (others=>'0'); -- max sector address
 
variable ined : slbit := '0'; -- non-existent drive
variable icerm : slbit := '0'; -- effectiv drive is rm
 
variable iclrreg : slbit := '0'; -- clr enable
 
variable iscinc : slbit := '0'; -- increment r.sc enable
 
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';
iei_req := '0';
imem_we0 := '0';
imem_we1 := '0';
imem_addr := r.amap; -- default address (from mapper)
imem_din := r.dinmsk; -- default input (from masker)
 
ieunit := (others=>'0');
 
iomux := (others=>'0');
iamap := (others=>'0');
imask := (others=>'1'); -- default: all bits ok
imbreg := '0';
inormr := '0';
 
idte := (others=>'0');
idtyp := (others=>'0');
icamax := (others=>'0');
itamax := (others=>'0');
isamax := (others=>'0');
 
ined := '0';
icerm := '0';
 
iclrreg := '0';
 
iscinc := '0';
 
-- ibus address decoder, accept only offsets 0 to ibaddr_cs3
n.ibsel := '0';
if IB_MREQ.aval = '1' and
IB_MREQ.addr(12 downto 6) = ibaddr_rhrp(12 downto 6) and
unsigned(IB_MREQ.addr(5 downto 1)) <= unsigned(ibaddr_cs3) then
n.ibsel := '1';
end if;
-- internal state machine
case r.state is
when s_idle => -- idle: handle ibus -----------------
 
if r.ibsel='1' then -- selected
 
-- determine effective unit number
if ibrem = '1' then
ieunit := r.runit;
else
ieunit := r.cs2unit;
end if;
n.eunit := ieunit;
 
-- determine drive properties (always via iunit) FIXME: correct ??
idte(2) := r.dtrm(to_integer(unsigned(r.cs2unit)));
idte(1) := r.dte1(to_integer(unsigned(r.cs2unit)));
idte(0) := r.dte0(to_integer(unsigned(r.cs2unit)));
case idte is
when dte_rp04 => -- RP04
idtyp := rp04_dtyp;
icamax := rp04_camax;
itamax := rp04_tamax;
isamax := rp04_samax;
when dte_rp06 => -- RP06
idtyp := rp06_dtyp;
icamax := rp06_camax;
itamax := rp06_tamax;
isamax := rp06_samax;
when dte_rm03 => -- RM03
idtyp := rm03_dtyp;
icamax := rm03_camax;
itamax := rm03_tamax;
isamax := rm03_samax;
when dte_rm80 => -- RM80
idtyp := rm80_dtyp;
icamax := rm80_camax;
itamax := rm80_tamax;
isamax := rm80_samax;
when dte_rm05 => -- RM05
idtyp := rm05_dtyp;
icamax := rm05_camax;
itamax := rm05_tamax;
isamax := rm05_samax;
when dte_rp07 => -- RP07
idtyp := rp07_dtyp;
icamax := rp07_camax;
itamax := rp07_tamax;
isamax := rp07_samax;
when others =>
idtyp := (others=>'0');
icamax := (others=>'0');
itamax := (others=>'0');
isamax := (others=>'0');
end case; -- case idte
n.dtyp := idtyp;
n.camax := icamax;
n.tamax := itamax;
n.samax := isamax;
 
-- consider drive non-existent if not 'DPR' or unit>=4 selected
if r.dsdpr(to_integer(unsigned(r.cs2unit))) = '0' or
r.cs2unit2 = '1' then
ined := '1';
end if;
n.ned := ined;
icerm := r.dtrm(to_integer(unsigned(ieunit)));
n.cerm := icerm;
-- setup mapper
case IB_MREQ.addr(5 downto 1) is
 
when ibaddr_cs1 => -- RxCS1 control reg 1
-- cs1 not flagged mbreg !! ned handling done explicitely
iamap := ieunit & amapc_cs1;
iomux := omux_cs1;
 
when ibaddr_wc => -- RxWC word count
iamap := amapr_wc & amapc_ext;
iomux := omux_mem;
 
when ibaddr_ba => -- RxBA bus address
imask := "1111111111111110"; -- lsb ignored
iamap := amapr_ba & amapc_ext;
iomux := omux_mem;
 
when ibaddr_da => -- RxDA disk address
imask := "0001111100111111"; -- 000t tttt 00ss ssss
iamap := ieunit & amapc_da;
iomux := omux_mem;
imbreg := '1'; -- mb 5
 
when ibaddr_cs2 => -- RxCS2 control reg 2
iomux := omux_cs2;
 
when ibaddr_ds => -- RxDS drive status
iomux := omux_ds;
imbreg := '1'; -- mb 1
 
when ibaddr_er1 => -- RxER1 error status 1
iomux := omux_er1;
imbreg := '1'; -- mb 2
 
when ibaddr_as => -- RxAS attention summary
iomux := omux_as;
imbreg := '1'; -- mb 4
inormr := '1'; -- AS writes allowed when RDY=0
 
when ibaddr_la => -- RxLA look ahead
iomux := omux_la;
imbreg := '1'; -- mb 7
 
when ibaddr_db => -- RxDB data buffer
iamap := amapr_db & amapc_ext;
iomux := omux_mem;
 
when ibaddr_mr1 => -- RxMR1 maintenance reg 1
iamap := ieunit & amapc_mr1;
iomux := omux_mem;
imbreg := '1'; -- mb 3
inormr := '1'; -- MR1 writes allowed when RDY=0
 
when ibaddr_dt => -- RxDT drive type
iomux := omux_dt;
imbreg := '1'; -- mb 6
 
when ibaddr_sn => -- RxSN serial number
iomux := omux_sn;
imbreg := '1'; -- mb 10
 
when ibaddr_of => -- RxOF offset reg
imask := "0001110011111111"; -- 000f eh00 d??? ????
iamap := ieunit & amapc_of;
iomux := omux_mem;
imbreg := '1'; -- mb 11
 
when ibaddr_dc => -- RxDC desired cylinder
imask := "0000001111111111"; -- 0000 00cc cccc cccc
iamap := ieunit & amapc_dc;
iomux := omux_mem;
imbreg := '1'; -- mb 12
 
when ibaddr_m13 =>
if icerm = '1' then
iamap := ieunit & amapc_hr; -- RMHR holding reg
else
iamap := ieunit & amapc_dc; -- RPDC current cylinder
end if;
iomux := omux_mem;
imbreg := '1'; -- mb 13
 
when ibaddr_m14 =>
if icerm = '1' then
iamap := ieunit & amapc_mr2; -- RMMR2 maintenance reg 2
iomux := omux_mem;
else
iomux := omux_zero; -- RPER2 error status 2
end if;
imbreg := '1'; -- mb 14
 
when ibaddr_m15 => -- RxER3 error status 3/2
iomux := omux_zero;
imbreg := '1'; -- mb 15
 
when ibaddr_ec1 => -- RxEC1 ecc status 1
iomux := omux_zero;
imbreg := '1'; -- mb 16
 
when ibaddr_ec2 => -- RxEC2 ecc status 2
iomux := omux_zero;
imbreg := '1'; -- mb 17
 
when ibaddr_bae => -- RxBAE bus addr extension
iomux := omux_bae;
 
when ibaddr_cs3 => -- RxCS3 control reg 3
iomux := omux_cs3;
when others => null; -- doesn't happen, ibsel only for
-- subrange up to cs3, and all
-- 22 regs are decoded above
end case; -- case IB_MREQ.addr
n.amap := iamap;
n.omux := iomux;
n.dinmsk := imask and IB_MREQ.din;
 
if IB_MREQ.we = '1' then -- write request
ibhold := '1'; -- assume follow-up state taken
case IB_MREQ.addr(5 downto 1) is
when ibaddr_cs1 => n.state := s_wcs1; -- RxCS1
when ibaddr_wc => n.state := s_wmembe; -- RxWC
when ibaddr_ba => n.state := s_wmembe; -- RxBA
when ibaddr_da => n.state := s_wmem; -- RxDA
when ibaddr_cs2 => n.state := s_wcs2; -- RxCS2
when ibaddr_ds => n.state := s_wds; -- RxDS (read-only)
when ibaddr_er1 => n.state := s_wer1; -- RxER1 (read-only)
when ibaddr_as => n.state := s_was; -- RxAS
when ibaddr_la => n.state := s_whr; -- RxLA (read-only)
when ibaddr_db => n.state := s_wmembe; -- RxDB
when ibaddr_mr1 => n.state := s_wmem; -- RxMR1
when ibaddr_dt => n.state := s_wdt; -- RxDT (read-only)
when ibaddr_sn => n.state := s_whr; -- RxSN (read-only)
when ibaddr_of => n.state := s_wmem; -- RxOF
when ibaddr_dc => n.state := s_wmem; -- RxDC
when ibaddr_m13 => n.state := s_whr; -- RPCC|RMHR (fits both)
when ibaddr_m14 =>
if icerm = '1' then
n.state := s_wmem; -- RMMR2
else
n.state := s_whr; -- RPER2
end if;
when ibaddr_m15 => n.state := s_whr; -- RPER3|RMER2 (fits both)
when ibaddr_ec1 => n.state := s_whr; -- RxEC1
when ibaddr_ec2 => n.state := s_whr; -- RxEC2
when ibaddr_bae => n.state := s_wbae; -- RxBAE
when ibaddr_cs3 => n.state := s_wcs3; -- RxCS3
 
when others => null; -- doesn't happen, ibsel only for
-- subrange up to cs3, and all
-- 22 regs are decoded above
end case; -- case IB_MREQ.addr
 
-- some general error catchers
if ibrem = '0' and imbreg='1' then -- local massbus write
-- for cs1: imbreg=0 !!
-- write to non-existent drives
if ined = '1' then
n.cs2ned := '1';
-- write to a busy unit, can be a search/seek or a transfer
elsif inormr='0' and -- rmr protected reg
(r.dspip(to_integer(unsigned(r.cs2unit)))='1' or -- busy pip
(r.cs1rdy='0' and (r.funit = r.cs2unit)) -- busy xfer
) then
n.state := s_setrmr;
end if;
end if;
elsif IB_MREQ.re = '1' then -- read request
if ibrem='0' and imbreg='1' and ined='1' then
n.cs2ned := '1'; -- signal error
else
ibhold := '1';
n.state := s_read;
end if;
 
end if; -- if IB_MREQ.we .. elsif IB_MREQ.re
 
-- BRESET and ITIMER can be handled in the 'else' because both can
-- never come during an ibus transaction. Done here to keep logic
-- path in the 'if' short.
else -- if r.ibsel='1'
if BRESET = '1' then
n.eunit := "00";
n.clrmode := clrmode_breset;
n.state := s_oot_clr0; -- OOT state, no hold!
end if;
 
if unsigned(r.idlycnt) = 0 then -- interrupt delay expired
n.dsata := r.dsata or r.dspip; -- convert pip's to ata's
n.dspip := (others=>'0'); -- and mark them done
else
if ITIMER = '1' then -- not expired and ITIMER
n.idlycnt := slv(unsigned(r.idlycnt) - 1); -- count down
end if;
end if;
end if; -- if r.ibsel='1'
 
-- s_idle goes up to here !!
when s_wcs1 => -- wcs1: write cs1 -------------------
n.state := s_idle; -- in general return to s_idle
imem_addr := r.amap; -- use mapped address
imem_din := r.dinmsk; -- use masked input
 
if ibrem = '0' then -- loc write access
 
if IB_MREQ.be1 = '1' then
if IB_MREQ.din(cs1_ibf_tre) = '1' then -- TRE=1 -> clear errors
n.cs2wce := '0';
n.cs2ned := '0';
n.cs2nem := '0';
n.cs2pge := '0';
n.cs2mxf := '0';
end if;
if r.cs1rdy = '1' then -- only if RDY
n.bae(1 downto 0) := IB_MREQ.din(cs1_ibf_bae); -- update bae
end if;
end if; -- IB_MREQ.be1 = '1'
 
if IB_MREQ.be0 = '1' then
n.cs1ie := IB_MREQ.din(cs1_ibf_ie);
if IB_MREQ.din(cs1_ibf_ie) = '1' and -- if IE and RDY both 1
IB_MREQ.din(cs1_ibf_rdy) = '1'then
n.ireq := '1'; -- issue software interrupt
end if;
if r.ned = '0' and -- drive on
IB_MREQ.din(cs1_ibf_go) = '1' then -- GO bit set
ibhold := '1';
n.state := s_funcchk;
end if;
 
-- FIXME_code: that's likely not fully correct, cs1 func bits are
-- stored before all error checks are done...
imem_we0 := IB_MREQ.be0; -- remember func field per unit
 
if r.ned = '1' then -- loc access and drive off
n.cs2ned := '1'; -- signal error
end if;
 
end if; -- IB_MREQ.be0 = '1'
 
else -- rem write access. GO not checked
-- always treated as remote function
case IB_MREQ.din(cs1_ibf_func) is
 
when rfunc_wunit => -- rfunc: wunit ---------------
n.runit := IB_MREQ.din(cs1_ibf_runit);
 
when rfunc_cunit => -- rfunc: cunit ---------------
n.runit := r.funit; -- use unit from last ext func go
 
when rfunc_done => -- rfunc: done ----------------
n.cs1rdy := '1';
if IB_MREQ.din(cs1_ibf_rata) = '0' then
n.ireq := r.cs1ie; -- yes, ireq is set from ie !!
else
n.dsata(to_integer(unsigned(r.funit))) := '1';
end if;
 
when rfunc_widly => -- rfunc: widly ---------------
n.idlyval := IB_MREQ.din(cs1_ibf_ridly);
 
when others => null;
 
end case;
end if;
when s_wcs2 => -- wcs2: write cs2 -------------------
n.state := s_idle; -- in general return to s_idle
if ibrem = '1' then -- rem access
n.cs3wco := IB_MREQ.din(cs2_ibf_rwco); -- cs3.wco rem set via cs2 !!
n.cs2wce := IB_MREQ.din(cs2_ibf_wce);
n.cs2nem := IB_MREQ.din(cs2_ibf_nem);
n.cs2mxf := IB_MREQ.din(cs2_ibf_mxf); -- FIXME: really used ???
else
if IB_MREQ.be0 = '1' then
n.cs2pat := IB_MREQ.din(cs2_ibf_pat);
n.cs2bai := IB_MREQ.din(cs2_ibf_bai);
n.cs2unit2 := IB_MREQ.din(cs2_ibf_unit2);
n.cs2unit := IB_MREQ.din(cs2_ibf_unit);
if IB_MREQ.din(cs2_ibf_clr) = '1' then
n.eunit := "00";
n.clrmode := clrmode_cs2clr;
n.state := s_oot_clr0; -- OOT state, no hold!
end if;
end if;
end if;
 
when s_wcs3 => -- wcs3: write cs3 -------------------
n.state := s_idle; -- in general return to s_idle
if ibrem = '0' then -- loc access
if IB_MREQ.be0 = '1' then
n.cs1ie := IB_MREQ.din(cs3_ibf_ie);
end if;
end if;
when s_wer1 => -- wer1: write er1 (rem only) --------
n.state := s_idle; -- in general return to s_idle
if ibrem = '1' then -- rem access
if IB_MREQ.din(er1_ibf_uns) = '1' then
n.er1uns(to_integer(unsigned(r.eunit))) := '1';
end if;
if IB_MREQ.din(er1_ibf_wle) = '1' then
n.er1wle(to_integer(unsigned(r.eunit))) := '1';
end if;
if IB_MREQ.din(er1_ibf_iae) = '1' then
n.er1iae(to_integer(unsigned(r.eunit))) := '1';
end if;
if IB_MREQ.din(er1_ibf_aoe) = '1' then
n.er1aoe(to_integer(unsigned(r.eunit))) := '1';
end if;
if IB_MREQ.din(er1_ibf_ilf) = '1' then
n.er1ilf(to_integer(unsigned(r.eunit))) := '1';
end if;
else -- loc access
ibhold := '1';
n.state := s_whr;
end if;
 
when s_was => -- was: write as ---------------------
n.state := s_idle; -- in general return to s_idle
-- clear the attention bits marked as '1' in data word (loc and rem !!)
n.dsata := r.dsata and not IB_MREQ.din(r.dsata'range);
if ibrem = '0' then -- loc access
ibhold := '1';
n.state := s_whr;
end if;
when s_wdt => -- wdt: write dt ---------------------
n.state := s_idle; -- in general return to s_idle
if ibrem = '1' then -- rem access
n.dtrm(to_integer(unsigned(r.runit))) := IB_MREQ.din(dt_ibf_rm);
n.dte1(to_integer(unsigned(r.runit))) := IB_MREQ.din(dt_ibf_e1);
n.dte0(to_integer(unsigned(r.runit))) := IB_MREQ.din(dt_ibf_e0);
n.state := s_idle;
else -- loc access
ibhold := '1';
n.state := s_whr;
end if;
when s_wds => -- wdt: write ds ---------------------
n.state := s_idle; -- in general return to s_idle
if ibrem = '1' then -- rem access
n.dsmol(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_mol);
n.dswrl(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_wrl);
n.dslbt(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_lbt);
n.dsdpr(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_dpr);
if IB_MREQ.din(ds_ibf_ata) = '1' then -- set ata on demand
n.dsata(to_integer(unsigned(r.runit))) := '1';
end if;
if IB_MREQ.din(ds_ibf_vv) = '1' then -- clr vv on demand
n.dsvv(to_integer(unsigned(r.runit))) := '0';
end if;
if IB_MREQ.din(ds_ibf_erp) = '1' then -- clr er1 on demand
n.er1uns(to_integer(unsigned(r.eunit))) := '0'; -- clr all er1
n.er1wle(to_integer(unsigned(r.eunit))) := '0'; -- "
n.er1iae(to_integer(unsigned(r.eunit))) := '0'; -- "
n.er1aoe(to_integer(unsigned(r.eunit))) := '0'; -- "
n.er1rmr(to_integer(unsigned(r.eunit))) := '0'; -- "
n.er1ilf(to_integer(unsigned(r.eunit))) := '0'; -- "
end if;
n.state := s_idle;
else -- loc access
ibhold := '1'; -- read-only reg, thus noop
n.state := s_whr;
end if;
when s_wbae => -- wbae: write bae -------------------
n.state := s_idle; -- in general return to s_idle
if IB_MREQ.be0 = '1' then
n.bae := IB_MREQ.din(bae_ibf_bae);
end if;
when s_wmem => -- wmem: write mem (DA,MR1,OF,DC,MR2)-
-- this state only handles massbus registers
n.state := s_idle; -- in general return to s_idle
imem_addr := r.amap; -- use mapped address
imem_din := r.dinmsk; -- use masked input
 
if ibrem = '0' then -- loc access
imem_we0 := '1'; -- write memory
imem_we1 := '1';
ibhold := '1';
n.state := s_whr;
else -- rem access
imem_we0 := '1'; -- write memory
imem_we1 := '1';
end if;
when s_wmembe => -- wmem: write mem with be (WC,BA,DB)-
-- this state only handles controller registers --> no ned checking
n.state := s_idle; -- in general return to s_idle
imem_we0 := IB_MREQ.be0;
imem_we1 := IB_MREQ.be1;
imem_addr := r.amap;
imem_din := r.dinmsk;
when s_whr => -- whr: write hr ---------------------
n.state := s_idle; -- in general return to s_idle
imem_addr := r.cs2unit & amapc_hr; -- mem address of holding reg
imem_din := not IB_MREQ.din;
if ibrem = '0' then -- loc access
imem_we0 := '1'; -- keep state
imem_we1 := '1';
end if;
when s_funcchk => -- funcchk: check function go --------
n.state := s_idle; -- in general return to s_idle
if r.cs1rdy = '0' and
unsigned(IB_MREQ.din(cs1_ibf_func)) >= unsigned(func_xfer) then
n.cs2pge := '1'; -- issue program error
elsif IB_MREQ.din(cs1_ibf_func) = func_dclr then
n.eunit := r.cs2unit; -- for follow-up states
n.clrmode := clrmode_fdclr;
n.state := s_oot_clr0; -- OOT state, no hold!
elsif r.dserp(to_integer(unsigned(r.cs2unit))) = '1' then
n.er1ilf(to_integer(unsigned(r.cs2unit))) := '1';
else
ibhold := '1';
n.state := s_funcgo;
end if;
when s_funcgo => -- funcgo: handle function go --------
n.state := s_idle; -- in general return to s_idle
n.dsata(to_integer(unsigned(r.cs2unit))) := '0';
 
case IB_MREQ.din(cs1_ibf_func) is
when func_noop => -- func: noop --------------
null; -- nothing done...
when func_pore => -- func: port release-------
n.poredone := '1'; -- take note in done flag
when func_unl => -- func: unload ------------
-- only for RP, simply clears MOL
if r.dtrm(to_integer(unsigned(r.cs2unit))) = '0' then
n.dsmol(to_integer(unsigned(r.cs2unit))) := '0';
n.dswrl(to_integer(unsigned(r.cs2unit))) := '0';
n.dsvv(to_integer(unsigned(r.cs2unit))) := '0';
n.dsom(to_integer(unsigned(r.cs2unit))) := '0';
else
n.er1ilf(to_integer(unsigned(r.cs2unit))) := '1';
end if;
n.dsata(to_integer(unsigned(r.cs2unit))) := '1';
-- when func_dclr => now handled in funcchk !!
when func_offs | -- func: offset ------------
func_retc => -- func: return to center --
 
-- currently always immediate completion, so ata set here
n.dsata(to_integer(unsigned(r.cs2unit))) := '1';
 
if r.dsmol(to_integer(unsigned(r.cs2unit))) = '0' then
n.er1uns(to_integer(unsigned(r.cs2unit))) := '1';
else
if IB_MREQ.din(cs1_ibf_func) = func_offs then
n.dsom(to_integer(unsigned(r.cs2unit))) := '1';
else
n.dsom(to_integer(unsigned(r.cs2unit))) := '0';
end if;
end if;
when func_pres => -- func: readin preset -----
n.dsvv(to_integer(unsigned(r.cs2unit))) := '1';
n.eunit := r.cs2unit; -- for follow-up states
n.clrmode := clrmode_fpres;
n.state := s_oot_clr0; -- OOT state, no hold!
when func_pack => -- func: pack acknowledge --
n.dsvv(to_integer(unsigned(r.cs2unit))) := '1';
n.packdone := '1'; -- take note in done flag
-- seek like and data transfer functions
when func_seek | -- func: seek --------------
func_recal | -- func: recalibrate -------
func_sear | -- func: search ------------
func_wcd | -- func: write check data --
func_wchd | -- func: write check h&d ---
func_write | -- func: write ------------
func_whd | -- func: write header&data -
func_read | -- func: read --------------
func_rhd => -- func: read header&data --
 
if IB_MREQ.din(cs1_ibf_func) = func_seek then
n.seekdone := '1'; -- take note in done flag
end if;
if IB_MREQ.din(cs1_ibf_func) = func_sear then
n.seardone := '1'; -- take note in done flag
end if;
 
-- check for transfer functions
n.fxfer := '0';
if unsigned(IB_MREQ.din(cs1_ibf_func)) >= unsigned(func_wcd) then
n.fxfer := '1';
-- in case of write, check for write lock
if IB_MREQ.din(cs1_ibf_func) = func_write or
IB_MREQ.din(cs1_ibf_func) = func_whd then
if r.dswrl(to_integer(unsigned(r.cs2unit))) = '1' then
n.er1wle(to_integer(unsigned(r.cs2unit))) := '1';
end if;
end if;
end if;
if r.dsmol(to_integer(unsigned(r.cs2unit))) = '0' then
n.er1uns(to_integer(unsigned(r.cs2unit))) := '1';
n.dsata(to_integer(unsigned(r.cs2unit))) := '1';
else
ibhold := '1';
n.state := s_chkdc;
end if;
-- illegal function codes
when others =>
n.er1ilf(to_integer(unsigned(r.cs2unit))) := '1';
n.dsata(to_integer(unsigned(r.cs2unit))) := '1';
end case; -- IB_MREQ.din(cs1_ibf_func)
 
when s_chkdc => -- chkdc: handle dc check ------------
imem_addr := r.cs2unit & amapc_dc; -- mem address of dc reg
if unsigned(MEM_DOUT(dc_ibf_ca)) > unsigned(r.camax) then
n.er1iae(to_integer(unsigned(r.cs2unit))) := '1';
end if;
ibhold := '1';
n.state := s_chkda;
 
when s_chkda => -- chkda: handle da check ------------
imem_addr := r.cs2unit & amapc_da; -- mem address of da reg
if unsigned(MEM_DOUT(da_ibf_sa)) > unsigned(r.samax) or
unsigned(MEM_DOUT(da_ibf_ta)) > unsigned(r.tamax) then
n.er1iae(to_integer(unsigned(r.cs2unit))) := '1';
end if;
ibhold := '1';
n.state := s_chkdo;
when s_chkdo => -- chkdo: execute function -----------
if r.er1iae(to_integer(unsigned(r.cs2unit))) = '1' or
r.er1wle(to_integer(unsigned(r.cs2unit))) = '1' then
n.dsata(to_integer(unsigned(r.cs2unit))) := '1'; -- ata and done
else
if r.fxfer = '0' then -- must be seek like function
n.dspip(to_integer(unsigned(r.cs2unit))) := '1'; -- pip
n.idlycnt := r.idlyval; -- start delay
else -- must be transfer function
n.ffunc := IB_MREQ.din(cs1_ibf_func); -- latch func
n.funit := r.cs2unit; -- latch unit
n.cs1rdy := '0'; -- controller busy
n.cs2wce := '0'; -- clear errors
n.cs2ned := '0';
n.cs2nem := '0';
n.cs2pge := '0';
n.cs2mxf := '0';
ilam := '1'; -- issue lam
end if;
end if;
n.state := s_idle;
when s_read => -- read: all register reads ----------
n.state := s_idle; -- in general return to s_idle
imem_addr := r.amap;
 
case r.omux is
 
when omux_cs1 => -- omux: cs1 reg ---------------
idout(cs1_ibf_sc) := r.cs1sc;
idout(cs1_ibf_tre) := r.cs1tre;
idout(cs1_ibf_dva) := '1';
idout(cs1_ibf_bae) := r.bae(1 downto 0);
idout(cs1_ibf_rdy) := r.cs1rdy;
idout(cs1_ibf_ie) := r.cs1ie;
if ibrem = '0' then -- loc access
idout(cs1_ibf_func) := MEM_DOUT(cs1_ibf_func); --func per unit
if r.ned = '1' then -- drive off
n.cs2ned := '1'; -- signal error
end if;
else -- rem access
idout(cs1_ibf_func) := r.ffunc;
end if;
 
when omux_cs2 => -- omux: cs2 reg ---------------
idout(cs2_ibf_wce) := r.cs2wce;
idout(cs2_ibf_ned) := r.cs2ned;
idout(cs2_ibf_nem) := r.cs2nem;
idout(cs2_ibf_pge) := r.cs2pge;
idout(cs2_ibf_mxf) := r.cs2mxf;
idout(cs2_ibf_or) := '1';
idout(cs2_ibf_ir) := '1';
idout(cs2_ibf_pat) := r.cs2pat;
idout(cs2_ibf_bai) := r.cs2bai;
idout(cs2_ibf_unit2) := r.cs2unit2;
if ibrem = '0' then -- loc access
idout(cs2_ibf_unit) := r.cs2unit;
else -- rem access
idout(cs2_ibf_unit) := r.funit;
end if;
 
when omux_ds => -- omux: ds reg ---------------
idout(ds_ibf_ata) := r.dsata(to_integer(unsigned(r.eunit)));
idout(ds_ibf_erp) := r.dserp(to_integer(unsigned(r.eunit)));
idout(ds_ibf_pip) := r.dspip(to_integer(unsigned(r.eunit)));
idout(ds_ibf_mol) := r.dsmol(to_integer(unsigned(r.eunit)));
idout(ds_ibf_wrl) := r.dswrl(to_integer(unsigned(r.eunit)));
idout(ds_ibf_lbt) := r.dslbt(to_integer(unsigned(r.eunit)));
idout(ds_ibf_dpr) := r.dsdpr(to_integer(unsigned(r.eunit)));
 
-- ds.dry is 0 if mol=0 or if transfer or seek is active on unit
-- the logic below checks for the complement ...
if r.dsmol(to_integer(unsigned(r.eunit))) = '1' then
if (r.cs1rdy = '1' or r.funit /= r.eunit) and
r.dspip(to_integer(unsigned(r.eunit))) = '0' then
idout(ds_ibf_dry) := '1';
end if;
end if;
 
idout(ds_ibf_vv) := r.dsvv (to_integer(unsigned(r.eunit)));
idout(ds_ibf_om) := r.dsom (to_integer(unsigned(r.eunit)));
 
when omux_er1 => -- omux: er1 reg ---------------
idout(er1_ibf_uns) := r.er1uns(to_integer(unsigned(r.eunit)));
idout(er1_ibf_wle) := r.er1wle(to_integer(unsigned(r.eunit)));
idout(er1_ibf_iae) := r.er1iae(to_integer(unsigned(r.eunit)));
idout(er1_ibf_aoe) := r.er1aoe(to_integer(unsigned(r.eunit)));
idout(er1_ibf_rmr) := r.er1rmr(to_integer(unsigned(r.eunit)));
idout(er1_ibf_ilf) := r.er1ilf(to_integer(unsigned(r.eunit)));
 
when omux_as => -- omux: as reg ---------------
idout(r.dsata'range) := r.dsata;
 
when omux_la => -- omux: la reg ---------------
idout(la_ibf_sc) := r.sc;
 
when omux_dt => -- omux: dt reg ---------------
if ibrem = '0' then -- loc access
idout(13) := '1'; -- set bit 020000 (movable head)
idout(r.dtyp'range) := r.dtyp;
else -- rem access (read back rem side)
idout(dt_ibf_rm) := r.dtrm(to_integer(unsigned(r.runit)));
idout(dt_ibf_e1) := r.dte1(to_integer(unsigned(r.runit)));
idout(dt_ibf_e0) := r.dte0(to_integer(unsigned(r.runit)));
end if;
 
when omux_sn => -- omux: sn reg ---------------
-- the serial number is encoded as 4 digit BCD
-- digit 3: always 1
-- digit 2: 1 if RM type; 0 if RP type
-- digit 1: 0-3 based on encoded drive type
-- digit 0: 0-3 taken as complement of unit
-- Note: the 3lsb are the *complement* of the unit number because
-- 211bsd driver code contains a hack to detect SI and CDC
-- drives. For those drives the drive type is encode in the
-- sn register, and one convention is that the 3 lsb of sn
-- equal the unit numnber. To prevent that the SI/CDC hacks
-- are actived the 3lsb are set as complement of the unit !
idout(12) := '1';
idout(8) := r.dtrm(to_integer(unsigned(r.eunit)));
idout(5) := r.dte1(to_integer(unsigned(r.eunit)));
idout(4) := r.dte0(to_integer(unsigned(r.eunit)));
idout(2) := '1';
idout(1) := not r.eunit(1);
idout(0) := not r.eunit(0);
when omux_bae => -- omux: bae reg ---------------
idout(bae_ibf_bae) := r.bae;
 
when omux_cs3 => -- omux: cs3 reg ---------------
idout(cs3_ibf_wco) := r.cs2wce and r.cs3wco;
idout(cs3_ibf_wce) := r.cs2wce and not r.cs3wco;
idout(cs3_ibf_ie) := r.cs1ie;
if ibrem = '1' then -- rem access
idout(cs3_ibf_rseardone) := r.seardone;
idout(cs3_ibf_rpackdone) := r.packdone;
idout(cs3_ibf_rporedone) := r.poredone;
idout(cs3_ibf_rseekdone) := r.seekdone;
if IB_MREQ.re = '1' then -- if read, do read & clear
n.seardone := '0';
n.packdone := '0';
n.poredone := '0';
n.seekdone := '0';
end if;
end if;
 
when omux_mem => -- omux: mem output ------------
idout := MEM_DOUT;
 
when omux_zero => -- omux: zero ------------------
idout := (others=>'0');
when others => null; -- nxr caught before in mapper !
end case; -- case r.omux
 
when s_setrmr => -- set rmr flag ----------------------
n.er1rmr(to_integer(unsigned(r.cs2unit))) := '1';
n.state := s_idle;
when s_oot_clr0 => -- OOT clr0: state 0 -----------------
if r.clrmode=clrmode_breset or r.clrmode=clrmode_cs2clr then
n.cs1rdy := '1'; -- clear cs1
n.cs1ie := '0';
n.cs2wce := '0'; -- clear cs2
n.cs2ned := '0';
n.cs2nem := '0';
n.cs2pge := '0';
n.cs2mxf := '0';
n.cs2pat := '0';
n.cs2bai := '0';
n.cs2unit2 := '0';
n.cs2unit := (others=>'0');
n.bae := (others=>'0'); -- clear bae
n.ireq := '0'; -- clear iff
end if;
if r.clrmode=clrmode_breset or r.clrmode=clrmode_fdclr then
n.er1uns(to_integer(unsigned(r.eunit))) := '0'; -- clr all er1
n.er1wle(to_integer(unsigned(r.eunit))) := '0'; -- "
n.er1iae(to_integer(unsigned(r.eunit))) := '0'; -- "
n.er1aoe(to_integer(unsigned(r.eunit))) := '0'; -- "
n.er1rmr(to_integer(unsigned(r.eunit))) := '0'; -- "
n.er1ilf(to_integer(unsigned(r.eunit))) := '0'; -- "
end if;
 
n.cerm := r.dtrm(to_integer(unsigned(ieunit)));
n.clrreg := "000";
ibhold := r.ibsel; -- delay pending request
n.state := s_oot_clr1;
 
when s_oot_clr1 => -- OOT clr1: state 1 ----------------
imem_addr := r.eunit & r.clrreg;
imem_din := (others=>'0');
 
iclrreg := '0';
case r.clrmode is
 
when clrmode_breset => -- BRESET -------------------------
iclrreg := '1'; -- simply clear all (cntl+drives)
 
when clrmode_cs2clr => -- CS2.CLR (controller clr) -------
case r.clrreg is
when amapc_ext => iclrreg := '1';
when amapc_mr1 => iclrreg := r.cerm;
when others => null;
end case;
 
when clrmode_fdclr => -- func=DCLR (drive clr) ----------
case r.clrreg is
when amapc_mr1 => iclrreg := r.cerm;
when others => null;
end case;
 
when clrmode_fpres => -- func=PRESET --------------------
case r.clrreg is
when amapc_da => iclrreg := '1';
when amapc_of => iclrreg := '1';
when amapc_dc => iclrreg := '1';
when others => null;
end case;
 
when others => null;
end case;
if iclrreg = '1' then
imem_we0 := IB_MREQ.be0;
imem_we1 := IB_MREQ.be1;
end if;
n.clrreg := slv(unsigned(r.clrreg) + 1);
 
ibhold := r.ibsel; -- delay pending request
if r.clrreg = "111" then -- if last register done
n.state := s_oot_clr2; -- proceed with clr2
end if;
when s_oot_clr2 => -- OOT clr2: state 2 ----------------
n.eunit := slv(unsigned(r.eunit) + 1);
 
ibhold := r.ibsel; -- delay pending request, so that
-- s_idle can finally process it
if (r.clrmode=clrmode_breset or r.clrmode=clrmode_cs2clr) and
r.eunit /= "11" then
n.state := s_oot_clr0;
else
n.state := s_idle;
end if;
when others => null; -- <> ------------------------------
end case; -- case r.state
 
-- update cs1tre and cs1sc
n.cs1tre := r.cs2wce or r.cs2ned or r.cs2nem or r.cs2pge or r.cs2mxf;
n.cs1sc := n.cs1tre or r.dsata(0) or r.dsata(1) or r.dsata(2) or r.dsata(3);
-- update dserp
n.dserp := r.er1uns or -- or all er1
r.er1wle or -- "
r.er1iae or -- "
r.er1aoe or -- "
r.er1rmr or -- "
r.er1ilf; -- "
-- handle current sector counter (for RxLA emulation)
-- advance every 128 usec, so generate a pulse every 128 usec
if CE_USEC = '1' then
n.uscnt := slv(unsigned(r.uscnt) + 1);
if unsigned(r.uscnt) = 0 then
iscinc := '1';
end if;
end if;
 
-- if current sector larger or equal highest sector wrap to zero
-- note: iscinc is also '1' when unit changes, this ensures that
-- the sector counter is always in range when read to ibus.
if iscinc = '1' then
if unsigned(r.sc) >= unsigned(r.samax) then
n.sc := (others=>'0');
else
n.sc := slv(unsigned(r.sc) + 1);
end if;
end if;
 
-- the RH70 interrupt logic is very unusual
-- 1. done interrupts (rdy 0->1) are edge sensitive (via r.ireq)
-- 2. done interrupts are not canceled when IE is cleared
-- 3. attention interrupts are level sensitive (via r.cs1sc)
-- 4. IE is disabled on interrupt acknowledge
 
iei_req := r.ireq or (r.cs1sc and r.cs1ie and r.cs1rdy);
 
if EI_ACK = '1' then -- interrupt executed
n.ireq := '0'; -- cancel request
n.cs1ie := '0'; -- disable interrupts
end if;
N_REGS <= n;
 
MEM_0_WE <= imem_we0;
MEM_1_WE <= imem_we1;
MEM_ADDR <= imem_addr;
MEM_DIN <= imem_din;
IB_SRES.dout <= idout;
IB_SRES.ack <= r.ibsel and ibreq;
IB_SRES.busy <= ibhold and ibreq;
 
RB_LAM <= ilam;
EI_REQ <= iei_req;
end process proc_next;
 
end syn;
/ibdr_tm11.vbom
0,0 → 1,6
# libs
../vlib/slvtypes.vhd
iblib.vhd
# components
# design
ibdr_tm11.vhd
/ibdlib.vhd
0,0 → 1,299
-- $Id: ibdlib.vhd 682 2015-05-15 18:35:29Z mueller $
--
-- Copyright 2008-2015 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.
--
------------------------------------------------------------------------------
-- Package Name: ibdlib
-- Description: Definitions for ibus devices
--
-- Dependencies: -
-- Tool versions: ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31
-- Revision History:
-- Date Rev Version Comment
-- 2015-05-09 676 1.3 start/stop/suspend overhaul
-- 2015-03-13 658 1.2.1 add rprm declaration (later renaned to rhrp)
-- 2014-06-08 561 1.2 fix rl11 declaration
-- 2011-11-18 427 1.1.2 now numeric_std clean
-- 2010-10-23 335 1.1.1 rename RRI_LAM->RB_LAM;
-- 2010-06-11 303 1.1 use IB_MREQ.racc instead of RRI_REQ
-- 2009-07-12 233 1.0.5 add RESET, CE_USEC to _dl11, CE_USEC to _minisys
-- 2009-06-07 224 1.0.4 add iist_mreq and iist_sreq;
-- 2009-06-01 221 1.0.3 add RESET to kw11l; add iist;
-- 2009-05-30 220 1.0.2 add most additional device def's
-- 2009-05-24 219 1.0.1 add CE_MSEC to _rk11; add _maxisys
-- 2008-08-22 161 1.0 Initial version (extracted from pdp11.vhd)
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
use work.iblib.all;
 
package ibdlib is
 
type iist_line_type is record -- iist line
dcf : slbit; -- disconnect flag
req : slbit; -- request
stf : slbit; -- sanity timer flag
imask : slv4; -- interrupt mask
bmask : slv4; -- boot mask
par : slbit; -- parity (odd)
frm : slbit; -- frame error flag
end record iist_line_type;
 
constant iist_line_init : iist_line_type := ('1','0','0',"0000","0000",'0','0');
 
type iist_bus_type is array (3 downto 0) of iist_line_type;
constant iist_bus_init : iist_bus_type := (others=>iist_line_init);
 
type iist_mreq_type is record -- iist->cpu requests
lock : slbit; -- lock-up CPU
boot : slbit; -- boot-up CPU
end record iist_mreq_type;
 
constant iist_mreq_init : iist_mreq_type := ('0','0');
 
type iist_sres_type is record -- cpu->iist responses
ack_lock : slbit; -- release lock
ack_boot : slbit; -- boot started
end record iist_sres_type;
 
constant iist_sres_init : iist_sres_type := ('0','0');
 
-- ise 13.1 xst can bug check if generic defaults in a package are defined via
-- 'slv(to_unsigned())'. The conv_ construct prior to numeric_std was ok.
-- As workaround the ibus default addresses are defined here as constant.
constant ibaddr_dz11 : slv16 := slv(to_unsigned(8#160100#,16));
constant ibaddr_dl11 : slv16 := slv(to_unsigned(8#177560#,16));
 
component ibd_iist is -- ibus dev(loc): IIST
-- fixed address: 177500
generic (
SID : slv2 := "00"); -- self id
port (
CLK : in slbit; -- clock
CE_USEC : in slbit; -- usec pulse
RESET : in slbit; -- system reset
BRESET : in slbit; -- ibus reset
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
IIST_BUS : in iist_bus_type; -- iist bus (input from all iist's)
IIST_OUT : out iist_line_type; -- iist output
IIST_MREQ : out iist_mreq_type; -- iist->cpu requests
IIST_SRES : in iist_sres_type -- cpu->iist responses
);
end component;
 
component ibd_kw11p is -- ibus dev(loc): KW11-P (prog clock)
-- fixed address: 172540
port (
CLK : in slbit; -- clock
CE_USEC : in slbit; -- usec pulse
CE_MSEC : in slbit; -- msec pulse
RESET : in slbit; -- system reset
BRESET : in slbit; -- ibus reset
CPUSUSP : in slbit; -- cpu suspended
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 component;
 
component ibd_kw11l is -- ibus dev(loc): KW11-L (line clock)
-- fixed address: 177546
port (
CLK : in slbit; -- clock
CE_MSEC : in slbit; -- msec pulse
RESET : in slbit; -- system reset
BRESET : in slbit; -- ibus reset
CPUSUSP : in slbit; -- cpu suspended
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 component;
 
component ibdr_rhrp is -- ibus dev(rem): RH+RP
-- fixed address: 174400
port (
CLK : in slbit; -- clock
CE_USEC : in slbit; -- usec pulse
BRESET : in slbit; -- ibus reset
ITIMER : in slbit; -- instruction timer
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 component;
 
component ibdr_rl11 is -- ibus dev(rem): RL11
-- fixed address: 174400
port (
CLK : in slbit; -- clock
CE_MSEC : in slbit; -- msec pulse
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 component;
 
component ibdr_rk11 is -- ibus dev(rem): RK11
-- fixed address: 177400
port (
CLK : in slbit; -- clock
CE_MSEC : in slbit; -- msec pulse
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 component;
 
component ibdr_tm11 is -- ibus dev(rem): TM11
-- fixed address: 172520
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 component;
 
component ibdr_dz11 is -- ibus dev(rem): DZ11
generic (
IB_ADDR : slv16 := ibaddr_dz11);
port (
CLK : in slbit; -- clock
RESET : in slbit; -- system reset
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_RX : out slbit; -- interrupt request, receiver
EI_REQ_TX : out slbit; -- interrupt request, transmitter
EI_ACK_RX : in slbit; -- interrupt acknowledge, receiver
EI_ACK_TX : in slbit -- interrupt acknowledge, transmitter
);
end component;
 
component ibdr_dl11 is -- ibus dev(rem): DL11-A/B
generic (
IB_ADDR : slv16 := ibaddr_dl11);
port (
CLK : in slbit; -- clock
CE_USEC : in slbit; -- usec pulse
RESET : in slbit; -- system reset
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_RX : out slbit; -- interrupt request, receiver
EI_REQ_TX : out slbit; -- interrupt request, transmitter
EI_ACK_RX : in slbit; -- interrupt acknowledge, receiver
EI_ACK_TX : in slbit -- interrupt acknowledge, transmitter
);
end component;
 
component ibdr_pc11 is -- ibus dev(rem): PC11
-- fixed address: 177550
port (
CLK : in slbit; -- clock
RESET : in slbit; -- system reset
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_PTR : out slbit; -- interrupt request, reader
EI_REQ_PTP : out slbit; -- interrupt request, punch
EI_ACK_PTR : in slbit; -- interrupt acknowledge, reader
EI_ACK_PTP : in slbit -- interrupt acknowledge, punch
);
end component;
 
component ibdr_lp11 is -- ibus dev(rem): LP11
-- fixed address: 177514
port (
CLK : in slbit; -- clock
RESET : in slbit; -- system reset
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 component;
 
component ibdr_sdreg is -- ibus dev(rem): Switch/Display regs
-- fixed address: 177570
port (
CLK : in slbit; -- clock
RESET : in slbit; -- reset
IB_MREQ : in ib_mreq_type; -- ibus request
IB_SRES : out ib_sres_type; -- ibus response
DISPREG : out slv16 -- display register
);
end component;
 
component ibdr_minisys is -- ibus(rem) minimal sys:SDR+KW+DL+RK
port (
CLK : in slbit; -- clock
CE_USEC : in slbit; -- usec pulse
CE_MSEC : in slbit; -- msec pulse
RESET : in slbit; -- reset
BRESET : in slbit; -- ibus reset
RB_LAM : out slv16_1; -- remote attention vector
IB_MREQ : in ib_mreq_type; -- ibus request
IB_SRES : out ib_sres_type; -- ibus response
EI_ACKM : in slbit; -- interrupt acknowledge (from master)
EI_PRI : out slv3; -- interrupt priority (to cpu)
EI_VECT : out slv9_2; -- interrupt vector (to cpu)
DISPREG : out slv16 -- display register
);
end component;
component ibdr_maxisys is -- ibus(rem) full system
port (
CLK : in slbit; -- clock
CE_USEC : in slbit; -- usec pulse
CE_MSEC : in slbit; -- msec pulse
RESET : in slbit; -- reset
BRESET : in slbit; -- ibus reset
ITIMER : in slbit; -- instruction timer
CPUSUSP : in slbit; -- cpu suspended
RB_LAM : out slv16_1; -- remote attention vector
IB_MREQ : in ib_mreq_type; -- ibus request
IB_SRES : out ib_sres_type; -- ibus response
EI_ACKM : in slbit; -- interrupt acknowledge (from master)
EI_PRI : out slv3; -- interrupt priority (to cpu)
EI_VECT : out slv9_2; -- interrupt vector (to cpu)
DISPREG : out slv16 -- display register
);
end component;
end package ibdlib;
/ibdr_maxisys.vhd
0,0 → 1,487
-- $Id: ibdr_maxisys.vhd 683 2015-05-17 21:54:35Z mueller $
--
-- Copyright 2009-2015 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_maxisys - syn
-- Description: ibus(rem) devices for full system
--
-- Dependencies: ibd_iist
-- ibd_kw11l
-- ibdr_rhrp
-- ibdr_rl11
-- ibdr_rk11
-- ibdr_tm11
-- ibdr_dl11
-- ibdr_pc11
-- ibdr_lp11
-- ibdr_sdreg
-- ib_sres_or_4
-- ib_sres_or_3
-- ib_intmap
-- Test bench: -
-- Target Devices: generic
-- Tool versions: ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2015-04-06 664 14.7 131013 xc6slx16-2 559 1068 29 410 s 9.1 +RHRP
-- 2015-01-04 630 14.7 131013 xc6slx16-2 388 761 20 265 s 8.0 +RL11
-- 2014-06-08 560 14.7 131013 xc6slx16-2 311 615 8 216 s 7.1
-- 2010-10-17 333 12.1 M53d xc3s1000-4 312 1058 16 617 s 10.3
-- 2010-10-17 314 12.1 M53d xc3s1000-4 300 1094 16 626 s 10.4
--
-- Revision History:
-- Date Rev Version Comment
-- 2015-05-15 683 1.3.1 add TM11
-- 2015-05-10 678 1.3 start/stop/suspend overhaul
-- 2015-04-06 664 1.2.3 rename RPRM to RHRP
-- 2015-03-14 658 1.2.2 add RPRM; rearrange intmap (+rhrp,tm11,-kw11-l)
-- use sys_conf, make most devices configurable
-- 2015-01-04 630 1.2.1 RL11 back in
-- 2014-06-27 565 1.2.1 temporarily hide RL11
-- 2014-06-08 561 1.2 add RL11
-- 2011-11-18 427 1.1.2 now numeric_std clean
-- 2010-10-23 335 1.1.1 rename RRI_LAM->RB_LAM
-- 2010-06-11 303 1.1 use IB_MREQ.racc instead of RRI_REQ
-- 2009-07-12 233 1.0.4 reorder ports; add RESET, CE_USEC to _dl11
-- 2009-06-20 227 1.0.3 rename generate labels
-- 2009-06-07 224 1.0.2 add iist_mreq and iist_sres interfaces
-- 2009-06-01 221 1.0.1 add CE_USEC; add RESET to kw11l; add _pc11, _iist
-- 2009-05-24 219 1.0 Initial version
------------------------------------------------------------------------------
--
--
-- full system setup
--
-- ibbase vec pri slot attn sror device name
--
-- 172540 104 ?7 17 - 1/1 KW11-P
-- 177500 260 6 15 16 - 1/2 IIST
-- 177546 100 6 14 15 - 1/3 KW11-L
-- 174510 120 5 14 9 1/4 DEUNA
-- 176700 254 5 13 13 6 2/1 RHRP
-- 174400 160 5 12 12 5 2/2 RL11
-- 177400 220 5 11 11 4 2/3 RK11
-- 172520 224 5 10 10 7 2/4 TM11
-- 160100 310? 5 9 9 3 3/1 DZ11-RX
-- 314? 5 8 8 ^ DZ11-TX
-- 177560 060 4 7 7 1 3/2 DL11-RX 1st
-- 064 4 6 6 ^ DL11-TX 1st
-- 176500 300 4 5 5 2 3/3 DL11-RX 2nd
-- 304 4 4 4 ^ DL11-TX 2nd
-- 177550 070 4 3 3 10 4/1 PC11/PTR
-- 074 4 2 2 ^ PC11/PTP
-- 177514 200 4 1 1 8 4/2 LP11
-- 177570 - - - - 4/3 sdreg
--
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
use work.iblib.all;
use work.ibdlib.all;
use work.sys_conf.all;
 
-- ----------------------------------------------------------------------------
entity ibdr_maxisys is -- ibus(rem) full system
port (
CLK : in slbit; -- clock
CE_USEC : in slbit; -- usec pulse
CE_MSEC : in slbit; -- msec pulse
RESET : in slbit; -- reset
BRESET : in slbit; -- ibus reset
ITIMER : in slbit; -- instruction timer
CPUSUSP : in slbit; -- cpu suspended
RB_LAM : out slv16_1; -- remote attention vector
IB_MREQ : in ib_mreq_type; -- ibus request
IB_SRES : out ib_sres_type; -- ibus response
EI_ACKM : in slbit; -- interrupt acknowledge (from master)
EI_PRI : out slv3; -- interrupt priority (to cpu)
EI_VECT : out slv9_2; -- interrupt vector (to cpu)
DISPREG : out slv16 -- display register
);
end ibdr_maxisys;
 
architecture syn of ibdr_maxisys is
 
constant conf_intmap : intmap_array_type :=
((8#260#,6), -- line 15 IIST
(8#100#,6), -- line 14 KW11-L
(8#254#,5), -- line 13 RHRP
(8#160#,5), -- line 12 RL11
(8#220#,5), -- line 11 RK11
(8#224#,5), -- line 10 TM11
(8#310#,5), -- line 9 DZ11-RX
(8#314#,5), -- line 8 DZ11-TX
(8#060#,4), -- line 7 DL11-RX 1st
(8#064#,4), -- line 6 DL11-TX 1st
(8#300#,4), -- line 5 DL11-RX 2nd
(8#304#,4), -- line 4 DL11-TX 2nd
(8#070#,4), -- line 3 PC11-PTR
(8#074#,4), -- line 2 PC11-PTP
(8#200#,4), -- line 1 LP11
intmap_init -- line 0 (must be unused!)
);
 
signal RB_LAM_DENUA : slbit := '0';
signal RB_LAM_RHRP : slbit := '0';
signal RB_LAM_RL11 : slbit := '0';
signal RB_LAM_RK11 : slbit := '0';
signal RB_LAM_TM11 : slbit := '0';
signal RB_LAM_DZ11 : slbit := '0';
signal RB_LAM_DL11_0 : slbit := '0';
signal RB_LAM_DL11_1 : slbit := '0';
signal RB_LAM_PC11 : slbit := '0';
signal RB_LAM_LP11 : slbit := '0';
 
signal IB_SRES_IIST : ib_sres_type := ib_sres_init;
signal IB_SRES_KW11P : ib_sres_type := ib_sres_init;
signal IB_SRES_KW11L : ib_sres_type := ib_sres_init;
signal IB_SRES_DEUNA : ib_sres_type := ib_sres_init;
signal IB_SRES_RHRP : ib_sres_type := ib_sres_init;
signal IB_SRES_RL11 : ib_sres_type := ib_sres_init;
signal IB_SRES_RK11 : ib_sres_type := ib_sres_init;
signal IB_SRES_TM11 : ib_sres_type := ib_sres_init;
signal IB_SRES_DZ11 : ib_sres_type := ib_sres_init;
signal IB_SRES_DL11_0 : ib_sres_type := ib_sres_init;
signal IB_SRES_DL11_1 : ib_sres_type := ib_sres_init;
signal IB_SRES_PC11 : ib_sres_type := ib_sres_init;
signal IB_SRES_LP11 : ib_sres_type := ib_sres_init;
signal IB_SRES_SDREG : ib_sres_type := ib_sres_init;
 
signal IB_SRES_1 : ib_sres_type := ib_sres_init;
signal IB_SRES_2 : ib_sres_type := ib_sres_init;
signal IB_SRES_3 : ib_sres_type := ib_sres_init;
signal IB_SRES_4 : ib_sres_type := ib_sres_init;
signal EI_REQ : slv16_1 := (others=>'0');
signal EI_ACK : slv16_1 := (others=>'0');
 
signal EI_REQ_IIST : slbit := '0';
signal EI_REQ_KW11P : slbit := '0';
signal EI_REQ_KW11L : slbit := '0';
signal EI_REQ_DEUNA : slbit := '0';
signal EI_REQ_RHRP : slbit := '0';
signal EI_REQ_RL11 : slbit := '0';
signal EI_REQ_RK11 : slbit := '0';
signal EI_REQ_TM11 : slbit := '0';
signal EI_REQ_DZ11RX : slbit := '0';
signal EI_REQ_DZ11TX : slbit := '0';
signal EI_REQ_DL11RX_0 : slbit := '0';
signal EI_REQ_DL11TX_0 : slbit := '0';
signal EI_REQ_DL11RX_1 : slbit := '0';
signal EI_REQ_DL11TX_1 : slbit := '0';
signal EI_REQ_PC11PTR : slbit := '0';
signal EI_REQ_PC11PTP : slbit := '0';
signal EI_REQ_LP11 : slbit := '0';
signal EI_ACK_IIST : slbit := '0';
signal EI_ACK_KW11P : slbit := '0';
signal EI_ACK_KW11L : slbit := '0';
signal EI_ACK_DEUNA : slbit := '0';
signal EI_ACK_RHRP : slbit := '0';
signal EI_ACK_RL11 : slbit := '0';
signal EI_ACK_RK11 : slbit := '0';
signal EI_ACK_TM11 : slbit := '0';
signal EI_ACK_DZ11RX : slbit := '0';
signal EI_ACK_DZ11TX : slbit := '0';
signal EI_ACK_DL11RX_0 : slbit := '0';
signal EI_ACK_DL11TX_0 : slbit := '0';
signal EI_ACK_DL11RX_1 : slbit := '0';
signal EI_ACK_DL11TX_1 : slbit := '0';
signal EI_ACK_PC11PTR : slbit := '0';
signal EI_ACK_PC11PTP : slbit := '0';
signal EI_ACK_LP11 : slbit := '0';
 
signal IIST_BUS : iist_bus_type := iist_bus_init;
signal IIST_OUT_0 : iist_line_type := iist_line_init;
signal IIST_MREQ : iist_mreq_type := iist_mreq_init;
signal IIST_SRES : iist_sres_type := iist_sres_init;
 
begin
 
IIST: if sys_conf_ibd_iist generate
begin
I0 : ibd_iist
port map (
CLK => CLK,
CE_USEC => CE_USEC,
RESET => RESET,
BRESET => BRESET,
IB_MREQ => IB_MREQ,
IB_SRES => IB_SRES_IIST,
EI_REQ => EI_REQ_IIST,
EI_ACK => EI_ACK_IIST,
IIST_BUS => IIST_BUS,
IIST_OUT => IIST_OUT_0,
IIST_MREQ => IIST_MREQ,
IIST_SRES => IIST_SRES
);
IIST_BUS(0) <= IIST_OUT_0;
IIST_BUS(1) <= iist_line_init;
IIST_BUS(2) <= iist_line_init;
IIST_BUS(3) <= iist_line_init;
end generate IIST;
 
KW11L : ibd_kw11l
port map (
CLK => CLK,
CE_MSEC => CE_MSEC,
RESET => RESET,
BRESET => BRESET,
CPUSUSP => CPUSUSP,
IB_MREQ => IB_MREQ,
IB_SRES => IB_SRES_KW11L,
EI_REQ => EI_REQ_KW11L,
EI_ACK => EI_ACK_KW11L
);
 
RHRP: if sys_conf_ibd_rhrp generate
begin
I0 : ibdr_rhrp
port map (
CLK => CLK,
CE_USEC => CE_USEC,
BRESET => BRESET,
ITIMER => ITIMER,
RB_LAM => RB_LAM_RHRP,
IB_MREQ => IB_MREQ,
IB_SRES => IB_SRES_RHRP,
EI_REQ => EI_REQ_RHRP,
EI_ACK => EI_ACK_RHRP
);
end generate RHRP;
 
RL11: if sys_conf_ibd_rl11 generate
begin
I0 : ibdr_rl11
port map (
CLK => CLK,
CE_MSEC => CE_MSEC,
BRESET => BRESET,
RB_LAM => RB_LAM_RL11,
IB_MREQ => IB_MREQ,
IB_SRES => IB_SRES_RL11,
EI_REQ => EI_REQ_RL11,
EI_ACK => EI_ACK_RL11
);
end generate RL11;
 
RK11: if sys_conf_ibd_rk11 generate
begin
I0 : ibdr_rk11
port map (
CLK => CLK,
CE_MSEC => CE_MSEC,
BRESET => BRESET,
RB_LAM => RB_LAM_RK11,
IB_MREQ => IB_MREQ,
IB_SRES => IB_SRES_RK11,
EI_REQ => EI_REQ_RK11,
EI_ACK => EI_ACK_RK11
);
end generate RK11;
 
TM11: if sys_conf_ibd_tm11 generate
begin
I0 : ibdr_tm11
port map (
CLK => CLK,
BRESET => BRESET,
RB_LAM => RB_LAM_TM11,
IB_MREQ => IB_MREQ,
IB_SRES => IB_SRES_TM11,
EI_REQ => EI_REQ_TM11,
EI_ACK => EI_ACK_TM11
);
end generate TM11;
 
DL11_0 : ibdr_dl11
port map (
CLK => CLK,
CE_USEC => CE_USEC,
RESET => RESET,
BRESET => BRESET,
RB_LAM => RB_LAM_DL11_0,
IB_MREQ => IB_MREQ,
IB_SRES => IB_SRES_DL11_0,
EI_REQ_RX => EI_REQ_DL11RX_0,
EI_REQ_TX => EI_REQ_DL11TX_0,
EI_ACK_RX => EI_ACK_DL11RX_0,
EI_ACK_TX => EI_ACK_DL11TX_0
);
DL11_1: if sys_conf_ibd_dl11_1 generate
begin
I0 : ibdr_dl11
generic map (
IB_ADDR => slv(to_unsigned(8#176500#,16)))
port map (
CLK => CLK,
CE_USEC => CE_USEC,
RESET => RESET,
BRESET => BRESET,
RB_LAM => RB_LAM_DL11_1,
IB_MREQ => IB_MREQ,
IB_SRES => IB_SRES_DL11_1,
EI_REQ_RX => EI_REQ_DL11RX_1,
EI_REQ_TX => EI_REQ_DL11TX_1,
EI_ACK_RX => EI_ACK_DL11RX_1,
EI_ACK_TX => EI_ACK_DL11TX_1
);
end generate DL11_1;
 
PC11: if sys_conf_ibd_pc11 generate
begin
I0 : ibdr_pc11
port map (
CLK => CLK,
RESET => RESET,
BRESET => BRESET,
RB_LAM => RB_LAM_PC11,
IB_MREQ => IB_MREQ,
IB_SRES => IB_SRES_PC11,
EI_REQ_PTR => EI_REQ_PC11PTR,
EI_REQ_PTP => EI_REQ_PC11PTP,
EI_ACK_PTR => EI_ACK_PC11PTR,
EI_ACK_PTP => EI_ACK_PC11PTP
);
end generate PC11;
 
LP11: if sys_conf_ibd_lp11 generate
begin
I0 : ibdr_lp11
port map (
CLK => CLK,
RESET => RESET,
BRESET => BRESET,
RB_LAM => RB_LAM_LP11,
IB_MREQ => IB_MREQ,
IB_SRES => IB_SRES_LP11,
EI_REQ => EI_REQ_LP11,
EI_ACK => EI_ACK_LP11
);
end generate LP11;
 
SDREG : ibdr_sdreg
port map (
CLK => CLK,
RESET => RESET,
IB_MREQ => IB_MREQ,
IB_SRES => IB_SRES_SDREG,
DISPREG => DISPREG
);
 
SRES_OR_1 : ib_sres_or_4
port map (
IB_SRES_1 => IB_SRES_KW11P,
IB_SRES_2 => IB_SRES_IIST,
IB_SRES_3 => IB_SRES_KW11L,
IB_SRES_4 => IB_SRES_DEUNA,
IB_SRES_OR => IB_SRES_1
);
 
SRES_OR_2 : ib_sres_or_4
port map (
IB_SRES_1 => IB_SRES_RHRP,
IB_SRES_2 => IB_SRES_RL11,
IB_SRES_3 => IB_SRES_RK11,
IB_SRES_4 => IB_SRES_TM11,
IB_SRES_OR => IB_SRES_2
);
 
SRES_OR_3 : ib_sres_or_3
port map (
IB_SRES_1 => IB_SRES_DZ11,
IB_SRES_2 => IB_SRES_DL11_0,
IB_SRES_3 => IB_SRES_DL11_1,
IB_SRES_OR => IB_SRES_3
);
 
SRES_OR_4 : ib_sres_or_3
port map (
IB_SRES_1 => IB_SRES_PC11,
IB_SRES_2 => IB_SRES_LP11,
IB_SRES_3 => IB_SRES_SDREG,
IB_SRES_OR => IB_SRES_4
);
 
SRES_OR : ib_sres_or_4
port map (
IB_SRES_1 => IB_SRES_1,
IB_SRES_2 => IB_SRES_2,
IB_SRES_3 => IB_SRES_3,
IB_SRES_4 => IB_SRES_4,
IB_SRES_OR => IB_SRES
);
 
INTMAP : ib_intmap
generic map (
INTMAP => conf_intmap)
port map (
EI_REQ => EI_REQ,
EI_ACKM => EI_ACKM,
EI_ACK => EI_ACK,
EI_PRI => EI_PRI,
EI_VECT => EI_VECT
);
EI_REQ(15) <= EI_REQ_IIST;
EI_REQ(14) <= EI_REQ_KW11L;
EI_REQ(13) <= EI_REQ_RHRP;
EI_REQ(12) <= EI_REQ_RL11;
EI_REQ(11) <= EI_REQ_RK11;
EI_REQ(10) <= EI_REQ_TM11;
EI_REQ( 9) <= EI_REQ_DZ11RX;
EI_REQ( 8) <= EI_REQ_DZ11TX;
EI_REQ( 7) <= EI_REQ_DL11RX_0;
EI_REQ( 6) <= EI_REQ_DL11TX_0;
EI_REQ( 5) <= EI_REQ_DL11RX_1;
EI_REQ( 4) <= EI_REQ_DL11TX_1;
EI_REQ( 3) <= EI_REQ_PC11PTR;
EI_REQ( 2) <= EI_REQ_PC11PTP;
EI_REQ( 1) <= EI_REQ_LP11;
 
EI_ACK_IIST <= EI_ACK(15);
EI_ACK_KW11L <= EI_ACK(14);
EI_ACK_RHRP <= EI_ACK(13);
EI_ACK_RL11 <= EI_ACK(12);
EI_ACK_RK11 <= EI_ACK(11);
EI_ACK_TM11 <= EI_ACK(10);
EI_ACK_DZ11RX <= EI_ACK( 9);
EI_ACK_DZ11TX <= EI_ACK( 8);
EI_ACK_DL11RX_0 <= EI_ACK( 7);
EI_ACK_DL11TX_0 <= EI_ACK( 6);
EI_ACK_DL11RX_1 <= EI_ACK( 5);
EI_ACK_DL11TX_1 <= EI_ACK( 4);
EI_ACK_PC11PTR <= EI_ACK( 3);
EI_ACK_PC11PTP <= EI_ACK( 2);
EI_ACK_LP11 <= EI_ACK( 1);
 
RB_LAM(15 downto 11) <= (others=>'0');
RB_LAM(10) <= RB_LAM_PC11;
RB_LAM( 9) <= RB_LAM_DENUA;
RB_LAM( 8) <= RB_LAM_LP11;
RB_LAM( 7) <= RB_LAM_TM11;
RB_LAM( 6) <= RB_LAM_RHRP;
RB_LAM( 5) <= RB_LAM_RL11;
RB_LAM( 4) <= RB_LAM_RK11;
RB_LAM( 3) <= RB_LAM_DZ11;
RB_LAM( 2) <= RB_LAM_DL11_1;
RB_LAM( 1) <= RB_LAM_DL11_0;
end syn;
/ibdr_maxisys.vbom
0,0 → 1,21
# libs
../vlib/slvtypes.vhd
iblib.vhd
ibdlib.vhd
${sys_conf := sys_conf.vhd}
# components
ibd_iist.vbom
ibd_kw11l.vbom
ibdr_rhrp.vbom
ibdr_rl11.vbom
ibdr_rk11.vbom
ibdr_tm11.vbom
ibdr_dl11.vbom
ibdr_pc11.vbom
ibdr_lp11.vbom
ibdr_sdreg.vbom
ib_sres_or_4.vbom
ib_sres_or_3.vbom
ib_intmap.vbom
# design
ibdr_maxisys.vhd
/ibd_ibmon.vbom
0,0 → 1,9
# libs
../vlib/slvtypes.vhd
../vlib/memlib/memlib.vhd
iblib.vhd
# components
[sim]../vlib/memlib/ram_1swsr_wfirst_gen.vbom
[xst,vsyn]../vlib/memlib/ram_1swsr_wfirst_gen_unisim.vbom
# design
ibd_ibmon.vhd
/ibd_kw11l.vhd
0,0 → 1,172
-- $Id: ibd_kw11l.vhd 676 2015-05-09 16:31:54Z mueller $
--
-- Copyright 2008-2015 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: ibd_kw11l - syn
-- Description: ibus dev(loc): KW11-L (line clock)
--
-- Dependencies: -
-- Test bench: -
-- Target Devices: generic
-- Tool versions: ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2010-10-17 333 12.1 M53d xc3s1000-4 9 23 0 14 s 5.3
-- 2009-07-11 232 10.1.03 K39 xc3s1000-4 8 25 0 15 s 5.3
--
-- Revision History:
-- Date Rev Version Comment
-- 2015-05-09 676 1.2 add CPUSUSP, freeze timer when cpu suspended
-- 2011-11-18 427 1.1.1 now numeric_std clean
-- 2010-10-17 333 1.1 use ibus V2 interface
-- 2009-06-01 221 1.0.5 BUGFIX: add RESET; don't clear tcnt on ibus reset
-- 2008-08-22 161 1.0.4 use iblib; add EI_ACK to proc_next sens. list
-- 2008-05-09 144 1.0.3 use intreq flop, use EI_ACK
-- 2008-01-20 112 1.0.2 fix proc_next sensitivity list; use BRESET
-- 2008-01-06 111 1.0.1 Renamed to ibd_kw11l (RRI_REQ not used)
-- 2008-01-05 110 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
use work.iblib.all;
 
-- ----------------------------------------------------------------------------
entity ibd_kw11l is -- ibus dev(loc): KW11-L (line clock)
-- fixed address: 177546
port (
CLK : in slbit; -- clock
CE_MSEC : in slbit; -- msec pulse
RESET : in slbit; -- system reset
BRESET : in slbit; -- ibus reset
CPUSUSP : in slbit; -- cpu suspended
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 ibd_kw11l;
 
architecture syn of ibd_kw11l is
 
constant ibaddr_kw11l : slv16 := slv(to_unsigned(8#177546#,16));
 
constant lks_ibf_ie : integer := 6;
constant lks_ibf_moni : integer := 7;
 
constant twidth : natural := 5;
constant tdivide : natural := 20;
type regs_type is record -- state registers
ibsel : slbit; -- ibus select
ie : slbit; -- interrupt enable
moni : slbit; -- monitor bit
intreq : slbit; -- interrupt request
tcnt : slv(twidth-1 downto 0); -- timer counter
end record regs_type;
 
constant regs_init : regs_type := (
'0', -- ibsel
'0', -- ie
'1', -- moni (set on reset !!)
'0', -- intreq
(others=>'0') -- tcnt
);
 
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
if BRESET = '1' then -- BRESET is 1 for system and ibus reset
R_REGS <= regs_init;
if RESET = '0' then -- if RESET=0 we do just an ibus reset
R_REGS.tcnt <= N_REGS.tcnt; -- don't clear msec tick counter
end if;
else
R_REGS <= N_REGS;
end if;
end if;
end process proc_regs;
 
proc_next : process (R_REGS, IB_MREQ, CE_MSEC, CPUSUSP, EI_ACK)
variable r : regs_type := regs_init;
variable n : regs_type := regs_init;
variable idout : slv16 := (others=>'0');
variable ibreq : slbit := '0';
variable ibw0 : slbit := '0';
begin
 
r := R_REGS;
n := R_REGS;
 
idout := (others=>'0');
ibreq := IB_MREQ.re or IB_MREQ.we;
ibw0 := IB_MREQ.we and IB_MREQ.be0;
-- ibus address decoder
n.ibsel := '0';
if IB_MREQ.aval='1' and
IB_MREQ.addr=ibaddr_kw11l(12 downto 1) then
n.ibsel := '1';
end if;
 
-- ibus output driver
if r.ibsel = '1' then
idout(lks_ibf_ie) := R_REGS.ie;
idout(lks_ibf_moni) := R_REGS.moni;
end if;
 
-- ibus write transactions
if r.ibsel='1' and ibw0='1' then
n.ie := IB_MREQ.din(lks_ibf_ie);
n.moni := IB_MREQ.din(lks_ibf_moni);
if IB_MREQ.din(lks_ibf_ie)='0' or IB_MREQ.din(lks_ibf_moni)='0' then
n.intreq := '0';
end if;
end if;
-- other state changes
if CE_MSEC='1' and CPUSUSP='0' then -- on msec and not suspended
n.tcnt := slv(unsigned(r.tcnt) + 1);
if unsigned(r.tcnt) = tdivide-1 then
n.tcnt := (others=>'0');
n.moni := '1';
if r.ie = '1' then
n.intreq := '1';
end if;
end if;
end if;
 
if EI_ACK = '1' then
n.intreq := '0';
end if;
N_REGS <= n;
 
IB_SRES.dout <= idout;
IB_SRES.ack <= r.ibsel and ibreq;
IB_SRES.busy <= '0';
EI_REQ <= r.intreq;
end process proc_next;
end syn;
/ibdr_rk11.vhd
0,0 → 1,494
-- $Id: ibdr_rk11.vhd 672 2015-05-02 21:58:28Z mueller $
--
-- Copyright 2008-2015 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_rk11 - syn
-- Description: ibus dev(rem): RK11-A/B
--
-- Dependencies: ram_1swar_gen
-- Test bench: -
-- Target Devices: generic
-- Tool versions: ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2014-06-08 561 14.7 131013 xc6slx16-2 44 139 9 60 s 5.6
-- 2010-10-17 333 12.1 M53d xc3s1000-4 46 248 16 137 s 7.2
-- 2009-06-01 221 10.1.03 K39 xc3s1000-4 46 249 16 148 s 7.1
-- 2008-01-06 111 8.2.03 I34 xc3s1000-4 36 189 16 111 s 6.0
--
-- Revision History:
-- Date Rev Version Comment
-- 2015-05-01 672 1.3 BUGFIX: interrupt after dreset,seek command start
-- 2011-11-18 427 1.2.2 now numeric_std clean
-- 2010-10-23 335 1.2.1 rename RRI_LAM->RB_LAM;
-- 2010-10-17 333 1.2 use ibus V2 interface
-- 2010-06-11 303 1.1 use IB_MREQ.racc instead of RRI_REQ
-- 2009-05-24 219 1.0.9 add CE_MSEC input; inc sector counter every msec
-- BUGFIX: sector counter now counts 000,...,013.
-- 2009-05-21 217 1.0.8 cancel pending interrupt requests when IE=0
-- 2009-05-16 216 1.0.7 BUGFIX: correct interrupt on IE 0->1 logic
-- BUGFIX: re-work the seek complete handling
-- 2008-08-22 161 1.0.6 use iblib
-- 2008-05-30 151 1.0.5 BUGFIX: do control reset locally now, add CRDONE
-- 2008-03-30 131 1.0.4 issue interrupt when IDE bit set with GO=0
-- 2008-02-23 118 1.0.3 remove redundant condition in rkda access code
-- fix bug in control reset logic (we's missing)
-- 2008-01-20 113 1.0.2 Fix busy handling when control reset done
-- 2008-01-20 112 1.0.1 Fix scp handling; use BRESET
-- 2008-01-06 111 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
use work.memlib.all;
use work.iblib.all;
 
-- ----------------------------------------------------------------------------
entity ibdr_rk11 is -- ibus dev(rem): RK11
-- fixed address: 177400
port (
CLK : in slbit; -- clock
CE_MSEC : in slbit; -- msec pulse
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_rk11;
 
architecture syn of ibdr_rk11 is
 
constant ibaddr_rk11 : slv16 := slv(to_unsigned(8#177400#,16));
 
constant ibaddr_rkds : slv3 := "000"; -- rkds address offset
constant ibaddr_rker : slv3 := "001"; -- rker address offset
constant ibaddr_rkcs : slv3 := "010"; -- rkcs address offset
constant ibaddr_rkwc : slv3 := "011"; -- rkwc address offset
constant ibaddr_rkba : slv3 := "100"; -- rkba address offset
constant ibaddr_rkda : slv3 := "101"; -- rkda address offset
constant ibaddr_rkmr : slv3 := "110"; -- rkmr address offset
constant ibaddr_rkdb : slv3 := "111"; -- rkdb address offset
subtype rkds_ibf_id is integer range 15 downto 13;
constant rkds_ibf_adry : integer := 6;
constant rkds_ibf_scsa : integer := 4;
subtype rkds_ibf_sc is integer range 3 downto 0;
 
subtype rker_ibf_he is integer range 15 downto 5;
constant rker_ibf_cse : integer := 1;
constant rker_ibf_wce : integer := 0;
 
constant rkcs_ibf_err : integer := 15;
constant rkcs_ibf_he : integer := 14;
constant rkcs_ibf_scp : integer := 13;
constant rkcs_ibf_maint : integer := 12;
constant rkcs_ibf_rdy : integer := 7;
constant rkcs_ibf_ide : integer := 6;
subtype rkcs_ibf_mex is integer range 5 downto 4;
subtype rkcs_ibf_func is integer range 3 downto 1;
constant rkcs_ibf_go : integer := 0;
 
subtype rkda_ibf_drsel is integer range 15 downto 13;
 
subtype rkmr_ibf_rid is integer range 15 downto 13; -- rem id
constant rkmr_ibf_crdone: integer := 11; -- contr. reset done
constant rkmr_ibf_sbclr : integer := 10; -- clear sbusy's
constant rkmr_ibf_creset: integer := 9; -- control reset
constant rkmr_ibf_fdone : integer := 8; -- func done
subtype rkmr_ibf_sdone is integer range 7 downto 0; -- seek done
 
constant func_creset : slv3 := "000"; -- func: control reset
constant func_write : slv3 := "001"; -- func: write
constant func_read : slv3 := "010"; -- func: read
constant func_wchk : slv3 := "011"; -- func: write check
constant func_seek : slv3 := "100"; -- func: seek
constant func_rchk : slv3 := "101"; -- func: read check
constant func_dreset : slv3 := "110"; -- func: drive reset
constant func_wlock : slv3 := "111"; -- func: write lock
 
type state_type is (
s_idle,
s_init
);
 
type regs_type is record -- state registers
ibsel : slbit; -- ibus select
state : state_type; -- state
id : slv3; -- rkds: drive id of search done
sc : slv4; -- rkds: sector counter
cse : slbit; -- rker: check sum error
wce : slbit; -- rker: write check error
he : slbit; -- rkcs: hard error
scp : slbit; -- rkcs: seek complete
maint : slbit; -- rkcs: maintenance mode
rdy : slbit; -- rkcs: control ready
ide : slbit; -- rkcs: interrupt on done enable
drsel : slv3; -- rkda: currently selected drive
fireq : slbit; -- func done interrupt request flag
sireq : slv8; -- seek done interrupt request flags
sbusy : slv8; -- seek busy flags
rid : slv3; -- drive id for rem ds reads
icnt : slv3; -- init state counter
creset : slbit; -- control reset flag
crdone : slbit; -- control reset done since last fdone
end record regs_type;
 
constant regs_init : regs_type := (
'0', -- ibsel
s_init, -- state
(others=>'0'), -- id
(others=>'0'), -- sc
'0','0', -- cse, wce
'0','0','0', -- he, scp, maint
'1', -- rdy (SET TO 1)
'0', -- ide
(others=>'0'), -- drsel
'0', -- fireq
(others=>'0'), -- sireq
(others=>'0'), -- sbusy
(others=>'0'), -- rid
(others=>'0'), -- icnt
'0','1' -- creset, crdone
);
 
signal R_REGS : regs_type := regs_init;
signal N_REGS : regs_type := regs_init;
 
signal MEM_1_WE : slbit := '0';
signal MEM_0_WE : slbit := '0';
signal MEM_ADDR : slv4 := (others=>'0');
signal MEM_DIN : slv16 := (others=>'0');
signal MEM_DOUT : slv16 := (others=>'0');
begin
MEM_1 : ram_1swar_gen
generic map (
AWIDTH => 4,
DWIDTH => 8)
port map (
CLK => CLK,
WE => MEM_1_WE,
ADDR => MEM_ADDR,
DI => MEM_DIN(ibf_byte1),
DO => MEM_DOUT(ibf_byte1));
 
MEM_0 : ram_1swar_gen
generic map (
AWIDTH => 4,
DWIDTH => 8)
port map (
CLK => CLK,
WE => MEM_0_WE,
ADDR => MEM_ADDR,
DI => MEM_DIN(ibf_byte0),
DO => MEM_DOUT(ibf_byte0));
 
proc_regs: process (CLK)
begin
if rising_edge(CLK) then
if BRESET='1' or R_REGS.creset='1' then
R_REGS <= regs_init;
if R_REGS.creset = '1' then
R_REGS.sbusy <= N_REGS.sbusy;
end if;
else
R_REGS <= N_REGS;
end if;
end if;
end process proc_regs;
 
proc_next : process (R_REGS, CE_MSEC, IB_MREQ, MEM_DOUT, EI_ACK)
variable r : regs_type := regs_init;
variable n : regs_type := regs_init;
variable ibhold : slbit := '0';
variable icrip : 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';
variable iscval : slbit := '0';
variable iscid : slv3 := (others=>'0');
variable iei_req : slbit := '0';
variable imem_we0 : slbit := '0';
variable imem_we1 : slbit := '0';
variable imem_addr : slv4 := (others=>'0');
variable imem_din : slv16 := (others=>'0');
begin
 
r := R_REGS;
n := R_REGS;
 
ibhold := '0';
icrip := '0';
idout := (others=>'0');
ibrem := IB_MREQ.racc or r.maint;
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';
iscval := '0';
iscid := (others=>'0');
iei_req := '0';
 
imem_we0 := '0';
imem_we1 := '0';
imem_addr := '0' & IB_MREQ.addr(3 downto 1);
imem_din := IB_MREQ.din;
-- ibus address decoder
n.ibsel := '0';
if IB_MREQ.aval = '1' and
IB_MREQ.addr(12 downto 4)=ibaddr_rk11(12 downto 4) then
n.ibsel := '1';
end if;
 
-- internal state machine (for control reset)
case r.state is
when s_idle =>
null;
 
when s_init =>
ibhold := r.ibsel; -- hold ibus when controller busy
icrip := '1';
n.icnt := slv(unsigned(r.icnt) + 1);
if unsigned(r.icnt) = 7 then
n.state := s_idle;
end if;
when others => null;
end case;
 
-- ibus transactions
if r.ibsel='1' and ibhold='0' then -- selected and not holding
idout := MEM_DOUT;
imem_we0 := ibw0;
imem_we1 := ibw1;
case IB_MREQ.addr(3 downto 1) is
 
when ibaddr_rkds => -- RKDS -- drive status register ----
if ibrem = '0' then
imem_addr := '1' & r.drsel; -- loc read ds data: drsel as addr.
else
imem_addr := '1' & r.rid; -- rem read ds data: rid as addr.
end if;
idout(rkds_ibf_id) := r.id;
if ibrem = '0' then -- loc ? simulate drive sector monitor
if r.sc = MEM_DOUT(rkds_ibf_sc) then
idout(rkds_ibf_scsa) := '1';
else
idout(rkds_ibf_scsa) := '0';
end if;
idout(rkds_ibf_sc) := r.sc;
end if;
 
if r.sbusy(to_integer(unsigned(imem_addr(2 downto 0))))='1' then
idout(rkds_ibf_adry) := '0'; -- clear drive access rdy
end if;
if ibwrem = '1' then -- rem write ? than update ds data
imem_addr := '1' & IB_MREQ.din(rkds_ibf_id); -- use id field as addr
else -- loc write ?
imem_we0 := '0'; -- suppress we, is read-only
imem_we1 := '0';
end if;
when ibaddr_rker => -- RKER -- error register ------------
idout(4 downto 2) := (others=>'0'); -- unassigned bits
idout(rker_ibf_cse) := r.cse; -- use state bits (cleared at go !)
idout(rker_ibf_wce) := r.wce;
if ibwrem = '1' then -- rem write ?
if unsigned(IB_MREQ.din(rker_ibf_he)) /= 0 then -- hard errors set ?
n.he := '1';
else
n.he := '0';
end if;
n.cse := IB_MREQ.din(rker_ibf_cse); -- mirror cse bit
n.wce := IB_MREQ.din(rker_ibf_wce); -- mirror wce bit
else -- loc write ?
imem_we0 := '0'; -- suppress we, is read-only
imem_we1 := '0';
end if;
when ibaddr_rkcs => -- RKCS -- control status register ---
idout(rkcs_ibf_err) := r.he or r.cse or r.wce;
idout(rkcs_ibf_he) := r.he;
idout(rkcs_ibf_scp) := r.scp;
idout(rkcs_ibf_rdy) := r.rdy;
idout(rkcs_ibf_go) := not r.rdy;
 
if ibw1 = '1' then
n.maint := IB_MREQ.din(rkcs_ibf_maint); -- mirror maint bit
end if;
 
if ibw0 = '1' then
n.ide := IB_MREQ.din(rkcs_ibf_ide); -- mirror ide bit
if n.ide = '0' then -- if IE set to 0
n.fireq := '0'; -- cancel all pending
n.sireq := (others=>'0'); -- interrupt requests
end if;
 
if IB_MREQ.din(rkcs_ibf_go) = '1' then -- GO=1 ?
if r.rdy = '1' then -- ready and GO ?
n.scp := '0'; -- go clears scp !
n.rdy := '0'; -- mark busy
n.cse := '0'; -- clear soft errors
n.wce := '0';
n.fireq := '0'; -- cancel pend. int
 
if IB_MREQ.din(rkcs_ibf_func)=func_creset then -- control reset?
n.creset := '1'; -- handle locally
else
ilam := '1'; -- issue lam
end if;
if IB_MREQ.din(rkcs_ibf_func)=func_seek or -- if seek
IB_MREQ.din(rkcs_ibf_func)=func_dreset then -- or drive reset
n.sbusy(to_integer(unsigned(r.drsel))) := '1'; -- drive busy
if n.ide = '1' then -- if enabled
n.fireq := '1'; -- interrupt !
end if;
end if;
 
end if;
else -- GO=0
if r.ide='0' and n.ide='1' and -- if IDE 0->1 transition
r.rdy='1' then -- and controller ready
n.fireq := '1'; -- issue interrupt
end if;
end if;
end if;
when ibaddr_rkda => -- RKDA -- disk address register -----
if ibrem = '0' then -- loc access ?
if r.rdy = '0' then -- controller busy ?
imem_we0 := '0'; -- suppress write
imem_we1 := '0';
end if;
end if;
if imem_we1 = '1' then
n.drsel := IB_MREQ.din(rkda_ibf_drsel); -- mirror drsel bits
end if;
 
when ibaddr_rkmr => -- RKMR -- maintenance register ------
idout := (others=>'0');
idout(rkmr_ibf_rid) := r.rid;
idout(rkmr_ibf_crdone) := r.crdone;
idout(rkmr_ibf_sdone) := r.sbusy;
if ibwrem = '1' then -- rem write ?
n.rid := IB_MREQ.din(rkmr_ibf_rid);
 
if r.ide='1' and IB_MREQ.din(rkmr_ibf_sbclr)='0' then
n.sireq := r.sireq or (IB_MREQ.din(rkmr_ibf_sdone) and r.sbusy);
end if;
n.sbusy := r.sbusy and not IB_MREQ.din(rkmr_ibf_sdone);
if IB_MREQ.din(rkmr_ibf_fdone) = '1' then -- func completed
n.rdy := '1';
n.crdone := '0';
if r.ide = '1' then
n.fireq := '1';
end if;
end if;
if IB_MREQ.din(rkmr_ibf_creset) = '1' then -- control reset
n.creset := '1';
end if;
end if;
when others => -- all other regs
null;
end case;
end if;
 
iscval := '1';
if r.sireq(7) = '1' then iscid := "111";
elsif r.sireq(6) = '1' then iscid := "110";
elsif r.sireq(5) = '1' then iscid := "101";
elsif r.sireq(4) = '1' then iscid := "100";
elsif r.sireq(3) = '1' then iscid := "011";
elsif r.sireq(2) = '1' then iscid := "010";
elsif r.sireq(1) = '1' then iscid := "001";
elsif r.sireq(0) = '1' then iscid := "000";
else
iscval := '0';
end if;
 
if r.ide = '1' then
if r.fireq='1' or iscval='1' then
iei_req := '1';
end if;
end if;
 
if EI_ACK = '1' then -- interrupt executed
if r.fireq = '1' then
n.scp := '0'; -- clear scp flag, is command end
n.fireq := '0';
elsif iscval = '1' then -- was a seek done
n.scp := '1'; -- signal seek complete interrupt
n.id := iscid; -- load id
n.sireq(to_integer(unsigned(iscid))) := '0'; -- reset sireq bit
end if;
end if;
if icrip = '1' then -- control reset in progress ?
imem_addr := '0' & r.icnt; -- use icnt as addr
imem_din := (others=>'0'); -- force data to zero
imem_we0 := '1'; -- enable writes
imem_we1 := '1';
end if;
 
if CE_MSEC = '1' then -- advance sector counter every msec
if unsigned(r.sc) = 8#13# then -- sector counter (count to 8#13#)
n.sc := (others=>'0');
else
n.sc := slv(unsigned(r.sc) + 1);
end if;
end if;
N_REGS <= n;
 
MEM_0_WE <= imem_we0;
MEM_1_WE <= imem_we1;
MEM_ADDR <= imem_addr;
MEM_DIN <= imem_din;
IB_SRES.dout <= idout;
IB_SRES.ack <= r.ibsel and ibreq;
IB_SRES.busy <= ibhold and ibreq;
 
RB_LAM <= ilam;
EI_REQ <= iei_req;
end process proc_next;
 
end syn;
/iblib.vhd
0,0 → 1,164
-- $Id: iblib.vhd 672 2015-05-02 21:58:28Z mueller $
--
-- Copyright 2008-2015 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.
--
------------------------------------------------------------------------------
-- Package Name: iblib
-- Description: Definitions for ibus interface and bus entities
--
-- Dependencies: -
-- Tool versions: ise 8.1-14.7; viv 2014.4; ghdl 0.18-0.31
-- Revision History:
-- Date Rev Version Comment
-- 2015-04-24 668 2.1 add ibd_ibmon
-- 2010-10-23 335 2.0.1 add ib_sel; add ib_sres_or_mon
-- 2010-10-17 333 2.0 ibus V2 interface: use aval,re,we,rmw
-- 2010-06-11 303 1.1 added racc,cacc signals to ib_mreq_type
-- 2009-06-01 221 1.0.1 added dip signal to ib_mreq_type
-- 2008-08-22 161 1.0 Initial version (extracted from pdp11.vhd)
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
 
package iblib is
 
type ib_mreq_type is record -- ibus - master request
aval : slbit; -- address valid
re : slbit; -- read enable
we : slbit; -- write enable
rmw : slbit; -- read-modify-write
be0 : slbit; -- byte enable low
be1 : slbit; -- byte enable high
cacc : slbit; -- console access
racc : slbit; -- remote access
addr : slv13_1; -- address bit(12:1)
din : slv16; -- data (input to slave)
end record ib_mreq_type;
 
constant ib_mreq_init : ib_mreq_type :=
('0','0','0','0', -- aval, re, we, rmw
'0','0','0','0', -- be0, be1, cacc, racc
(others=>'0'), -- addr
(others=>'0')); -- din
 
type ib_sres_type is record -- ibus - slave response
ack : slbit; -- acknowledge
busy : slbit; -- busy
dout : slv16; -- data (output from slave)
end record ib_sres_type;
 
constant ib_sres_init : ib_sres_type :=
('0','0', -- ack, busy
(others=>'0')); -- dout
 
type ib_sres_vector is array (natural range <>) of ib_sres_type;
 
subtype ibf_byte1 is integer range 15 downto 8;
subtype ibf_byte0 is integer range 7 downto 0;
 
component ib_sel is -- ibus address select logic
generic (
IB_ADDR : slv16; -- ibus address base
SAWIDTH : natural := 0); -- device subaddress space width
port (
CLK : in slbit; -- clock
IB_MREQ : in ib_mreq_type; -- ibus request
SEL : out slbit -- select state bit
);
end component;
 
component ib_sres_or_2 is -- ibus result or, 2 input
port (
IB_SRES_1 : in ib_sres_type; -- ib_sres input 1
IB_SRES_2 : in ib_sres_type := ib_sres_init; -- ib_sres input 2
IB_SRES_OR : out ib_sres_type -- ib_sres or'ed output
);
end component;
component ib_sres_or_3 is -- ibus result or, 3 input
port (
IB_SRES_1 : in ib_sres_type; -- ib_sres input 1
IB_SRES_2 : in ib_sres_type := ib_sres_init; -- ib_sres input 2
IB_SRES_3 : in ib_sres_type := ib_sres_init; -- ib_sres input 3
IB_SRES_OR : out ib_sres_type -- ib_sres or'ed output
);
end component;
component ib_sres_or_4 is -- ibus result or, 4 input
port (
IB_SRES_1 : in ib_sres_type; -- ib_sres input 1
IB_SRES_2 : in ib_sres_type := ib_sres_init; -- ib_sres input 2
IB_SRES_3 : in ib_sres_type := ib_sres_init; -- ib_sres input 3
IB_SRES_4 : in ib_sres_type := ib_sres_init; -- ib_sres input 4
IB_SRES_OR : out ib_sres_type -- ib_sres or'ed output
);
end component;
 
component ib_sres_or_gen is -- ibus result or, generic
generic (
WIDTH : natural := 4); -- number of input ports
port (
IB_SRES_IN : in ib_sres_vector(1 to WIDTH); -- ib_sres input array
IB_SRES_OR : out ib_sres_type -- ib_sres or'ed output
);
end component;
 
type intmap_type is record -- interrupt map entry type
vec : integer; -- vector address
pri : integer; -- priority
end record intmap_type;
constant intmap_init : intmap_type := (0,0);
 
type intmap_array_type is array (15 downto 0) of intmap_type;
constant intmap_array_init : intmap_array_type := (others=>intmap_init);
 
component ib_intmap is -- external interrupt mapper
generic (
INTMAP : intmap_array_type := intmap_array_init);
port (
EI_REQ : in slv16_1; -- interrupt request lines
EI_ACKM : in slbit; -- interrupt acknowledge (from master)
EI_ACK : out slv16_1; -- interrupt acknowledge (to requestor)
EI_PRI : out slv3; -- interrupt priority
EI_VECT : out slv9_2 -- interrupt vector
);
end component;
 
component ibd_ibmon is -- ibus dev: ibus monitor
generic (
IB_ADDR : slv16 := slv(to_unsigned(8#160000#,16));
AWIDTH : natural := 9);
port (
CLK : in slbit; -- clock
RESET : in slbit; -- reset
IB_MREQ : in ib_mreq_type; -- ibus: request
IB_SRES : out ib_sres_type; -- ibus: response
IB_SRES_SUM : in ib_sres_type -- ibus: response (sum for monitor)
);
end component;
 
--
-- components for use in test benches (not synthesizable)
--
component ib_sres_or_mon is -- ibus result or monitor
port (
IB_SRES_1 : in ib_sres_type; -- ib_sres input 1
IB_SRES_2 : in ib_sres_type := ib_sres_init; -- ib_sres input 2
IB_SRES_3 : in ib_sres_type := ib_sres_init; -- ib_sres input 3
IB_SRES_4 : in ib_sres_type := ib_sres_init -- ib_sres input 4
);
end component;
 
end package iblib;
/ibd_ibmon.vhd
0,0 → 1,486
-- $Id: ibd_ibmon.vhd 672 2015-05-02 21:58:28Z mueller $
--
-- Copyright 2015- 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: ibd_ibmon - syn
-- Description: ibus dev: ibus monitor
--
-- Dependencies: memlib/ram_1swsr_wfirst_gen
--
-- Test bench: -
--
-- Target Devices: generic
-- Tool versions: xst 14.7; viv 2014.4; ghdl 0.31
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2015-04-24 668 14.7 131013 xc6slx16-2 112 235 0 83 s 5.6
--
-- Revision History:
-- Date Rev Version Comment
-- 2015-05-02 672 1.0.1 use natural for AWIDTH to work around a ghdl issue
-- 2015-04-24 668 1.0 Initial version (derived from rbd_rbmon)
------------------------------------------------------------------------------
--
-- Addr Bits Name r/w/f Function
-- 000 cntl r/w/f Control register
-- 05 conena r/w/- con enable
-- 04 remena r/w/- rem enable
-- 03 locena r/w/- loc enable
-- 02 wena r/w/- wrap enable
-- 01 stop r/w/f writing 1 stops moni
-- 00 start r/w/f writing 1 starts moni and clears addr
-- 001 stat r/w/- Status register
-- 15:13 bsize r/-/- buffer size (AWIDTH-9)
-- 00 wrap r/-/- line address wrapped (cleared on go)
-- 010 12:01 hilim r/w/- upper address limit, inclusive (def: 177776)
-- 011 12:01 lolim r/w/- lower address limit, inclusive (def: 160000)
-- 100 addr r/w/- Address register
-- *:02 laddr r/w/- line address
-- 01:00 waddr r/w/- word address
-- 101 data r/w/- Data register
--
-- data format:
-- word 3 15 : burst (2nd re/we in a aval sequence)
-- 14 : tout (busy in last re-we cycle)
-- 13 : nak (no ack in last non-busy cycle)
-- 12 : ack (ack seen)
-- 11 : busy (busy seen)
-- 10 : -- (reserved in case err is implemented)
-- 09 : we (write cycle)
-- 08 : rmw (read-modify-write)
-- 07:00 : delay to prev (msb's)
-- word 2 15:10 : delay to prev (lsb's)
-- 09:00 : number of busy cycles
-- word 1 : data
-- word 0 15 : be1 (byte enable low)
-- 14 : be0 (byte enable high)
-- 13 : racc (remote access)
-- 12:01 : addr (word address)
-- 0 : cacc (console access)
--
 
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
use work.memlib.all;
use work.iblib.all;
 
-- Note: AWIDTH has type natural to allow AWIDTH=0 can be used in if generates
-- to control the instantiation. ghdl checks even for not instantiated
-- entities the validity of generics, that's why natural needed here ....
 
entity ibd_ibmon is -- ibus dev: ibus monitor
generic (
IB_ADDR : slv16 := slv(to_unsigned(8#160000#,16)); -- base address
AWIDTH : natural := 9); -- buffer size
port (
CLK : in slbit; -- clock
RESET : in slbit; -- reset
IB_MREQ : in ib_mreq_type; -- ibus: request
IB_SRES : out ib_sres_type; -- ibus: response
IB_SRES_SUM : in ib_sres_type -- ibus: response (sum for monitor)
);
end entity ibd_ibmon;
 
 
architecture syn of ibd_ibmon is
 
constant ibaddr_cntl : slv3 := "000"; -- cntl address offset
constant ibaddr_stat : slv3 := "001"; -- stat address offset
constant ibaddr_hilim : slv3 := "010"; -- hilim address offset
constant ibaddr_lolim : slv3 := "011"; -- lolim address offset
constant ibaddr_addr : slv3 := "100"; -- addr address offset
constant ibaddr_data : slv3 := "101"; -- data address offset
 
constant cntl_ibf_conena : integer := 5;
constant cntl_ibf_remena : integer := 4;
constant cntl_ibf_locena : integer := 3;
constant cntl_ibf_wena : integer := 2;
constant cntl_ibf_stop : integer := 1;
constant cntl_ibf_start : integer := 0;
subtype stat_ibf_bsize is integer range 15 downto 13;
constant stat_ibf_wrap : integer := 0;
subtype addr_ibf_laddr is integer range 2+AWIDTH-1 downto 2;
subtype addr_ibf_waddr is integer range 1 downto 0;
 
subtype iba_ibf_pref is integer range 15 downto 13;
subtype iba_ibf_addr is integer range 12 downto 1;
 
constant dat3_ibf_burst : integer := 15;
constant dat3_ibf_tout : integer := 14;
constant dat3_ibf_nak : integer := 13;
constant dat3_ibf_ack : integer := 12;
constant dat3_ibf_busy : integer := 11;
constant dat3_ibf_we : integer := 9;
constant dat3_ibf_rmw : integer := 8;
subtype dat3_ibf_ndlymsb is integer range 7 downto 0;
subtype dat2_ibf_ndlylsb is integer range 15 downto 10;
subtype dat2_ibf_nbusy is integer range 9 downto 0;
constant dat0_ibf_be1 : integer := 15;
constant dat0_ibf_be0 : integer := 14;
constant dat0_ibf_racc : integer := 13;
subtype dat0_ibf_addr is integer range 12 downto 1;
constant dat0_ibf_cacc : integer := 0;
 
type regs_type is record -- state registers
ibsel : slbit; -- ibus select
conena : slbit; -- conena flag (record console access)
remena : slbit; -- remena flag (record remote access)
locena : slbit; -- locena flag (record local access)
wena : slbit; -- wena flag (wrap enable)
go : slbit; -- go flag
hilim : slv13_1; -- upper address limit
lolim : slv13_1; -- lower address limit
wrap : slbit; -- laddr wrap flag
laddr : slv(AWIDTH-1 downto 0); -- line address
waddr : slv2; -- word address
ibtake_1 : slbit; -- ib capture active in last cycle
ibaddr : slv13_1; -- ibus trace: addr
ibwe : slbit; -- ibus trace: we
ibrmw : slbit; -- ibus trace: rmw
ibbe0 : slbit; -- ibus trace: be0
ibbe1 : slbit; -- ibus trace: be1
ibcacc : slbit; -- ibus trace: cacc
ibracc : slbit; -- ibus trace: racc
iback : slbit; -- ibus trace: ack seen
ibbusy : slbit; -- ibus trace: busy seen
ibnak : slbit; -- ibus trace: nak detected
ibtout : slbit; -- ibus trace: tout detected
ibburst : slbit; -- ibus trace: burst detected
ibdata : slv16; -- ibus trace: data
ibnbusy : slv10; -- ibus number of busy cycles
ibndly : slv14; -- ibus delay to prev. access
end record regs_type;
 
constant laddrzero : slv(AWIDTH-1 downto 0) := (others=>'0');
constant laddrlast : slv(AWIDTH-1 downto 0) := (others=>'1');
constant regs_init : regs_type := (
'0', -- ibsel
'1','1','1','1','1', -- conena,remena,locena,wena,go
(others=>'1'), -- hilim (def: 177776)
(others=>'0'), -- lolim (def: 160000)
'0', -- wrap
laddrzero, -- laddr
"00", -- waddr
'0', -- ibtake_1
(others=>'0'), -- ibaddr
'0','0','0','0','0','0', -- ibwe,ibrmw,ibbe0,ibbe1,ibcacc,ibracc
'0','0', -- iback,ibbusy
'0','0','0', -- ibnak,ibtout,ibburst
(others=>'0'), -- ibdata
(others=>'0'), -- ibnbusy
(others=>'0') -- ibndly
);
 
constant ibnbusylast : slv10 := (others=>'1');
constant ibndlylast : slv14 := (others=>'1');
 
signal R_REGS : regs_type := regs_init;
signal N_REGS : regs_type := regs_init;
 
signal BRAM_EN : slbit := '0';
signal BRAM_WE : slbit := '0';
signal BRAM0_DI : slv32 := (others=>'0');
signal BRAM1_DI : slv32 := (others=>'0');
signal BRAM0_DO : slv32 := (others=>'0');
signal BRAM1_DO : slv32 := (others=>'0');
begin
 
assert AWIDTH>=9 and AWIDTH<=14
report "assert(AWIDTH>=9 and AWIDTH<=14): unsupported AWIDTH"
severity failure;
 
BRAM1 : ram_1swsr_wfirst_gen
generic map (
AWIDTH => AWIDTH,
DWIDTH => 32)
port map (
CLK => CLK,
EN => BRAM_EN,
WE => BRAM_WE,
ADDR => R_REGS.laddr,
DI => BRAM1_DI,
DO => BRAM1_DO
);
 
BRAM0 : ram_1swsr_wfirst_gen
generic map (
AWIDTH => AWIDTH,
DWIDTH => 32)
port map (
CLK => CLK,
EN => BRAM_EN,
WE => BRAM_WE,
ADDR => R_REGS.laddr,
DI => BRAM0_DI,
DO => BRAM0_DO
);
 
proc_regs: process (CLK)
begin
if rising_edge(CLK) then
if RESET = '1' then
R_REGS <= regs_init;
else
R_REGS <= N_REGS;
end if;
end if;
end process proc_regs;
 
proc_next : process (R_REGS, IB_MREQ, IB_SRES_SUM, BRAM0_DO, BRAM1_DO)
variable r : regs_type := regs_init;
variable n : regs_type := regs_init;
variable iib_ack : slbit := '0';
variable iib_busy : slbit := '0';
variable iib_dout : slv16 := (others=>'0');
variable iibena : slbit := '0';
variable ibramen : slbit := '0'; -- BRAM enable
variable ibramwe : slbit := '0'; -- BRAN we
variable ibtake : slbit := '0';
variable laddr_inc : slbit := '0';
variable idat0 : slv16 := (others=>'0');
variable idat1 : slv16 := (others=>'0');
variable idat2 : slv16 := (others=>'0');
variable idat3 : slv16 := (others=>'0');
begin
 
r := R_REGS;
n := R_REGS;
 
iib_ack := '0';
iib_busy := '0';
iib_dout := (others=>'0');
 
iibena := IB_MREQ.re or IB_MREQ.we;
ibramen := '0';
ibramwe := '0';
 
laddr_inc := '0';
-- ibus address decoder
n.ibsel := '0';
if IB_MREQ.aval='1' and IB_MREQ.addr(12 downto 4)=IB_ADDR(12 downto 4) then
n.ibsel := '1';
ibramen := '1';
end if;
 
-- ibus transactions (react only on console (this includes racc))
if r.ibsel = '1' and IB_MREQ.cacc='1' then
 
iib_ack := iibena; -- ack all accesses
 
case IB_MREQ.addr(3 downto 1) is
 
when ibaddr_cntl => -- cntl ------------------
if IB_MREQ.we = '1' then
n.conena := IB_MREQ.din(cntl_ibf_conena);
n.remena := IB_MREQ.din(cntl_ibf_remena);
n.locena := IB_MREQ.din(cntl_ibf_locena);
n.wena := IB_MREQ.din(cntl_ibf_wena);
if IB_MREQ.din(cntl_ibf_start) = '1' then
n.go := '1';
n.wrap := '0';
n.laddr := laddrzero;
n.waddr := "00";
end if;
if IB_MREQ.din(cntl_ibf_stop) = '1' then
n.go := '0';
end if;
end if;
when ibaddr_stat => null; -- stat ------------------
 
when ibaddr_hilim => -- hilim -----------------
if IB_MREQ.we = '1' then
n.hilim := IB_MREQ.din(iba_ibf_addr);
end if;
when ibaddr_lolim => -- lolim -----------------
if IB_MREQ.we = '1' then
n.lolim := IB_MREQ.din(iba_ibf_addr);
end if;
when ibaddr_addr => -- addr ------------------
if IB_MREQ.we = '1' then
n.go := '0';
n.wrap := '0';
n.laddr := IB_MREQ.din(addr_ibf_laddr);
n.waddr := IB_MREQ.din(addr_ibf_waddr);
end if;
 
when ibaddr_data => -- data ------------------
if r.go='1' or IB_MREQ.we='1' then
iib_ack := '0'; -- error, do nak
end if;
if IB_MREQ.re = '1' then
n.waddr := slv(unsigned(r.waddr) + 1);
if r.waddr = "11" then
laddr_inc := '1';
end if;
end if;
 
when others => -- <> --------------------
iib_ack := '0'; -- error, do nak
end case;
end if;
 
-- ibus output driver
if r.ibsel = '1' then
case IB_MREQ.addr(3 downto 1) is
when ibaddr_cntl => -- cntl ------------------
iib_dout(cntl_ibf_conena) := r.conena;
iib_dout(cntl_ibf_remena) := r.remena;
iib_dout(cntl_ibf_locena) := r.locena;
iib_dout(cntl_ibf_wena) := r.wena;
iib_dout(cntl_ibf_start) := r.go;
when ibaddr_stat => -- stat ------------------
iib_dout(stat_ibf_bsize) := slv(to_unsigned(AWIDTH-9,3));
iib_dout(stat_ibf_wrap) := r.wrap;
when ibaddr_hilim => -- hilim -----------------
iib_dout(iba_ibf_pref) := (others=>'1');
iib_dout(iba_ibf_addr) := r.hilim;
when ibaddr_lolim => -- lolim -----------------
iib_dout(iba_ibf_pref) := (others=>'1');
iib_dout(iba_ibf_addr) := r.lolim;
when ibaddr_addr => -- addr ------------------
iib_dout(addr_ibf_laddr) := r.laddr;
iib_dout(addr_ibf_waddr) := r.waddr;
when ibaddr_data => -- data ------------------
case r.waddr is
when "11" => iib_dout := BRAM1_DO(31 downto 16);
when "10" => iib_dout := BRAM1_DO(15 downto 0);
when "01" => iib_dout := BRAM0_DO(31 downto 16);
when "00" => iib_dout := BRAM0_DO(15 downto 0);
when others => null;
end case;
when others => null;
end case;
end if;
 
-- ibus monitor
-- a ibus transaction are captured if the address is in alim window
-- and the access is not refering to ibd_ibmon itself
ibtake := '0';
if IB_MREQ.aval='1' and iibena='1' then -- aval and (re or we)
if unsigned(IB_MREQ.addr)>=unsigned(r.lolim) and -- and in addr window
unsigned(IB_MREQ.addr)<=unsigned(r.hilim) and
r.ibsel='0' then -- and not self
if (r.locena='1' and IB_MREQ.cacc='0' and IB_MREQ.racc='0') or
(r.remena='1' and IB_MREQ.racc='1') or
(r.conena='1' and IB_MREQ.cacc='1') then
ibtake := '1';
end if;
end if;
end if;
 
if ibtake = '1' then -- if capture active
n.ibaddr := IB_MREQ.addr; -- keep track of some state
n.ibwe := IB_MREQ.we;
n.ibrmw := IB_MREQ.rmw;
n.ibbe0 := IB_MREQ.be0;
n.ibbe1 := IB_MREQ.be1;
n.ibcacc := IB_MREQ.cacc;
n.ibracc := IB_MREQ.racc;
if IB_MREQ.we='1' then -- for write of din
n.ibdata := IB_MREQ.din;
else -- for read of dout
n.ibdata := IB_SRES_SUM.dout;
end if;
if r.ibtake_1 = '0' then -- if initial cycle of a transaction
n.iback := IB_SRES_SUM.ack;
n.ibbusy := IB_SRES_SUM.busy;
n.ibnbusy := (others=>'0');
else -- if non-initial cycles
if r.ibnbusy /= ibnbusylast then -- and count
n.ibnbusy := slv(unsigned(r.ibnbusy) + 1);
end if;
end if;
n.ibnak := not IB_SRES_SUM.ack;
n.ibtout := IB_SRES_SUM.busy;
 
else -- if capture not active
if r.go='1' and r.ibtake_1='1' then -- active and transaction just ended
ibramen := '1';
ibramwe := '1';
laddr_inc := '1';
n.ibburst := '1'; -- assume burst
end if;
if r.ibtake_1 = '1' then -- ibus transaction just ended
n.ibndly := (others=>'0'); -- clear delay counter
else -- just idle
if r.ibndly /= ibndlylast then -- count cycles
n.ibndly := slv(unsigned(r.ibndly) + 1);
end if;
end if;
end if;
 
if IB_MREQ.aval = '0' then -- if aval gone
n.ibburst := '0'; -- clear burst flag
end if;
if laddr_inc = '1' then
n.laddr := slv(unsigned(r.laddr) + 1);
if r.go='1' and r.laddr=laddrlast then
if r.wena = '1' then
n.wrap := '1';
else
n.go := '0';
end if;
end if;
end if;
idat3 := (others=>'0');
idat3(dat3_ibf_burst) := r.ibburst;
idat3(dat3_ibf_tout) := r.ibtout;
idat3(dat3_ibf_nak) := r.ibnak;
idat3(dat3_ibf_ack) := r.iback;
idat3(dat3_ibf_busy) := r.ibbusy;
idat3(dat3_ibf_we) := r.ibwe;
idat3(dat3_ibf_rmw) := r.ibrmw;
idat3(dat3_ibf_ndlymsb):= r.ibndly(13 downto 6);
idat2(dat2_ibf_ndlylsb):= r.ibndly( 5 downto 0);
idat2(dat2_ibf_nbusy) := r.ibnbusy;
idat1 := r.ibdata;
idat0(dat0_ibf_be1) := r.ibbe1;
idat0(dat0_ibf_be0) := r.ibbe0;
idat0(dat0_ibf_racc) := r.ibracc;
idat0(dat0_ibf_addr) := r.ibaddr;
idat0(dat0_ibf_cacc) := r.ibcacc;
n.ibtake_1 := ibtake;
N_REGS <= n;
 
BRAM_EN <= ibramen;
BRAM_WE <= ibramwe;
 
BRAM1_DI <= idat3 & idat2;
BRAM0_DI <= idat1 & idat0;
IB_SRES.dout <= iib_dout;
IB_SRES.ack <= iib_ack;
IB_SRES.busy <= iib_busy;
 
end process proc_next;
 
end syn;
/ibdr_minisys.vhd
0,0 → 1,215
-- $Id: ibdr_minisys.vhd 676 2015-05-09 16:31:54Z mueller $
--
-- Copyright 2008-2011 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_minisys - syn
-- Description: ibus(rem) devices for minimal system:SDR+KW+DL+RK
--
-- Dependencies: ibdr_sdreg
-- ibd_kw11l
-- ibdr_dl11
-- ibdr_rk11
-- ib_sres_or_4
-- ib_intmap
-- Test bench: -
-- Target Devices: generic
-- Tool versions: ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2010-10-17 333 12.1 M53d xc3s1000-4 128 469 16 265 s 7.8
-- 2010-10-17 314 12.1 M53d xc3s1000-4 122 472 16 269 s 7.6
--
-- Revision History:
-- Date Rev Version Comment
-- 2011-11-18 427 1.1.2 now numeric_std clean
-- 2010-10-23 335 1.1.1 rename RRI_LAM->RB_LAM;
-- 2010-06-11 303 1.1 use IB_MREQ.racc instead of RRI_REQ
-- 2009-07-12 233 1.0.7 reorder ports, add CE_USEC; add RESET and CE_USEC
-- to _dl11
-- 2009-05-31 221 1.0.6 add RESET to kw11l;
-- 2009-05-24 219 1.0.5 _rk11 uses now CE_MSEC
-- 2008-08-22 161 1.0.4 use iblib, ibdlib
-- 2008-05-09 144 1.0.3 use EI_ACK with _kw11l, _dl11
-- 2008-04-18 136 1.0.2 add RESET port, use for ibdr_sdreg
-- 2008-01-20 113 1.0.1 RRI_LAM now vector
-- 2008-01-20 112 1.0 Initial version
------------------------------------------------------------------------------
--
-- mini system setup
--
-- ibbase vec pri slot attn device name
--
-- 177546 100 6 4 - KW11-L
-- 177400 220 5 3 4 RK11
-- 177560 060 4 2 1 DL11-RX 1st
-- 064 4 1 ^ DL11-TX 1st
-- 177570 - - - - sdreg
--
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
use work.iblib.all;
use work.ibdlib.all;
 
-- ----------------------------------------------------------------------------
entity ibdr_minisys is -- ibus(rem) minimal sys:SDR+KW+DL+RK
port (
CLK : in slbit; -- clock
CE_USEC : in slbit; -- usec pulse
CE_MSEC : in slbit; -- msec pulse
RESET : in slbit; -- reset
BRESET : in slbit; -- ibus reset
RB_LAM : out slv16_1; -- remote attention vector
IB_MREQ : in ib_mreq_type; -- ibus request
IB_SRES : out ib_sres_type; -- ibus response
EI_ACKM : in slbit; -- interrupt acknowledge (from master)
EI_PRI : out slv3; -- interrupt priority (to cpu)
EI_VECT : out slv9_2; -- interrupt vector (to cpu)
DISPREG : out slv16 -- display register
);
end ibdr_minisys;
 
architecture syn of ibdr_minisys is
 
constant conf_intmap : intmap_array_type :=
(intmap_init, -- line 15
intmap_init, -- line 14
intmap_init, -- line 13
intmap_init, -- line 12
intmap_init, -- line 11
intmap_init, -- line 10
intmap_init, -- line 9
intmap_init, -- line 8
intmap_init, -- line 7
intmap_init, -- line 6
intmap_init, -- line 5
(8#100#,6), -- line 4 KW11-L
(8#220#,5), -- line 3 RK11
(8#060#,4), -- line 2 DL11-RX
(8#064#,4), -- line 1 DL11-TX
intmap_init -- line 0
);
 
signal RB_LAM_DL11 : slbit := '0';
signal RB_LAM_RK11 : slbit := '0';
 
signal IB_SRES_SDREG : ib_sres_type := ib_sres_init;
signal IB_SRES_KW11L : ib_sres_type := ib_sres_init;
signal IB_SRES_DL11 : ib_sres_type := ib_sres_init;
signal IB_SRES_RK11 : ib_sres_type := ib_sres_init;
 
signal EI_REQ : slv16_1 := (others=>'0');
signal EI_ACK : slv16_1 := (others=>'0');
 
signal EI_REQ_KW11L : slbit := '0';
signal EI_REQ_DL11RX : slbit := '0';
signal EI_REQ_DL11TX : slbit := '0';
signal EI_REQ_RK11 : slbit := '0';
signal EI_ACK_KW11L : slbit := '0';
signal EI_ACK_DL11RX : slbit := '0';
signal EI_ACK_DL11TX : slbit := '0';
signal EI_ACK_RK11 : slbit := '0';
 
begin
 
SDREG : ibdr_sdreg
port map (
CLK => CLK,
RESET => RESET,
IB_MREQ => IB_MREQ,
IB_SRES => IB_SRES_SDREG,
DISPREG => DISPREG
);
 
KW11L : ibd_kw11l
port map (
CLK => CLK,
CE_MSEC => CE_MSEC,
RESET => RESET,
BRESET => BRESET,
CPUSUSP => '0',
IB_MREQ => IB_MREQ,
IB_SRES => IB_SRES_KW11L,
EI_REQ => EI_REQ_KW11L,
EI_ACK => EI_ACK_KW11L
);
 
DL11 : ibdr_dl11
port map (
CLK => CLK,
CE_USEC => CE_USEC,
RESET => RESET,
BRESET => BRESET,
RB_LAM => RB_LAM_DL11,
IB_MREQ => IB_MREQ,
IB_SRES => IB_SRES_DL11,
EI_REQ_RX => EI_REQ_DL11RX,
EI_REQ_TX => EI_REQ_DL11TX,
EI_ACK_RX => EI_ACK_DL11RX,
EI_ACK_TX => EI_ACK_DL11TX
);
RK11 : ibdr_rk11
port map (
CLK => CLK,
CE_MSEC => CE_MSEC,
BRESET => BRESET,
RB_LAM => RB_LAM_RK11,
IB_MREQ => IB_MREQ,
IB_SRES => IB_SRES_RK11,
EI_REQ => EI_REQ_RK11,
EI_ACK => EI_ACK_RK11
);
 
SRES_OR : ib_sres_or_4
port map (
IB_SRES_1 => IB_SRES_SDREG,
IB_SRES_2 => IB_SRES_KW11L,
IB_SRES_3 => IB_SRES_DL11,
IB_SRES_4 => IB_SRES_RK11,
IB_SRES_OR => IB_SRES
);
 
INTMAP : ib_intmap
generic map (
INTMAP => conf_intmap)
port map (
EI_REQ => EI_REQ,
EI_ACKM => EI_ACKM,
EI_ACK => EI_ACK,
EI_PRI => EI_PRI,
EI_VECT => EI_VECT
);
EI_REQ(4) <= EI_REQ_KW11L;
EI_REQ(3) <= EI_REQ_RK11;
EI_REQ(2) <= EI_REQ_DL11RX;
EI_REQ(1) <= EI_REQ_DL11TX;
 
EI_ACK_KW11L <= EI_ACK(4);
EI_ACK_RK11 <= EI_ACK(3);
EI_ACK_DL11RX <= EI_ACK(2);
EI_ACK_DL11TX <= EI_ACK(1);
 
RB_LAM(1) <= RB_LAM_DL11;
RB_LAM(2) <= '0'; -- for 2nd DL11
RB_LAM(3) <= '0'; -- for DZ11
RB_LAM(4) <= RB_LAM_RK11;
RB_LAM(15 downto 5) <= (others=>'0');
end syn;
/ibdr_rhrp.vbom
0,0 → 1,9
# libs
../vlib/slvtypes.vhd
../vlib/memlib/memlib.vhd
iblib.vhd
# components
[sim]../vlib/memlib/ram_1swar_gen.vbom
[xst,vsyn]../vlib/memlib/ram_1swar_gen_unisim.vbom
# design
ibdr_rhrp.vhd
/ib_sres_or_mon.vhd
0,0 → 1,99
-- $Id: ib_sres_or_mon.vhd 649 2015-02-21 21:10:16Z mueller $
--
-- Copyright 2010- 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: ib_sres_or_mon - sim
-- Description: ibus result or monitor
--
-- Dependencies: -
-- Test bench: -
-- Tool versions: ghdl 0.29-0.31
--
-- Revision History:
-- Date Rev Version Comment
-- 2010-10-28 336 1.0.1 log errors only if now>0ns (drop startup glitches)
-- 2010-10-23 335 1.0 Initial version (derived from rritb_sres_or_mon)
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_textio.all;
use std.textio.all;
 
use work.slvtypes.all;
use work.iblib.all;
 
-- ----------------------------------------------------------------------------
 
entity ib_sres_or_mon is -- ibus result or monitor
port (
IB_SRES_1 : in ib_sres_type; -- ib_sres input 1
IB_SRES_2 : in ib_sres_type; -- ib_sres input 2
IB_SRES_3 : in ib_sres_type := ib_sres_init; -- ib_sres input 3
IB_SRES_4 : in ib_sres_type := ib_sres_init -- ib_sres input 4
);
end ib_sres_or_mon;
 
architecture sim of ib_sres_or_mon is
begin
 
proc_comb : process (IB_SRES_1, IB_SRES_2, IB_SRES_3, IB_SRES_4)
constant dzero : slv16 := (others=>'0');
variable oline : line;
variable nack : integer := 0;
variable nbusy : integer := 0;
variable ndout : integer := 0;
begin
 
nack := 0;
nbusy := 0;
ndout := 0;
if IB_SRES_1.ack /= '0' then nack := nack + 1; end if;
if IB_SRES_2.ack /= '0' then nack := nack + 1; end if;
if IB_SRES_3.ack /= '0' then nack := nack + 1; end if;
if IB_SRES_4.ack /= '0' then nack := nack + 1; end if;
 
if IB_SRES_1.busy /= '0' then nbusy := nbusy + 1; end if;
if IB_SRES_2.busy /= '0' then nbusy := nbusy + 1; end if;
if IB_SRES_3.busy /= '0' then nbusy := nbusy + 1; end if;
if IB_SRES_4.busy /= '0' then nbusy := nbusy + 1; end if;
 
if IB_SRES_1.dout /= dzero then ndout := ndout + 1; end if;
if IB_SRES_2.dout /= dzero then ndout := ndout + 1; end if;
if IB_SRES_3.dout /= dzero then ndout := ndout + 1; end if;
if IB_SRES_4.dout /= dzero then ndout := ndout + 1; end if;
 
if now > 0 ns and (nack>1 or nbusy>1 or ndout>1) then
write(oline, now, right, 12);
if nack > 1 then
write(oline, string'(" #ack="));
write(oline, nack);
end if;
if nbusy > 1 then
write(oline, string'(" #busy="));
write(oline, nbusy);
end if;
if ndout > 1 then
write(oline, string'(" #dout="));
write(oline, ndout);
end if;
write(oline, string'(" FAIL in "));
write(oline, ib_sres_or_mon'path_name);
writeline(output, oline);
end if;
end process proc_comb;
end sim;
/ibdr_rk11.vbom
0,0 → 1,9
# libs
../vlib/slvtypes.vhd
../vlib/memlib/memlib.vhd
iblib.vhd
# components
[sim]../vlib/memlib/ram_1swar_gen.vbom
[xst,vsyn]../vlib/memlib/ram_1swar_gen_unisim.vbom
# design
ibdr_rk11.vhd
/ibdr_dl11.vhd
0,0 → 1,349
-- $Id: ibdr_dl11.vhd 641 2015-02-01 22:12:15Z mueller $
--
-- Copyright 2008-2011 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_dl11 - syn
-- Description: ibus dev(rem): DL11-A/B
--
-- Dependencies: -
-- Test bench: -
-- Target Devices: generic
-- Tool versions: ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2010-10-17 333 12.1 M53d xc3s1000-4 39 126 0 72 s 7.6
-- 2009-07-12 233 10.1.03 K39 xc3s1000-4 38 119 0 69 s 6.3
-- 2009-07-11 232 10.1.03 K39 xc3s1000-4 23 61 0 40 s 5.5
--
-- Revision History:
-- Date Rev Version Comment
-- 2011-11-18 427 1.2.2 now numeric_std clean
-- 2010-10-23 335 1.2.1 rename RRI_LAM->RB_LAM;
-- 2010-10-17 333 1.2 use ibus V2 interface
-- 2010-06-11 303 1.1 use IB_MREQ.racc instead of RRI_REQ
-- 2009-07-12 233 1.0.5 add RESET, CE_USEC port; implement input rate limit
-- 2008-08-22 161 1.0.6 use iblib; add EI_ACK_* to proc_next sens. list
-- 2008-05-09 144 1.0.5 use intreq flop, use EI_ACK
-- 2008-03-22 128 1.0.4 rename xdone -> xval (no functional change)
-- 2008-01-27 115 1.0.3 BUGFIX: set ilam when rbuf read by cpu;
-- add xdone and rrdy bits to rri xbuf read
-- 2008-01-20 113 1.0.2 fix maint mode logic (proper double buffer now)
-- 2008-01-20 112 1.0.1 use BRESET
-- 2008-01-05 108 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
use work.iblib.all;
 
-- ----------------------------------------------------------------------------
entity ibdr_dl11 is -- ibus dev(rem): DL11-A/B
generic (
IB_ADDR : slv16 := slv(to_unsigned(8#177560#,16)));
port (
CLK : in slbit; -- clock
CE_USEC : in slbit; -- usec pulse
RESET : in slbit; -- system reset
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_RX : out slbit; -- interrupt request, receiver
EI_REQ_TX : out slbit; -- interrupt request, transmitter
EI_ACK_RX : in slbit; -- interrupt acknowledge, receiver
EI_ACK_TX : in slbit -- interrupt acknowledge, transmitter
);
end ibdr_dl11;
 
architecture syn of ibdr_dl11 is
 
constant ibaddr_rcsr : slv2 := "00"; -- rcsr address offset
constant ibaddr_rbuf : slv2 := "01"; -- rbuf address offset
constant ibaddr_xcsr : slv2 := "10"; -- xcsr address offset
constant ibaddr_xbuf : slv2 := "11"; -- xbuf address offset
subtype rcsr_ibf_rrlim is integer range 14 downto 12;
constant rcsr_ibf_rdone : integer := 7;
constant rcsr_ibf_rie : integer := 6;
constant xcsr_ibf_xrdy : integer := 7;
constant xcsr_ibf_xie : integer := 6;
constant xcsr_ibf_xmaint: integer := 2;
 
constant xbuf_ibf_xval : integer := 8;
constant xbuf_ibf_rrdy : integer := 9;
 
type regs_type is record -- state registers
ibsel : slbit; -- ibus select
rrlim : slv3; -- rcsr: receiver rate limit
rdone : slbit; -- rcsr: receiver done
rie : slbit; -- rcsr: receiver interrupt enable
rbuf : slv8; -- rbuf:
rval : slbit; -- rx rbuf valid
rintreq : slbit; -- rx interrupt request
rdlybsy : slbit; -- rx delay busy
rdlycnt : slv10; -- rx delay counter
xrdy : slbit; -- xcsr: transmitter ready
xie : slbit; -- xcsr: transmitter interrupt enable
xmaint : slbit; -- xcsr: maintenance mode
xbuf : slv8; -- xbuf:
xintreq : slbit; -- tx interrupt request
end record regs_type;
 
constant regs_init : regs_type := (
'0', -- ibsel
(others=>'0'), -- rrlim
'0','0', -- rdone, rie
(others=>'0'), -- rbuf
'0','0','0', -- rval,rintreq,rdlybsy
(others=>'0'), -- rdlycnt
'1', -- xrdy !! is set !!
'0','0', -- xie,xmaint
(others=>'0'), -- xbuf
'0' -- xintreq
);
 
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
if BRESET = '1' then
R_REGS <= regs_init;
if RESET = '0' then -- if RESET=0 we do just an ibus reset
R_REGS.rrlim <= N_REGS.rrlim; -- don't reset rx rate limit
R_REGS.rdlybsy <= N_REGS.rdlybsy; -- don't reset rx delay busy
R_REGS.rdlycnt <= N_REGS.rdlycnt; -- don't reset rx delay counter
end if;
else
R_REGS <= N_REGS;
end if;
end if;
end process proc_regs;
 
proc_next : process (CE_USEC, R_REGS, IB_MREQ, EI_ACK_RX, EI_ACK_TX)
variable r : regs_type := regs_init;
variable n : regs_type := regs_init;
variable idout : slv16 := (others=>'0');
variable ibreq : slbit := '0';
variable ibrd : slbit := '0';
variable ibw0 : slbit := '0';
variable ibw1 : slbit := '0';
variable ilam : slbit := '0';
variable rdlystart : slbit := '0';
variable rdlyinit : slv10 := (others=>'0');
begin
 
r := R_REGS;
n := R_REGS;
 
idout := (others=>'0');
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;
ilam := '0';
rdlystart := '0';
-- ibus address decoder
n.ibsel := '0';
if IB_MREQ.aval='1' and
IB_MREQ.addr(12 downto 3)=IB_ADDR(12 downto 3) then
n.ibsel := '1';
end if;
 
-- ibus transactions
if r.ibsel = '1' then
case IB_MREQ.addr(2 downto 1) is
 
when ibaddr_rcsr => -- RCSR -- receive control status ----
idout(rcsr_ibf_rdone) := r.rdone;
idout(rcsr_ibf_rie) := r.rie;
if IB_MREQ.racc = '0' then -- cpu ---------------------
if ibw0 = '1' then
n.rie := IB_MREQ.din(rcsr_ibf_rie);
if IB_MREQ.din(rcsr_ibf_rie) = '1' then
if r.rdone='1' and r.rie='0' then -- ie set while done=1
n.rintreq := '1'; -- request interrupt
end if;
else
n.rintreq := '0';
end if;
end if;
 
else -- rri ---------------------
idout(rcsr_ibf_rrlim) := r.rrlim;
if ibw1 = '1' then
n.rrlim := IB_MREQ.din(rcsr_ibf_rrlim);
end if;
end if;
 
when ibaddr_rbuf => -- RBUF -- receive data buffer -------
 
idout(r.rbuf'range) := r.rbuf;
 
if IB_MREQ.racc = '0' then -- cpu ---------------------
if ibrd = '1' then
n.rdone := '0'; -- clear DONE
n.rval := '0'; -- clear rbuf valid
n.rintreq := '0'; -- clear pending interrupts
rdlystart := '1'; -- start rx delay counter
if r.xmaint = '0' then -- if not in loop-back
ilam := '1'; -- request rb attention
end if;
end if;
 
else -- rri ---------------------
if ibw0 = '1' then
n.rbuf := IB_MREQ.din(n.rbuf'range);
n.rval := '1'; -- set rbuf valid
if r.rdlybsy = '0' then -- if rdly timer not running
n.rdone := '1'; -- set DONE
if r.rie = '1' then -- if rx interrupt enabled
n.rintreq := '1'; -- request interrupt
end if;
end if;
end if;
end if;
 
when ibaddr_xcsr => -- XCSR -- transmit control status ---
 
idout(xcsr_ibf_xrdy) := r.xrdy;
idout(xcsr_ibf_xie) := r.xie;
idout(xcsr_ibf_xmaint):= r.xmaint;
 
if IB_MREQ.racc = '0' then -- cpu ---------------------
if ibw0 = '1' then
n.xie := IB_MREQ.din(xcsr_ibf_xie);
if IB_MREQ.din(xcsr_ibf_xie) = '1' then
if r.xrdy='1' and r.xie='0' then -- ie set while ready=1
n.xintreq := '1'; -- request interrupt
end if;
else
n.xintreq := '0';
end if;
n.xmaint := IB_MREQ.din(xcsr_ibf_xmaint);
end if;
end if;
when ibaddr_xbuf => -- XBUF -- transmit data buffer ------
 
if IB_MREQ.racc = '0' then -- cpu ---------------------
if ibw0 = '1' then
n.xbuf := IB_MREQ.din(n.xbuf'range);
n.xrdy := '0';
n.xintreq := '0';
if r.xmaint = '0' then
ilam := '1';
end if;
end if;
 
else -- rri ---------------------
idout(r.xbuf'range) := r.xbuf;
if r.xmaint = '0' then -- if not in maintenace mode
idout(xbuf_ibf_xval) := not r.xrdy;
idout(xbuf_ibf_rrdy) := not r.rval;
end if;
if ibrd = '1' then
n.xrdy := '1';
if r.xie = '1' then
n.xintreq := '1';
end if;
end if;
end if;
 
when others => null;
end case;
 
else -- if unselected handle loop-back
if r.xmaint = '1' and -- if in maintenace mode
r.xrdy='0' and -- and transmit pending
r.rdone='0' and -- and receive buffer empty
r.rdlybsy='0' then -- and rdly timer not running
n.rbuf := r.xbuf; -- copy transmit to receive buffer
n.xrdy := '1'; -- mark transmit done
n.rdone := '1'; -- make receive done
if r.rie = '1' then -- if rx interrupt enabled
n.rintreq := '1'; -- request it
end if;
if r.xie = '1' then -- if tx interrupt enabled
n.xintreq := '1'; -- request it
end if;
end if;
end if;
 
-- other state changes
 
rdlyinit := (others=>'0');
case r.rrlim is
when "000" => rdlyinit := "0000000000"; -- rlim=0 -> disabled
when "001" => rdlyinit := "0000000011"; -- rlim=1 -> delay by 3+ usec
when "010" => rdlyinit := "0000001111"; -- rlim=2 -> delay by 15+ usec
when "011" => rdlyinit := "0000111111"; -- rlim=3 -> delay by 63+ usec
when "100" => rdlyinit := "0001111111"; -- rlim=4 -> delay by 127+ usec
when "101" => rdlyinit := "0011111111"; -- rlim=5 -> delay by 255+ usec
when "110" => rdlyinit := "0111111111"; -- rlim=6 -> delay by 511+ usec
when "111" => rdlyinit := "1111111111"; -- rlim=7 -> delay by 1023+ usec
when others => null;
end case;
if rdlystart = '1' then -- if rdly timer start requested
n.rdlycnt := rdlyinit; -- init counter
if r.rrlim /= "000" then -- rate limiter enabled ?
n.rdlybsy := '1'; -- set busy
end if;
elsif CE_USEC = '1' then -- if end-of-usec
n.rdlycnt := slv(unsigned(r.rdlycnt) - 1); -- decrement
if r.rdlybsy='1' and -- if delay busy
unsigned(r.rdlycnt) = 0 then -- and counter at zero
n.rdlybsy := '0'; -- clear busy
if n.rval = '1' then -- if rbuf is valid or is set
-- valid this cycle (use n.!!)
n.rdone := '1'; -- set DONE
if r.rie = '1' then -- if rx interrupt enabled
n.rintreq := '1'; -- request interrupt
end if;
end if;
end if;
end if;
if EI_ACK_RX = '1' then
n.rintreq := '0';
end if;
if EI_ACK_TX = '1' then
n.xintreq := '0';
end if;
 
N_REGS <= n;
 
IB_SRES.dout <= idout;
IB_SRES.ack <= r.ibsel and ibreq;
IB_SRES.busy <= '0';
 
RB_LAM <= ilam;
EI_REQ_RX <= r.rintreq;
EI_REQ_TX <= r.xintreq;
end process proc_next;
 
end syn;
/ibdr_pc11.vhd
0,0 → 1,323
-- $Id: ibdr_pc11.vhd 641 2015-02-01 22:12:15Z mueller $
--
-- Copyright 2009-2013 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_pc11 - syn
-- Description: ibus dev(rem): PC11
--
-- Dependencies: -
-- Test bench: xxdp: zpcae0
-- Target Devices: generic
-- Tool versions: ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2010-10-17 333 12.1 M53d xc3s1000-4 26 97 0 57 s 6.0
-- 2009-06-28 230 10.1.03 K39 xc3s1000-4 25 92 0 54 s 4.9
--
-- Revision History:
-- Date Rev Version Comment
-- 2013-05-04 515 1.3 BUGFIX: r.rbuf was immediately cleared ! Was broken
-- since ibus V2 update, never tested afterwards...
-- 2011-11-18 427 1.2.2 now numeric_std clean
-- 2010-10-23 335 1.2.1 rename RRI_LAM->RB_LAM;
-- 2010-10-17 333 1.2 use ibus V2 interface
-- 2010-06-11 303 1.1 use IB_MREQ.racc instead of RRI_REQ
-- 2009-06-28 230 1.0 prdy now inits to '1'; setting err bit in csr now
-- causes interrupt, if enabled; validated with zpcae0
-- 2009-06-01 221 0.9 Initial version (untested)
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
use work.iblib.all;
 
-- ----------------------------------------------------------------------------
entity ibdr_pc11 is -- ibus dev(rem): PC11
-- fixed address: 177550
port (
CLK : in slbit; -- clock
RESET : in slbit; -- system reset
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_PTR : out slbit; -- interrupt request, reader
EI_REQ_PTP : out slbit; -- interrupt request, punch
EI_ACK_PTR : in slbit; -- interrupt acknowledge, reader
EI_ACK_PTP : in slbit -- interrupt acknowledge, punch
);
end ibdr_pc11;
 
architecture syn of ibdr_pc11 is
 
constant ibaddr_pc11 : slv16 := slv(to_unsigned(8#177550#,16));
 
constant ibaddr_rcsr : slv2 := "00"; -- rcsr address offset
constant ibaddr_rbuf : slv2 := "01"; -- rbuf address offset
constant ibaddr_pcsr : slv2 := "10"; -- pcsr address offset
constant ibaddr_pbuf : slv2 := "11"; -- pbuf address offset
constant rcsr_ibf_rerr : integer := 15;
constant rcsr_ibf_rbusy : integer := 11;
constant rcsr_ibf_rdone : integer := 7;
constant rcsr_ibf_rie : integer := 6;
constant rcsr_ibf_renb : integer := 0;
constant pcsr_ibf_perr : integer := 15;
constant pcsr_ibf_prdy : integer := 7;
constant pcsr_ibf_pie : integer := 6;
 
constant pbuf_ibf_pval : integer := 8;
constant pbuf_ibf_rbusy : integer := 9;
 
type regs_type is record -- state registers
ibsel : slbit; -- ibus select
rerr : slbit; -- rcsr: reader error
rbusy : slbit; -- rcsr: reader busy
rdone : slbit; -- rcsr: reader done
rie : slbit; -- rcsr: reader interrupt enable
rbuf : slv8; -- rbuf:
rintreq : slbit; -- ptr interrupt request
perr : slbit; -- pcsr: punch error
prdy : slbit; -- pcsr: punch ready
pie : slbit; -- pcsr: punch interrupt enable
pbuf : slv8; -- pbuf:
pintreq : slbit; -- ptp interrupt request
end record regs_type;
 
constant regs_init : regs_type := (
'0', -- ibsel
'1', -- rerr (init=1!)
'0','0','0', -- rbusy,rdone,rie
(others=>'0'), -- rbuf
'0', -- rintreq
'1', -- perr (init=1!)
'1', -- prdy (init=1!)
'0', -- pie
(others=>'0'), -- pbuf
'0' -- pintreq
);
 
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
if BRESET = '1' then -- BRESET is 1 for system and ibus reset
R_REGS <= regs_init; --
if RESET = '0' then -- if RESET=0 we do just an ibus reset
R_REGS.rerr <= N_REGS.rerr; -- don't reset RERR flag
R_REGS.perr <= N_REGS.perr; -- don't reset PERR flag
end if;
else
R_REGS <= N_REGS;
end if;
end if;
end process proc_regs;
 
proc_next : process (R_REGS, IB_MREQ, EI_ACK_PTR, EI_ACK_PTP)
variable r : regs_type := regs_init;
variable n : regs_type := regs_init;
variable idout : slv16 := (others=>'0');
variable ibreq : slbit := '0';
variable ibrd : slbit := '0';
variable ibw0 : slbit := '0';
variable ibw1 : slbit := '0';
variable ilam : slbit := '0';
begin
 
r := R_REGS;
n := R_REGS;
 
idout := (others=>'0');
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;
ilam := '0';
-- ibus address decoder
n.ibsel := '0';
if IB_MREQ.aval='1' and
IB_MREQ.addr(12 downto 3)=ibaddr_pc11(12 downto 3) then
n.ibsel := '1';
end if;
 
-- ibus transactions
if r.ibsel = '1' then
case IB_MREQ.addr(2 downto 1) is
 
when ibaddr_rcsr => -- RCSR -- reader control status -----
 
idout(rcsr_ibf_rerr) := r.rerr;
idout(rcsr_ibf_rbusy) := r.rbusy;
idout(rcsr_ibf_rdone) := r.rdone;
idout(rcsr_ibf_rie) := r.rie;
 
if IB_MREQ.racc = '0' then -- cpu ---------------------
if ibw0 = '1' then
n.rie := IB_MREQ.din(rcsr_ibf_rie);
if IB_MREQ.din(rcsr_ibf_rie) = '1' then-- set IE to 1
if r.rie = '0' and -- IE 0->1 transition
IB_MREQ.din(rcsr_ibf_renb)='0' and -- when RENB not set
(r.rerr='1' or r.rdone='1') then -- but err or done set
n.rintreq := '1'; -- request interrupt
end if;
else -- set IE to 0
n.rintreq := '0'; -- cancel interrupts
end if;
if IB_MREQ.din(rcsr_ibf_renb) = '1' then -- set RENB
if r.rerr = '0' then -- if not in error state
n.rbusy := '1'; -- set busy
n.rdone := '0'; -- clear done
n.rbuf := (others=>'0'); -- clear buffer
n.rintreq := '0'; -- cancel interrupt
ilam := '1'; -- rri lam
else -- if in error state
if r.rie = '1' then -- if interrupts on
n.rintreq := '1'; -- request interrupt
end if;
end if;
end if;
end if;
 
else -- rri ---------------------
if ibw1 = '1' then
n.rerr := IB_MREQ.din(rcsr_ibf_rerr); -- set ERR bit
if IB_MREQ.din(rcsr_ibf_rerr)='1' -- if 0->1 transition
and r.rerr='0' then
n.rbusy := '0'; -- clear busy
n.rdone := '0'; -- clear done
if r.rie = '1' then -- if interrupts on
n.rintreq := '1'; -- request interrupt
end if;
end if;
end if;
end if;
 
when ibaddr_rbuf => -- RBUF -- reader data buffer --------
 
idout(r.rbuf'range) := r.rbuf;
 
if IB_MREQ.racc = '0' then -- cpu ---------------------
if ibreq = '1' then -- !! PC11 is unusual !!
n.rdone := '0'; -- *any* read or write will clear done
n.rbuf := (others=>'0'); -- and the reader buffer
n.rintreq := '0'; -- also interrupt is canceled
end if;
 
else -- rri ---------------------
if ibw0 = '1' then
n.rbuf := IB_MREQ.din(n.rbuf'range);
n.rbusy := '0';
n.rdone := '1';
if r.rie = '1' then
n.rintreq := '1';
end if;
end if;
end if;
 
when ibaddr_pcsr => -- PCSR -- punch control status ------
 
idout(pcsr_ibf_perr) := r.perr;
idout(pcsr_ibf_prdy) := r.prdy;
idout(pcsr_ibf_pie) := r.pie;
 
if IB_MREQ.racc = '0' then -- cpu ---------------------
if ibw0 = '1' then
n.pie := IB_MREQ.din(pcsr_ibf_pie);
if IB_MREQ.din(pcsr_ibf_pie) = '1' then-- set IE to 1
if r.pie='0' and -- IE 0->1 transition
(r.perr='1' or r.prdy='1') then -- but err or done set
n.pintreq := '1'; -- request interrupt
end if;
else -- set IE to 0
n.pintreq := '0'; -- cancel interrupts
end if;
end if;
 
else -- rri ---------------------
if ibw1 = '1' then
n.perr := IB_MREQ.din(pcsr_ibf_perr); -- set ERR bit
if IB_MREQ.din(pcsr_ibf_perr)='1' -- if 0->1 transition
and r.perr='0' then
n.prdy := '1'; -- set ready
if r.pie = '1' then -- if interrupts on
n.pintreq := '1'; -- request interrupt
end if;
end if;
end if;
end if;
 
when ibaddr_pbuf => -- PBUF -- punch data buffer ---------
 
if IB_MREQ.racc = '0' then -- cpu ---------------------
if ibw0 = '1' then
if r.perr = '0' then -- if not in error state
n.pbuf := IB_MREQ.din(n.pbuf'range);
n.prdy := '0'; -- clear ready
n.pintreq := '0'; -- cancel interrupts
ilam := '1'; -- rri lam
else -- if in error state
if r.pie = '1' then -- if interrupts on
n.pintreq := '1'; -- request interrupt
end if;
end if;
end if;
 
else -- rri ---------------------
idout(r.pbuf'range) := r.pbuf;
idout(pbuf_ibf_pval) := not r.prdy;
idout(pbuf_ibf_rbusy) := r.rbusy;
if ibrd = '1' then
n.prdy := '1';
if r.pie = '1' then
n.pintreq := '1';
end if;
end if;
end if;
 
when others => null;
end case;
end if;
 
-- other state changes
if EI_ACK_PTR = '1' then
n.rintreq := '0';
end if;
if EI_ACK_PTP = '1' then
n.pintreq := '0';
end if;
 
N_REGS <= n;
 
IB_SRES.dout <= idout;
IB_SRES.ack <= r.ibsel and ibreq;
IB_SRES.busy <= '0';
 
RB_LAM <= ilam;
EI_REQ_PTR <= r.rintreq;
EI_REQ_PTP <= r.pintreq;
end process proc_next;
 
end syn;
/ib_sres_or_2.vhd
0,0 → 1,73
-- $Id: ib_sres_or_2.vhd 641 2015-02-01 22:12:15Z mueller $
--
-- Copyright 2007-2010 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: ib_sres_or_2 - syn
-- Description: ibus: result or, 2 input
--
-- Dependencies: -
-- Test bench: tb/tb_pdp11_core (implicit)
-- Target Devices: generic
-- Tool versions: ise 8.1-14.7; viv 2014.4; ghdl 0.18-0.31
--
-- Revision History:
-- Date Rev Version Comment
-- 2010-10-23 335 1.1 add ib_sres_or_mon
-- 2008-08-22 161 1.0.2 renamed pdp11_ibres_ -> ib_sres_; use iblib
-- 2008-01-05 110 1.0.1 rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy)
-- 2007-12-29 107 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
use work.slvtypes.all;
use work.iblib.all;
 
-- ----------------------------------------------------------------------------
 
entity ib_sres_or_2 is -- ibus result or, 2 input
port (
IB_SRES_1 : in ib_sres_type; -- ib_sres input 1
IB_SRES_2 : in ib_sres_type := ib_sres_init; -- ib_sres input 2
IB_SRES_OR : out ib_sres_type -- ib_sres or'ed output
);
end ib_sres_or_2;
 
architecture syn of ib_sres_or_2 is
begin
 
proc_comb : process (IB_SRES_1, IB_SRES_2)
begin
 
IB_SRES_OR.ack <= IB_SRES_1.ack or
IB_SRES_2.ack;
IB_SRES_OR.busy <= IB_SRES_1.busy or
IB_SRES_2.busy;
IB_SRES_OR.dout <= IB_SRES_1.dout or
IB_SRES_2.dout;
end process proc_comb;
-- synthesis translate_off
ORMON : ib_sres_or_mon
port map (
IB_SRES_1 => IB_SRES_1,
IB_SRES_2 => IB_SRES_2,
IB_SRES_3 => ib_sres_init,
IB_SRES_4 => ib_sres_init
);
-- synthesis translate_on
 
end syn;
/ib_sres_or_3.vhd
0,0 → 1,77
-- $Id: ib_sres_or_3.vhd 641 2015-02-01 22:12:15Z mueller $
--
-- Copyright 2007-2010 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: ib_sres_or_3 - syn
-- Description: ibus: result or, 3 input
--
-- Dependencies: -
-- Test bench: tb/tb_pdp11_core (implicit)
-- Target Devices: generic
-- Tool versions: ise 8.1-14.7; viv 2014.4; ghdl 0.18-0.31
--
-- Revision History:
-- Date Rev Version Comment
-- 2010-10-23 335 1.1 add ib_sres_or_mon
-- 2008-08-22 161 1.0.2 renamed pdp11_ibres_ -> ib_sres_; use iblib
-- 2008-01-05 110 1.0.1 rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy)
-- 2007-12-29 107 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
use work.slvtypes.all;
use work.iblib.all;
 
-- ----------------------------------------------------------------------------
 
entity ib_sres_or_3 is -- ibus result or, 3 input
port (
IB_SRES_1 : in ib_sres_type; -- ib_sres input 1
IB_SRES_2 : in ib_sres_type := ib_sres_init; -- ib_sres input 2
IB_SRES_3 : in ib_sres_type := ib_sres_init; -- ib_sres input 3
IB_SRES_OR : out ib_sres_type -- ib_sres or'ed output
);
end ib_sres_or_3;
 
architecture syn of ib_sres_or_3 is
begin
 
proc_comb : process (IB_SRES_1, IB_SRES_2, IB_SRES_3)
begin
 
IB_SRES_OR.ack <= IB_SRES_1.ack or
IB_SRES_2.ack or
IB_SRES_3.ack;
IB_SRES_OR.busy <= IB_SRES_1.busy or
IB_SRES_2.busy or
IB_SRES_3.busy;
IB_SRES_OR.dout <= IB_SRES_1.dout or
IB_SRES_2.dout or
IB_SRES_3.dout;
end process proc_comb;
 
-- synthesis translate_off
ORMON : ib_sres_or_mon
port map (
IB_SRES_1 => IB_SRES_1,
IB_SRES_2 => IB_SRES_2,
IB_SRES_3 => IB_SRES_3,
IB_SRES_4 => ib_sres_init
);
-- synthesis translate_on
end syn;
/ib_sres_or_4.vhd
0,0 → 1,81
-- $Id: ib_sres_or_4.vhd 641 2015-02-01 22:12:15Z mueller $
--
-- Copyright 2007-2010 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: ib_sres_or_4 - syn
-- Description: ibus: result or, 4 input
--
-- Dependencies: -
-- Test bench: tb/tb_pdp11_core (implicit)
-- Target Devices: generic
-- Tool versions: ise 8.1-14.7; viv 2014.4; ghdl 0.18-0.31
--
-- Revision History:
-- Date Rev Version Comment
-- 2010-10-23 335 1.1 add ib_sres_or_mon
-- 2008-08-22 161 1.0.2 renamed pdp11_ibres_ -> ib_sres_; use iblib
-- 2008-01-05 110 1.0.1 rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy)
-- 2007-12-29 107 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
use work.slvtypes.all;
use work.iblib.all;
 
-- ----------------------------------------------------------------------------
 
entity ib_sres_or_4 is -- ibus result or, 4 input
port (
IB_SRES_1 : in ib_sres_type; -- ib_sres input 1
IB_SRES_2 : in ib_sres_type := ib_sres_init; -- ib_sres input 2
IB_SRES_3 : in ib_sres_type := ib_sres_init; -- ib_sres input 3
IB_SRES_4 : in ib_sres_type := ib_sres_init; -- ib_sres input 4
IB_SRES_OR : out ib_sres_type -- ib_sres or'ed output
);
end ib_sres_or_4;
 
architecture syn of ib_sres_or_4 is
begin
 
proc_comb : process (IB_SRES_1, IB_SRES_2, IB_SRES_3, IB_SRES_4)
begin
 
IB_SRES_OR.ack <= IB_SRES_1.ack or
IB_SRES_2.ack or
IB_SRES_3.ack or
IB_SRES_4.ack;
IB_SRES_OR.busy <= IB_SRES_1.busy or
IB_SRES_2.busy or
IB_SRES_3.busy or
IB_SRES_4.busy;
IB_SRES_OR.dout <= IB_SRES_1.dout or
IB_SRES_2.dout or
IB_SRES_3.dout or
IB_SRES_4.dout;
end process proc_comb;
 
-- synthesis translate_off
ORMON : ib_sres_or_mon
port map (
IB_SRES_1 => IB_SRES_1,
IB_SRES_2 => IB_SRES_2,
IB_SRES_3 => IB_SRES_3,
IB_SRES_4 => IB_SRES_4
);
-- synthesis translate_on
end syn;
/ibdr_lp11.vhd
0,0 → 1,217
-- $Id: ibdr_lp11.vhd 641 2015-02-01 22:12:15Z mueller $
--
-- Copyright 2009-2013 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_lp11 - syn
-- Description: ibus dev(rem): LP11
--
-- Dependencies: -
-- Test bench: -
-- Target Devices: generic
-- Tool versions: ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2010-10-17 333 12.1 M53d xc3s1000-4 12 35 0 24 s 5.6
-- 2009-07-11 232 10.1.03 K39 xc3s1000-4 11 30 0 19 s 5.8
--
-- Revision History:
-- Date Rev Version Comment
-- 2013-05-04 515 1.3 BUGFIX: r.err was cleared in racc read !
-- 2011-11-18 427 1.2.2 now numeric_std clean
-- 2010-10-23 335 1.2.1 rename RRI_LAM->RB_LAM;
-- 2010-10-17 333 1.2 use ibus V2 interface
-- 2010-06-11 303 1.1 use IB_MREQ.racc instead of RRI_REQ
-- 2009-06-21 228 1.0.1 generate interrupt locally when err=1
-- 2009-05-30 220 1.0 Initial version
------------------------------------------------------------------------------
--
-- Notes:
-- - the ERR bit is just a status flag
-- - no hardware interlock (DONE forced 0 when ERR=1), like in simh
-- - also no interrupt when ERR goes 1, like in simh
 
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
use work.iblib.all;
 
-- ----------------------------------------------------------------------------
entity ibdr_lp11 is -- ibus dev(rem): LP11
-- fixed address: 177514
port (
CLK : in slbit; -- clock
RESET : in slbit; -- system reset
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_lp11;
 
architecture syn of ibdr_lp11 is
 
constant ibaddr_lp11 : slv16 := slv(to_unsigned(8#177514#,16));
 
constant ibaddr_csr : slv1 := "0"; -- csr address offset
constant ibaddr_buf : slv1 := "1"; -- buf address offset
constant csr_ibf_err : integer := 15;
constant csr_ibf_done : integer := 7;
constant csr_ibf_ie : integer := 6;
constant buf_ibf_val : integer := 8;
 
type regs_type is record -- state registers
ibsel : slbit; -- ibus select
err : slbit; -- csr: error flag
done : slbit; -- csr: done flag
ie : slbit; -- csr: interrupt enable
buf : slv7; -- buf:
intreq : slbit; -- interrupt request
end record regs_type;
 
constant regs_init : regs_type := (
'0', -- ibsel
'1', -- err !! is set !!
'1', -- done !! is set !!
'0', -- ie
(others=>'0'), -- buf
'0' -- intreq
);
 
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
if BRESET = '1' then -- BRESET is 1 for system and ibus reset
R_REGS <= regs_init;
if RESET = '0' then -- if RESET=0 we do just an ibus reset
R_REGS.err <= N_REGS.err; -- don't reset ERR flag
end if;
else
R_REGS <= N_REGS;
end if;
end if;
end process proc_regs;
 
proc_next : process (R_REGS, IB_MREQ, EI_ACK)
variable r : regs_type := regs_init;
variable n : regs_type := regs_init;
variable idout : slv16 := (others=>'0');
variable ibreq : slbit := '0';
variable ibrd : slbit := '0';
variable ibw0 : slbit := '0';
variable ibw1 : slbit := '0';
variable ilam : slbit := '0';
begin
 
r := R_REGS;
n := R_REGS;
 
idout := (others=>'0');
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;
ilam := '0';
-- ibus address decoder
n.ibsel := '0';
if IB_MREQ.aval='1' and
IB_MREQ.addr(12 downto 2)=ibaddr_lp11(12 downto 2) then
n.ibsel := '1';
end if;
 
-- ibus transactions
if r.ibsel = '1' then
case IB_MREQ.addr(1 downto 1) is
 
when ibaddr_csr => -- CSR -- control status -------------
idout(csr_ibf_err) := r.err;
idout(csr_ibf_done) := r.done;
idout(csr_ibf_ie) := r.ie;
if IB_MREQ.racc = '0' then -- cpu
if ibw0 = '1' then
n.ie := IB_MREQ.din(csr_ibf_ie);
if IB_MREQ.din(csr_ibf_ie) = '1' then
if r.done='1' and r.ie='0' then -- ie set while done=1
n.intreq := '1'; -- request interrupt
end if;
else
n.intreq := '0';
end if;
end if;
else -- rri
if ibw1 = '1' then
n.err := IB_MREQ.din(csr_ibf_err);
end if;
end if;
 
when ibaddr_buf => -- BUF -- data buffer ----------------
if IB_MREQ.racc = '0' then -- cpu
if ibw0 = '1' then
n.buf := IB_MREQ.din(n.buf'range);
if r.err = '0' then -- if online (handle via rbus)
ilam := '1'; -- request attention
n.done := '0'; -- clear done
n.intreq := '0'; -- clear interrupt
else -- if offline (discard locally)
n.done := '1'; -- set done
if r.ie = '1' then -- if interrupts enabled
n.intreq := '1'; -- request interrupt
end if;
end if;
end if;
else -- rri
idout(r.buf'range) := r.buf;
idout(buf_ibf_val) := not r.done;
if ibrd = '1' then
n.done := '1';
if r.ie = '1' then
n.intreq := '1';
end if;
end if;
end if;
 
when others => null;
end case;
 
end if;
 
-- other state changes
if EI_ACK = '1' then
n.intreq := '0';
end if;
 
N_REGS <= n;
 
IB_SRES.dout <= idout;
IB_SRES.ack <= r.ibsel and ibreq;
IB_SRES.busy <= '0';
 
RB_LAM <= ilam;
EI_REQ <= r.intreq;
end process proc_next;
 
end syn;
/ibdr_rl11.vhd
0,0 → 1,660
-- $Id: ibdr_rl11.vhd 655 2015-03-04 20:35:21Z mueller $
--
-- Copyright 2014-2015 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_rl11 - syn
-- Description: ibus dev(rem): RL11
--
-- Dependencies: ram_1swar_gen
-- Test bench: -
-- Target Devices: generic
-- Tool versions: ise 14.7; viv 2014.4; ghdl 0.31
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2015-02-28 653 14.7 131013 xc6slx16-2 80 197 12 80 s 7.9
-- 2014-06-15 562 14.7 131013 xc6slx16-2 81 199 13 78 s 8.0
--
-- Revision History:
-- Date Rev Version Comment
-- 2015-03-04 655 1.0.1 seek: ignore da(6:5), don't check for 0 anymore
-- 2015-02-28 653 1.0 Initial verison
-- 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.memlib.all;
use work.iblib.all;
 
-- ----------------------------------------------------------------------------
entity ibdr_rl11 is -- ibus dev(rem): RL11
-- fixed address: 174400
port (
CLK : in slbit; -- clock
CE_MSEC : in slbit; -- msec pulse
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_rl11;
 
architecture syn of ibdr_rl11 is
 
constant ibaddr_rl11 : slv16 := slv(to_unsigned(8#174400#,16));
 
constant ibaddr_rlcs : slv2 := "00"; -- rlcs address offset
constant ibaddr_rlba : slv2 := "01"; -- rlba address offset
constant ibaddr_rlda : slv2 := "10"; -- rlda address offset
constant ibaddr_rlmp : slv2 := "11"; -- rlmp address offset
 
-- usage of 16x16 memory bank
-- 0 0000 unused (but mirrors rlcs)
-- 1 0001 rlba
-- 2 0010 unused (but mirrors rlda)
-- 3 0011 rlmp (1st value)
-- 4 0100 rlmp (3rd value after gs; the crc)
-- 5 0101 unused
-- 6 0110 unused
-- 7 0111 unused (target for bad mprem states)
-- 11: 8 10-- sta(ds) (drive status)
-- 15:12 11-- pos(ds) (drive disk address)
constant imem_cs : slv4 := "0000"; -- unused
constant imem_ba : slv4 := "0001";
constant imem_da : slv4 := "0010"; -- unused
constant imem_mp : slv4 := "0011";
constant imem_crc : slv4 := "0100";
constant imem_bad : slv4 := "0111"; -- target for bad mprem states
constant imem_sta : slv4 := "1000";
constant imem_pos : slv4 := "1100";
 
subtype imf_typ is integer range 3 downto 2;
subtype imf_ds is integer range 1 downto 0;
 
constant rlcs_ibf_err : integer := 15;
constant rlcs_ibf_de : integer := 14;
subtype rlcs_ibf_e is integer range 13 downto 10;
subtype rlcs_ibf_ds is integer range 9 downto 8;
constant rlcs_ibf_crdy : integer := 7;
constant rlcs_ibf_ie : integer := 6;
subtype rlcs_ibf_bae is integer range 5 downto 4;
subtype rlcs_ibf_func is integer range 3 downto 1;
constant rlcs_ibf_drdy : integer := 0;
 
constant func_noop : slv3 := "000"; -- func: noop
constant func_wchk : slv3 := "001"; -- func: write check
constant func_gs : slv3 := "010"; -- func: get status
constant func_seek : slv3 := "011"; -- func: seek
constant func_rhdr : slv3 := "100"; -- func: read header
constant func_write : slv3 := "101"; -- func: write data
constant func_read : slv3 := "110"; -- func: read data
constant func_rnhc : slv3 := "111"; -- func: read data without header check
 
constant e_ok : slv4 := "0000"; -- e code: ok
constant e_incomp : slv4 := "0001"; -- e code: operation incomplete
 
-- defs for rem access of rlcs; func codes
constant rfunc_wcs : slv3 := "001"; -- rem func: write cs (err,de,e,drdy)
constant rfunc_wmp : slv3 := "010"; -- rem func: write mprem or mploc
 
-- rlcs usage or rem func=wmp
subtype rlcs_ibf_mprem is integer range 15 downto 11;
subtype rlcs_ibf_mploc is integer range 10 downto 8;
constant rlcs_ibf_ena_mprem : integer := 5;
constant rlcs_ibf_ena_mploc : integer := 4;
 
subtype rlda_ibf_seek_df is integer range 15 downto 7;
constant rlda_ibf_seek_hs : integer := 4;
constant rlda_ibf_seek_dir : integer := 2;
constant rlda_msk_seek : slv16 := "0000000000001011";
constant rlda_val_seek : slv16 := "0000000000000001";
 
constant rlda_ibf_gs_rst : integer := 3;
constant rlda_msk_gs : slv16 := "0000000011110111";
constant rlda_val_gs : slv16 := "0000000000000011";
 
constant sta_ibf_wde : integer := 15; -- Write data error - always 0
constant sta_ibf_che : integer := 14; -- Current head error - always 0
constant sta_ibf_wl : integer := 13; -- Write lock - used
constant sta_ibf_sto : integer := 12; -- Seek time out - used
constant sta_ibf_spe : integer := 11; -- Spin error - used
constant sta_ibf_wge : integer := 10; -- Write gate error - used
constant sta_ibf_vce : integer := 9; -- Volume check - used
constant sta_ibf_dse : integer := 8; -- Drive select error - used
constant sta_ibf_dt : integer := 7; -- Drive type - used
constant sta_ibf_hs : integer := 6; -- Head select - used
constant sta_ibf_co : integer := 5; -- Cover open - used
constant sta_ibf_ho : integer := 4; -- Heads out - used
constant sta_ibf_bh : integer := 3; -- Brush home - always 1
subtype sta_ibf_st is integer range 2 downto 0; -- Drive state
 
constant st_load : slv3 := "000"; -- st: Load(ing) cartidge - used
constant st_spin : slv3 := "001"; -- st: Spin(ing) up - !unused!
constant st_brush : slv3 := "010"; -- st: Brush(ing) cycle - !unused!
constant st_hload : slv3 := "011"; -- st: Load(ing) heads - !unused!
constant st_seek : slv3 := "100"; -- st: Seek(ing) - may be used
constant st_lock : slv3 := "101"; -- st: Lock(ed) on - used
constant st_unl : slv3 := "110"; -- st: Unload(ing) heads - !unused!
constant st_down : slv3 := "111"; -- st: Spin(ing) down - !unused!
-- only two mayor drive states are used
-- on: st=lock; ho=1; co=0; ( file connected in backend)
-- off: st=load; ho=0; co=1; (no file connected in backend)
 
subtype pos_ibf_ca is integer range 15 downto 7;
constant pos_ibf_hs : integer := 6;
subtype pos_ibf_sa is integer range 5 downto 0;
constant mploc_mp : slv3 := "000"; -- return imem(mp)
constant mploc_sta : slv3 := "001"; -- return sta(ds)
constant mploc_pos : slv3 := "010"; -- return pos(ds)
constant mploc_zero : slv3 := "011"; -- return 0
constant mploc_crc : slv3 := "100"; -- return imem(crc)
 
constant mprem_f_map : integer := 4; -- mprem map enable
subtype mprem_f_addr is integer range 3 downto 0;
constant mprem_f_seq : integer := 3; -- mprem seq enable
subtype mprem_f_state is integer range 2 downto 0;
constant mprem_mapseq : slv2 := "11"; -- enable map + seq
constant mprem_s_mp : slv3 := "000"; -- access imem(mp)
constant mprem_s_sta : slv3 := "001"; -- access sta(ds)
constant mprem_s_pos : slv3 := "010"; -- access pos(ds)
constant mprem_init : slv5 := "10000"; -- enable map,fix, show mp
constant ca_max_rl01 : slv9 := "011111111"; -- max cylinder for RL01 (255)
constant ca_max_rl02 : slv9 := "111111111"; -- max cylinder for RL02 (511)
type state_type is (
s_idle, -- idle: handle ibus
s_csread, -- csread: handle cs read
s_gs_rpos, -- gs_rpos: read pos(ds)
s_gs_sta, -- gs_sta: handle status
s_seek_rsta, -- seek_rsta: read sta(ds)
s_seek_rpos, -- seek_rpos: read pos(ds)
s_seek_clip, -- seek_clip: clip new ca
s_seek_wpos, -- seek_wpos: write pos(ds)
s_init -- init: handle init
);
 
type regs_type is record -- state registers
ibsel : slbit; -- ibus select
state : state_type; -- state
iaddr : slv4; -- init addr counter
cserr : slbit; -- rlcs: composite error
csde : slbit; -- rlcs: drive error
cse : slv4; -- rlcs: error
csds : slv2; -- rlcs: drive select
cscrdy : slbit; -- rlcs: controller ready
csie : slbit; -- rlcs: interrupt enable
csbae : slv2; -- rlcs: bus address extenstion
csfunc : slv3; -- rlcs: function code
csdrdy : slbit; -- rlcs: drive ready
da : slv16; -- rlda shadow reg
gshs : slbit; -- gs: pos(ds)(hs) (head select)
seekdt : slbit; -- seek: drive type: 0=RL01, 1=RL02
seekcan: slv10; -- seek: cylinder address, new
seekcac: slv9; -- seek: cylinder address, clipped
ireq : slbit; -- interrupt request flag
mploc : slv3; -- mp loc state
mprem : slv5; -- mp rem state
crdone : slbit; -- control reset done since last fdone
end record regs_type;
 
constant regs_init : regs_type := (
'0', -- ibsel
s_init, -- state
imem_ba, -- iaddr
'0','0', -- cserr,csde
(others=>'0'), -- cse
(others=>'0'), -- csds
'1','0', -- cscrdy, csie
(others=>'0'), -- csbae
(others=>'0'), -- csfunc
'0', -- csdrdy
(others=>'0'), -- da
'0', -- gshs
'0', -- seekdt
(others=>'0'), -- seekcan
(others=>'0'), -- seekcac
'0', -- ireq
mploc_mp, -- mploc
mprem_init, -- mprem
'1' -- crdone
);
 
signal R_REGS : regs_type := regs_init;
signal N_REGS : regs_type := regs_init;
 
signal MEM_1_WE : slbit := '0';
signal MEM_0_WE : slbit := '0';
signal MEM_ADDR : slv4 := (others=>'0');
signal MEM_DIN : slv16 := (others=>'0');
signal MEM_DOUT : slv16 := (others=>'0');
begin
MEM_1 : ram_1swar_gen
generic map (
AWIDTH => 4,
DWIDTH => 8)
port map (
CLK => CLK,
WE => MEM_1_WE,
ADDR => MEM_ADDR,
DI => MEM_DIN(ibf_byte1),
DO => MEM_DOUT(ibf_byte1));
 
MEM_0 : ram_1swar_gen
generic map (
AWIDTH => 4,
DWIDTH => 8)
port map (
CLK => CLK,
WE => MEM_0_WE,
ADDR => MEM_ADDR,
DI => MEM_DIN(ibf_byte0),
DO => MEM_DOUT(ibf_byte0));
 
proc_regs: process (CLK)
begin
if rising_edge(CLK) then
if BRESET='1' then
R_REGS <= regs_init;
else
R_REGS <= N_REGS;
end if;
end if;
end process proc_regs;
 
proc_next : process (R_REGS, CE_MSEC, IB_MREQ, MEM_DOUT, EI_ACK)
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';
variable iei_req : slbit := '0';
variable imem_we0 : slbit := '0';
variable imem_we1 : slbit := '0';
variable imem_addr : slv4 := (others=>'0');
variable imem_din : slv16 := (others=>'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';
iei_req := '0';
 
imem_we0 := '0';
imem_we1 := '0';
imem_addr := "00" & IB_MREQ.addr(2 downto 1);
imem_din := IB_MREQ.din;
-- ibus address decoder
n.ibsel := '0';
if IB_MREQ.aval = '1' and
IB_MREQ.addr(12 downto 3)=ibaddr_rl11(12 downto 3) then
n.ibsel := '1';
end if;
 
-- internal state machine
case r.state is
when s_idle => -- idle: handle ibus -----------------
 
if r.ibsel='1' then -- selected
idout := MEM_DOUT;
imem_we0 := ibw0;
imem_we1 := ibw1;
 
case IB_MREQ.addr(2 downto 1) is
 
when ibaddr_rlcs => -- RLCS - control register -------
imem_we0 := '0'; -- MEM not used for rlcs
imem_we1 := '0';
imem_addr := imem_sta(imf_typ) & r.csds; -- get sta(ds)
 
-- determine DRDY
n.csdrdy := '1';
if MEM_DOUT(sta_ibf_st) /= st_lock or -- drive not on and locked
MEM_DOUT(sta_ibf_vce) = '1' then -- or volume check
-- ??? also CRDY=0 here ???
n.csdrdy := '0';
end if;
 
-- determine DE and ERR
n.cserr := '0';
if MEM_DOUT(sta_ibf_st) = st_load or -- drive off
MEM_DOUT(sta_ibf_vce) = '1' then -- or volume check
n.csde := '1';
n.cserr := '1';
end if;
if r.csde = '1' or r.cse /= e_ok then
n.cserr := '1';
end if;
if ibrd = '1' then -- cs read
ibhold := '1';
n.state := s_csread;
 
elsif IB_MREQ.we = '1' then -- cs write
 
if ibrem = '0' then -- loc write access
 
if IB_MREQ.be1 = '1' then
if r.cscrdy = '1' then -- freeze csds when busy
n.csds := IB_MREQ.din(rlcs_ibf_ds);
end if;
end if;
 
if IB_MREQ.be0 = '1' then
n.csie := IB_MREQ.din(rlcs_ibf_ie);
n.csbae := IB_MREQ.din(rlcs_ibf_bae);
 
if r.cscrdy = '1' then -- controller ready
 
n.csfunc := IB_MREQ.din(rlcs_ibf_func); -- latch func
if IB_MREQ.din(rlcs_ibf_crdy) = '1' then -- no crdy clr
if IB_MREQ.din(rlcs_ibf_ie) = '1' and r.csie = '0' then
n.ireq := '1';
end if;
else -- crdy clr --> handle func
 
n.cserr := '0'; -- clear errors
n.csde := '0';
n.cse := "0000";
 
case IB_MREQ.din(rlcs_ibf_func) is
when func_noop => -- noop -------
n.ireq := r.csie; -- interrupt
 
when func_gs => -- get status -
if (r.da and rlda_msk_gs) /= rlda_val_gs then
n.cserr := '1';
n.cse := e_incomp;
n.ireq := IB_MREQ.din(rlcs_ibf_ie);
else
ibhold := '1';
n.state := s_gs_rpos;
end if;
when func_seek => -- seek -------
if (r.da and rlda_msk_seek) /= rlda_val_seek then
n.cserr := '1';
n.cse := e_incomp;
n.ireq := IB_MREQ.din(rlcs_ibf_ie);
else
ibhold := '1';
n.state := s_seek_rsta;
end if;
 
when others => -- all other funcs
n.cscrdy := '0'; -- signal cntl busy
ilam := '1'; -- issue lam
end case;
end if; -- else IB_MREQ.din(rlcs_ibf_crdy) = '1'
end if; -- r.cscrdy = '1'
end if; -- IB_MREQ.be0 = '1'
else -- rem write access
case IB_MREQ.din(rlcs_ibf_func) is
 
when rfunc_wcs =>
n.csde := IB_MREQ.din(rlcs_ibf_de);
n.cse := IB_MREQ.din(rlcs_ibf_e);
n.cscrdy := IB_MREQ.din(rlcs_ibf_crdy);
n.csbae := IB_MREQ.din(rlcs_ibf_bae);
if r.cscrdy = '0' and IB_MREQ.din(rlcs_ibf_crdy) = '1' then
n.ireq := r.csie;
end if;
when rfunc_wmp =>
if IB_MREQ.din(rlcs_ibf_ena_mprem) = '1' then
n.mprem := IB_MREQ.din(rlcs_ibf_mprem);
end if;
if IB_MREQ.din(rlcs_ibf_ena_mploc) = '1' then
n.mploc := IB_MREQ.din(rlcs_ibf_mploc);
end if;
 
when others => null;
end case;
end if;
end if;
 
when ibaddr_rlba => -- RLBA - bus address register ---
imem_din(0) := '0'; -- lsb forced 0
null;
 
when ibaddr_rlda => -- RLDA - disk address register --
if ibw1 = '1' then
n.da(15 downto 8) := IB_MREQ.din(15 downto 8);
end if;
if ibw0 = '1' then
n.da( 7 downto 0) := IB_MREQ.din( 7 downto 0);
end if;
 
when ibaddr_rlmp => -- RLMP - multipurpose register --
 
if ibrem = '0' then -- loc access
if ibrd = '1' then -- loc mp read
case r.mploc is
when mploc_mp => -- return imem(mp)
null;
when mploc_sta => -- return sta(ds)
imem_addr := imem_sta(imf_typ) & r.csds;
when mploc_pos => -- return pos(ds)
imem_addr := imem_pos(imf_typ) & r.csds;
n.mploc := mploc_zero;
when mploc_zero => -- return 0
idout := (others => '0');
n.mploc := mploc_crc;
when mploc_crc => -- return imem(crc)
imem_addr := imem_crc;
when others => null;
end case;
elsif IB_MREQ.we = '1' then -- loc mp write
n.mploc := mploc_mp; -- use main mp reg in future
end if;
 
else -- rem access
if r.mprem(mprem_f_map) = '0' then -- map off - fixed addr
imem_addr := r.mprem(mprem_f_addr);
else -- sequence
case r.mprem(mprem_f_state) is
when mprem_s_mp => -- mp {used as wc}
imem_addr := imem_mp;
if r.mprem(mprem_f_seq) = '1' then -- ??? check re&we !!!
n.mprem := mprem_mapseq & mprem_s_sta;
end if;
when mprem_s_sta => -- sta(ds)
imem_addr := imem_sta(imf_typ) & r.csds;
if r.mprem(mprem_f_seq) = '1' then -- ??? check re&we !!!
n.mprem := mprem_mapseq & mprem_s_pos;
end if;
when mprem_s_pos => -- pos(ds)
imem_addr := imem_pos(imf_typ) & r.csds;
when others => -- bad state
imem_addr := imem_bad;
end case;
end if;
end if;
when others => null;
end case;
end if;
 
when s_csread => -- csread: handle cs read -----------
idout(rlcs_ibf_err) := r.cserr;
idout(rlcs_ibf_de) := r.csde;
idout(rlcs_ibf_e) := r.cse;
idout(rlcs_ibf_ds) := r.csds;
idout(rlcs_ibf_crdy) := r.cscrdy;
idout(rlcs_ibf_ie) := r.csie;
idout(rlcs_ibf_bae) := r.csbae;
idout(rlcs_ibf_func) := r.csfunc;
idout(rlcs_ibf_drdy) := r.csdrdy;
n.state := s_idle;
when s_gs_rpos => -- gs_rpos: read pos(ds) -----------
imem_addr := imem_pos(imf_typ) & r.csds; -- get pos(ds)
n.gshs := MEM_DOUT(pos_ibf_hs); -- get hs bit
ibhold := r.ibsel;
n.state := s_gs_sta;
 
when s_gs_sta => -- gs_sta: handle status -----------
imem_addr := imem_sta(imf_typ) & r.csds; -- get sta(ds)
imem_we0 := '1'; -- always update
imem_we1 := '1';
imem_din := MEM_DOUT;
imem_din(sta_ibf_hs) := r.gshs;
if r.da(rlda_ibf_gs_rst) = '1' then -- if RST set
imem_din(sta_ibf_wde) := '0'; -- clear error bits
imem_din(sta_ibf_che) := '0';
imem_din(sta_ibf_sto) := '0';
imem_din(sta_ibf_spe) := '0';
imem_din(sta_ibf_wge) := '0';
imem_din(sta_ibf_vce) := '0';
imem_din(sta_ibf_dse) := '0';
end if;
n.mploc := mploc_sta; -- use sta(ds) as mp
n.ireq := r.csie; -- interrupt
n.state := s_idle;
when s_seek_rsta => -- seek_rsta: read sta(ds) -----------
imem_addr := imem_sta(imf_typ) & r.csds; -- get sta(ds)
n.seekdt := MEM_DOUT(sta_ibf_dt);
imem_din := MEM_DOUT;
if MEM_DOUT(sta_ibf_st) /= st_lock then -- drive off
imem_we0 := '1'; -- update sta
imem_we1 := '1';
imem_din(sta_ibf_sto) := '1'; -- set STO (seek time out)
n.cse := e_incomp;
n.ireq := r.csie; -- interrupt
n.state := s_idle;
else -- drive on
ibhold := r.ibsel;
n.state := s_seek_rpos;
end if;
when s_seek_rpos => -- seek_rpos: read pos(ds) -----------
imem_addr := imem_pos(imf_typ) & r.csds; -- get pos(ds)
if r.da(rlda_ibf_seek_dir) = '1' then
n.seekcan := slv(unsigned('0' & MEM_DOUT(pos_ibf_ca)) +
unsigned('0' & r.da(rlda_ibf_seek_df)) );
else
n.seekcan := slv(unsigned('0' & MEM_DOUT(pos_ibf_ca)) -
unsigned('0' & r.da(rlda_ibf_seek_df)) );
end if;
ibhold := r.ibsel;
n.state := s_seek_clip;
 
when s_seek_clip => -- seek_clip: clip new ca ------------
n.seekcac := r.seekcan(8 downto 0);
-- new ca overflowed ? for RL02 (9) and for RL01 (9:8) must be "00"
if r.seekcan(9) = '1' or
(r.seekdt = '0' and r.seekcan(8) = '1') then
if r.da(rlda_ibf_seek_dir) = '1' then -- outward seek
if r.seekdt = '1' then -- is RL02
n.seekcac := ca_max_rl02; -- clip to RL02 max ca
else -- is RL01
n.seekcac := ca_max_rl01; -- clip to RL01 max ca
end if;
else -- inward seek
n.seekcac := "000000000"; -- clip to 0
end if;
end if;
ibhold := r.ibsel;
n.state := s_seek_wpos;
 
when s_seek_wpos => -- seek_wpos: write pos(ds) ----------
imem_addr := imem_pos(imf_typ) & r.csds; -- get pos(ds)
imem_we0 := '1';
imem_we1 := '1';
imem_din := MEM_DOUT;
imem_din(pos_ibf_ca) := r.seekcac;
imem_din(pos_ibf_hs) := r.da(rlda_ibf_seek_hs);
n.ireq := r.csie; -- interrupt
n.state := s_idle;
when s_init => -- init: handle init -----------------
ibhold := r.ibsel; -- hold ibus when controller busy
imem_addr := r.iaddr;
imem_din := (others=>'0');
imem_we0 := '1';
imem_we1 := '1';
if r.iaddr(imf_typ) = imem_sta(imf_typ) then -- if sta(x)
imem_din := MEM_DOUT; -- keep state
imem_din(sta_ibf_wde) := '0'; -- and clear err
imem_din(sta_ibf_che) := '0';
imem_din(sta_ibf_sto) := '0';
imem_din(sta_ibf_spe) := '0';
imem_din(sta_ibf_wge) := '0';
imem_din(sta_ibf_vce) := '0';
imem_din(sta_ibf_dse) := '0';
end if;
n.iaddr := slv(unsigned(r.iaddr) + 1);
if unsigned(r.iaddr) = unsigned(imem_sta)+3 then -- stop after sta(3)
n.state := s_idle;
end if;
when others => null;
end case;
 
iei_req := r.ireq; -- ??? simplify, use r.ireq directly
 
if EI_ACK = '1' or r.csie = '0' then -- interrupt executed or ie disabled
n.ireq := '0'; -- cancel request
end if;
N_REGS <= n;
 
MEM_0_WE <= imem_we0;
MEM_1_WE <= imem_we1;
MEM_ADDR <= imem_addr;
MEM_DIN <= imem_din;
IB_SRES.dout <= idout;
IB_SRES.ack <= r.ibsel and ibreq;
IB_SRES.busy <= ibhold and ibreq;
 
RB_LAM <= ilam;
EI_REQ <= iei_req;
end process proc_next;
 
end syn;
/ibd_iist.vhd
0,0 → 1,684
-- $Id: ibd_iist.vhd 641 2015-02-01 22:12:15Z mueller $
--
-- Copyright 2009-2011 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: ibd_iist - syn
-- Description: ibus dev(loc): IIST
--
-- Dependencies: -
-- Test bench: -
-- Target Devices: generic
-- Tool versions: ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2010-10-17 333 12.1 M53d xc3s1000-4 112 510 0 291 s 15.8
-- 2010-10-17 314 12.1 M53d xc3s1000-4 111 504 0 290 s 15.6
-- 2009-06-01 223 10.1.03 K39 xc3s1000-4 111 439 0 256 s 9.8
-- 2009-06-01 221 10.1.03 K39 xc3s1000-4 111 449 0 258 s 13.3
--
-- Revision History:
-- Date Rev Version Comment
-- 2011-11-18 427 0.8.1 now numeric_std clean
-- 2010-10-17 333 0.8 use ibus V2 interface
-- 2009-06-07 224 0.7 send inverted stc_stp; remove pgc_err; honor msk_im
-- also for dcf_dcf and exc_rte; add iist_mreq and
-- iist_sreq, boot and lock interfaces
-- 2009-06-05 223 0.6 level interrupt, parity logic, exc.ui logic
-- st logic modified (partially tested)
-- 2009-06-01 221 0.5 Initial version (untested, lock&boot missing)
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
use work.iblib.all;
use work.ibdlib.all;
 
-- ----------------------------------------------------------------------------
entity ibd_iist is -- ibus dev(loc): IIST
-- fixed address: 177500
generic (
SID : slv2 := "00"); -- self id
port (
CLK : in slbit; -- clock
CE_USEC : in slbit; -- usec pulse
RESET : in slbit; -- system reset
BRESET : in slbit; -- ibus reset
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
IIST_BUS : in iist_bus_type; -- iist bus (input from all iist's)
IIST_OUT : out iist_line_type; -- iist output
IIST_MREQ : out iist_mreq_type; -- iist->cpu requests
IIST_SRES : in iist_sres_type -- cpu->iist responses
);
end ibd_iist;
 
architecture syn of ibd_iist is
 
constant ibaddr_iist : slv16 := slv(to_unsigned(8#177500#,16));
 
constant tdlysnd : natural := 150; -- send delay timer
 
constant ibaddr_acr : slv1 := "0"; -- acr address offset
constant ibaddr_adr : slv1 := "1"; -- adr address offset
constant acr_ibf_clr : integer := 15; -- clear flag
subtype acr_ibf_sid is integer range 9 downto 8; -- self id
subtype acr_ibf_ac is integer range 3 downto 0; -- ac code
 
constant ac_pge : slv4 := "0000"; -- 0 program generated enables
constant ac_pgc : slv4 := "0001"; -- 1 program generated control/status
constant ac_ste : slv4 := "0010"; -- 2 sanity timer enables
constant ac_stc : slv4 := "0011"; -- 3 sanity timer control/status
constant ac_msk : slv4 := "0100"; -- 4 input masks
constant ac_pgf : slv4 := "0101"; -- 5 program generated flags
constant ac_stf : slv4 := "0110"; -- 6 sanity timer flags
constant ac_dcf : slv4 := "0111"; -- 7 disconnect flags
constant ac_exc : slv4 := "1000"; -- 10 exceptions
constant ac_mtc : slv4 := "1101"; -- 15 maintenance control
 
subtype pge_ibf_pbe is integer range 11 downto 8; -- pg boot ena
subtype pge_ibf_pie is integer range 3 downto 0; -- pg int ena
 
constant pgc_ibf_err : integer := 15; -- error
constant pgc_ibf_grj : integer := 14; -- go reject
constant pgc_ibf_pgrmr : integer := 13; -- pg req refused
constant pgc_ibf_strmr : integer := 12; -- st req refused
constant pgc_ibf_rdy : integer := 11; -- ready flag
subtype pgc_ibf_sid is integer range 9 downto 8; -- self id
constant pgc_ibf_ip : integer := 3; -- int pending
constant pgc_ibf_ie : integer := 2; -- int enable
constant pgc_ibf_ptp : integer := 1; -- pg parity
constant pgc_ibf_go : integer := 0; -- go flag
 
subtype ste_ibf_sbe is integer range 11 downto 8; -- st boot enable
subtype ste_ibf_sie is integer range 3 downto 0; -- st int enable
 
subtype stc_ibf_count is integer range 15 downto 8; -- count
constant stc_ibf_tmo : integer := 3; -- timeout
constant stc_ibf_lke : integer := 2; -- lockup enable
constant stc_ibf_stp : integer := 1; -- st parity
constant stc_ibf_enb : integer := 0; -- enable
subtype msk_ibf_bm is integer range 11 downto 8; -- boot mask
subtype msk_ibf_im is integer range 3 downto 0; -- int mask
 
subtype pgf_ibf_pbf is integer range 11 downto 8; -- boot flags
subtype pgf_ibf_pif is integer range 3 downto 0; -- int flags
 
subtype stf_ibf_sbf is integer range 11 downto 8; -- boot flags
subtype stf_ibf_sif is integer range 3 downto 0; -- int flags
 
subtype dcf_ibf_brk is integer range 11 downto 8; -- break flags
subtype dcf_ibf_dcf is integer range 3 downto 0; -- disconnect flags
 
subtype exc_ibf_ui is integer range 11 downto 8; -- unexpected int
subtype exc_ibf_rte is integer range 3 downto 0; -- transm. error
 
constant mtc_ibf_mttp : integer := 11; -- maint. type
constant mtc_ibf_mfrm : integer := 10; -- maint. frame err
subtype mtc_ibf_mid is integer range 9 downto 8; -- maint. id
constant mtc_ibf_dsbt : integer := 3; -- disable boot
constant mtc_ibf_enmxd : integer := 2; -- enable maint mux
constant mtc_ibf_enmlp : integer := 1; -- enable maint loop
constant mtc_ibf_dsdrv : integer := 0; -- disable driver
 
type state_type is (
s_idle, -- idle state
s_clear, -- handle acr clr
s_stsnd, -- handle st transmit
s_pgsnd -- handle pg transmit
);
 
type regs_type is record -- state registers
ibsel : slbit; -- ibus select
acr_ac : slv4; -- acr: ac
pge_pbe : slv4; -- pge: pg boot ena
pge_pie : slv4; -- pge: pg int ena
pgc_grj : slbit; -- pgc: go reject
pgc_pgrmr : slbit; -- pgc: pg req refused
pgc_strmr : slbit; -- pgc: st req refused
pgc_ie : slbit; -- pgc: int enable
pgc_ptp : slbit; -- pgc: pg parity
ste_sbe : slv4; -- ste: st boot enable
ste_sie : slv4; -- ste: st int enable
stc_count : slv8; -- stc: count
stc_tmo : slbit; -- stc: timeout
stc_lke : slbit; -- stc: lockup enable
stc_stp : slbit; -- stc: st parity
stc_enb : slbit; -- stc: enable
msk_bm : slv4; -- msk: boot mask
msk_im : slv4; -- msk: int mask
pgf_pbf : slv4; -- pgf: boot flags
pgf_pif : slv4; -- pgf: int flags
stf_sbf : slv4; -- stf: boot flags
stf_sif : slv4; -- stf: int flags
dcf_brk : slv4; -- dcf: break flags
dcf_dcf : slv4; -- dcf: disconnect flags
exc_ui : slv4; -- exc: unexpected int
exc_rte : slv4; -- exc: transm. error
mtc_mttp : slbit; -- mtc: maint. type
mtc_mfrm : slbit; -- mtc: maint. frame err
mtc_mid : slv2; -- mtc: maint. id
mtc_dsbt : slbit; -- mtc: disable boot
mtc_enmxd : slbit; -- mtc: enable maint mux
mtc_enmlp : slbit; -- mtc: enable maint loop
mtc_dsdrv : slbit; -- mtc: disable driver
state : state_type; -- state
req_clear : slbit; -- request clear
req_stsnd : slbit; -- request sanity timer transmit
req_pgsnd : slbit; -- request prog. gen. transmit
tcnt256 : slv8; -- usec clock divider for st clock
tcntsnd : slv8; -- timer for transmit delay
req_lock : slbit; -- cpu lock request
req_boot : slbit; -- cpu boot request
end record regs_type;
 
constant regs_init : regs_type := (
'0', -- ibsel
"0000", -- acr_ac
"0000","0000", -- pge_pbe, pge_pie
'0', -- pgc_grj
'0','0', -- pgc_pgrmr, pgc_strmr
'0','0', -- pgc_ie, pgc_ptp
"0000","0000", -- ste_sbe, ste_sie
(others=>'0'), -- stc_count
'0','0', -- stc_tmo, stc_lke
'0','0', -- stc_stp, stc_enb
"0000","0000", -- msk_bm, msk_im
"0000","0000", -- pgf_pbf, pgf_pif
"0000","0000", -- stf_sbf, stf_sif
"0000","0000", -- dcf_brk, dcf_dcf
"0000","0000", -- exc_ui, exc_rte
'0','0', -- mtc_mttp, mtc_mfrm
"00", -- mtc_mid
'0','0', -- mtc_dsbt, mtc_enmxd
'0','0', -- mtc_enmlp, mtc_dsdrv
s_idle, -- state
'0', -- req_clear
'0','0', -- req_stsnd, req_pgsnd
(others=>'0'), -- tcnt256
(others=>'0'), -- tcntsnd
'0','0' -- req_lock, req_boot
);
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
if BRESET = '1' or -- BRESET is 1 for system and ibus reset
R_REGS.req_clear='1' then
R_REGS <= regs_init; --
if RESET = '0' then -- if RESET=0 we do just an ibus reset
R_REGS.pgf_pbf <= N_REGS.pgf_pbf; -- don't reset pg boot flags
R_REGS.stf_sbf <= N_REGS.stf_sbf; -- don't reset st boot flags
R_REGS.tcnt256 <= N_REGS.tcnt256; -- don't reset st clock divider
end if;
else
R_REGS <= N_REGS;
end if;
end if;
end process proc_regs;
 
proc_next : process (R_REGS, CE_USEC, IB_MREQ, EI_ACK, EI_ACK,
IIST_BUS(0), IIST_BUS(1), IIST_BUS(2), IIST_BUS(3),
IIST_SRES)
variable r : regs_type := regs_init;
variable n : regs_type := regs_init;
variable ibhold : slbit := '0';
variable idout : slv16 := (others=>'0');
variable ibreq : slbit := '0';
variable ibrd : slbit := '0';
variable ibw0 : slbit := '0';
variable ibw1 : slbit := '0';
variable int_or : slbit := '0';
variable tcnt256_end : slbit := '0';
variable tcntsnd_end : slbit := '0';
variable eff_id : slv2 := "00";
variable eff_bus : iist_bus_type := iist_bus_init;
variable par_err : slbit := '0';
variable act_ibit : slbit := '0';
variable act_bbit : slbit := '0';
variable iout : iist_line_type := iist_line_init;
begin
 
r := R_REGS;
n := R_REGS;
 
ibhold := '0';
idout := (others=>'0');
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;
 
int_or := r.pgc_grj or r.pgc_pgrmr or r.pgc_strmr;
for i in r.dcf_dcf'range loop
int_or := int_or or r.dcf_dcf(i) or
r.exc_rte(i) or
r.pgf_pif(i) or
r.stf_sif(i);
end loop; -- i
tcnt256_end := '0';
if CE_USEC='1' and r.stc_enb='1'then -- if st enabled on every usec
n.tcnt256 := slv(unsigned(r.tcnt256) + 1); -- advance 8 bit counter
if unsigned(r.tcnt256) = 255 then -- if wrap
tcnt256_end := '1'; -- signal 256 usec passed
end if;
end if;
tcntsnd_end := '0';
n.tcntsnd := slv(unsigned(r.tcntsnd) + 1); -- advance send timer counter
if unsigned(r.tcntsnd) = tdlysnd-1 then -- if delay time reached
tcntsnd_end := '1'; -- signal end
end if;
eff_id := SID; -- effective self-id, normally SID
if r.mtc_enmxd = '1' then -- if maint. mux enabled
eff_id := r.mtc_mid; -- use maint. id
end if;
 
eff_bus := IIST_BUS;
 
par_err := '0';
act_ibit := '0';
act_bbit := '0';
iout := iist_line_init; -- default state of out line
-- ibus address decoder
n.ibsel := '0';
if IB_MREQ.aval='1' and
IB_MREQ.addr(12 downto 2)=ibaddr_iist(12 downto 2) then
n.ibsel := '1';
end if;
 
-- internal state machine
case r.state is
when s_idle => -- idle state
n.tcntsnd := (others=>'0'); -- keep send delay timer zero
if r.req_stsnd = '1' then -- sanity timer request pending
n.state := s_stsnd;
elsif r.req_pgsnd = '1' then -- prog. gen. request pending
n.state := s_pgsnd;
end if;
when s_clear => -- handle acr clr
ibhold := r.ibsel; -- keep req pending if selected
-- r.req_clear is set when in this state and cause a reset in prog_regs
-- --> n.req_clear := '0';
-- --> n.state := s_idle;
 
when s_stsnd => -- handle st transmit
if tcntsnd_end = '1' then -- send delay expired
n.req_stsnd := '0'; -- clear st transmit request
iout.req := '1'; -- do transmit
iout.stf := '1'; -- signal type = st
iout.imask := r.ste_sie; -- int enables
iout.bmask := r.ste_sbe; -- boot enables
iout.par := not r.stc_stp; -- send parity (odd incl. stf!)
iout.frm := '0'; -- frame always ok
n.state := s_idle;
end if;
when s_pgsnd => -- handle pg transmit
if tcntsnd_end = '1' then -- send delay expired
n.req_pgsnd := '0'; -- clear pg transmit request
iout.req := '1'; -- do transmit
iout.stf := '0'; -- signal type = pg
iout.imask := r.pge_pie; -- int enables
iout.bmask := r.pge_pbe; -- boot enables
iout.par := r.pgc_ptp; -- send parity
iout.frm := '0'; -- frame always ok
n.state := s_idle;
end if;
when others => null;
end case;
 
if r.mtc_enmxd = '1' then -- if maintenance mux enabled
iout.stf := r.mtc_mttp; -- force type from mtc_mttp
iout.frm := r.mtc_mfrm; -- force frame from mtc_mfrm
end if;
-- ibus transactions
if r.ibsel = '1' and ibhold='0' then
 
if IB_MREQ.addr(1 downto 1) = "0" then -- ACR -- access control reg -----
 
idout(acr_ibf_sid) := SID;
idout(acr_ibf_ac) := r.acr_ac;
 
if ibw1 = '1' then
if IB_MREQ.din(acr_ibf_clr) = '1' then
n.req_clear := '1';
n.state := s_clear;
end if;
end if;
if ibw0 = '1' then
n.acr_ac := IB_MREQ.din(acr_ibf_ac);
end if;
 
else -- ADR -- access data reg --------
case r.acr_ac is
 
when ac_pge => -- PGE -- program gen enables --------
 
idout(pge_ibf_pbe) := r.pge_pbe;
idout(pge_ibf_pie) := r.pge_pie;
 
if IB_MREQ.we = '1' then
if r.req_pgsnd = '0' then -- no pg transmit pending
if ibw1 = '1' then
n.pge_pbe := IB_MREQ.din(pge_ibf_pbe);
end if;
if ibw0 = '1' then
n.pge_pie := IB_MREQ.din(pge_ibf_pie);
end if;
else -- if collision with pg transmit
n.pgc_pgrmr := '1'; -- set pge refused flag
end if;
 
end if;
 
when ac_pgc => -- PGC -- program gen control/status -
 
idout(pgc_ibf_err) := r.pgc_grj or r.pgc_pgrmr or r.pgc_strmr;
idout(pgc_ibf_grj) := r.pgc_grj;
idout(pgc_ibf_pgrmr) := r.pgc_pgrmr;
idout(pgc_ibf_strmr) := r.pgc_strmr;
idout(pgc_ibf_rdy) := not r.req_pgsnd;
idout(pgc_ibf_sid) := eff_id;
idout(pgc_ibf_ip) := int_or;
idout(pgc_ibf_ie) := r.pgc_ie;
idout(pgc_ibf_ptp) := r.pgc_ptp;
 
if ibw1 = '1' then
if IB_MREQ.din(pgc_ibf_err) = '1' then -- '1' written into ERR
n.pgc_grj := '0'; -- clears GRJ
n.pgc_pgrmr := '0'; -- clears PGRMR
n.pgc_strmr := '0'; -- clears STRMR
end if;
end if;
if ibw0 = '1' then
n.pgc_ie := IB_MREQ.din(pgc_ibf_ie);
n.pgc_ptp := IB_MREQ.din(pgc_ibf_ptp);
if IB_MREQ.din(pgc_ibf_go) = '1' then -- GO bit set
if r.req_pgsnd = '0' then -- if ready (no pgsnd pend)
n.req_pgsnd := '1'; -- request pgsnd
else -- if not ready
n.pgc_grj := '1'; -- set go reject flag
end if;
end if;
end if;
 
when ac_ste => -- STE -- sanity timer enables -------
 
idout(ste_ibf_sbe) := r.ste_sbe;
idout(ste_ibf_sie) := r.ste_sie;
 
if IB_MREQ.we = '1' then
if r.req_stsnd = '0' then -- no st transmit pending
if ibw1 = '1' then
n.ste_sbe := IB_MREQ.din(ste_ibf_sbe);
end if;
if ibw0 = '1' then
n.ste_sie := IB_MREQ.din(ste_ibf_sie);
end if;
else -- if collision with st transmit
n.pgc_strmr := '1'; -- set ste refused flag
end if;
 
end if;
when ac_stc => -- STC -- sanity timer control/status
 
idout(stc_ibf_count) := r.stc_count;
idout(stc_ibf_tmo) := r.stc_tmo;
idout(stc_ibf_lke) := r.stc_lke;
idout(stc_ibf_stp) := r.stc_stp;
idout(stc_ibf_enb) := r.stc_enb;
 
if ibw1 = '1' then
n.stc_count := IB_MREQ.din(stc_ibf_count); -- reset st count
n.tcnt256 := (others=>'0'); -- reset usec count
end if;
if ibw0 = '1' then
if IB_MREQ.din(stc_ibf_tmo) = '1' then -- 1 written into TMO
n.stc_tmo := '0';
end if;
n.stc_lke := IB_MREQ.din(stc_ibf_lke);
n.stc_stp := IB_MREQ.din(stc_ibf_stp);
n.stc_enb := IB_MREQ.din(stc_ibf_enb);
end if;
 
when ac_msk => -- MSK -- input masks ----------------
 
idout(msk_ibf_bm) := r.msk_bm;
idout(msk_ibf_im) := r.msk_im;
 
if ibw1 = '1' then
n.msk_bm := IB_MREQ.din(msk_ibf_bm);
end if;
if ibw0 = '1' then
n.msk_im := IB_MREQ.din(msk_ibf_im);
end if;
 
when ac_pgf => -- PGF -- program generated flags ----
 
idout(pgf_ibf_pbf) := r.pgf_pbf;
idout(pgf_ibf_pif) := r.pgf_pif;
 
if ibw1 = '1' then
n.pgf_pbf := r.pgf_pbf and not IB_MREQ.din(pgf_ibf_pbf);
end if;
if ibw0 = '1' then
n.pgf_pif := r.pgf_pif and not IB_MREQ.din(pgf_ibf_pif);
end if;
 
when ac_stf => -- STF -- sanity timer flags ---------
 
idout(stf_ibf_sbf) := r.stf_sbf;
idout(stf_ibf_sif) := r.stf_sif;
 
if ibw1 = '1' then
n.stf_sbf := r.stf_sbf and not IB_MREQ.din(stf_ibf_sbf);
end if;
if ibw0 = '1' then
n.stf_sif := r.stf_sif and not IB_MREQ.din(stf_ibf_sif);
end if;
 
when ac_dcf => -- DCE -- disconnect flags -----------
 
idout(dcf_ibf_brk) := r.dcf_brk;
idout(dcf_ibf_dcf) := r.dcf_dcf;
 
if ibw0 = '1' then
n.dcf_dcf := r.dcf_dcf and not IB_MREQ.din(dcf_ibf_dcf);
end if;
 
when ac_exc => -- EXC -- exceptions -----------------
 
idout(exc_ibf_ui) := r.exc_ui;
idout(exc_ibf_rte) := r.exc_rte;
 
if ibw1 = '1' then
n.exc_ui := r.exc_ui and not IB_MREQ.din(exc_ibf_ui);
end if;
if ibw0 = '1' then
n.exc_rte := r.exc_rte and not IB_MREQ.din(exc_ibf_rte);
end if;
 
when ac_mtc => -- MTC -- maintenance control --------
 
idout(mtc_ibf_mttp) := r.mtc_mttp;
idout(mtc_ibf_mfrm) := r.mtc_mfrm;
idout(mtc_ibf_mid) := r.mtc_mid;
idout(mtc_ibf_dsbt) := r.mtc_dsbt;
idout(mtc_ibf_enmxd) := r.mtc_enmxd;
idout(mtc_ibf_enmlp) := r.mtc_enmlp;
idout(mtc_ibf_dsdrv) := r.mtc_dsdrv;
 
if ibw1 = '1' then
n.mtc_mttp := IB_MREQ.din(mtc_ibf_mttp);
n.mtc_mfrm := IB_MREQ.din(mtc_ibf_mfrm);
n.mtc_mid := IB_MREQ.din(mtc_ibf_mid);
end if;
if ibw0 = '1' then
n.mtc_dsbt := IB_MREQ.din(mtc_ibf_dsbt);
n.mtc_enmxd := IB_MREQ.din(mtc_ibf_enmxd);
n.mtc_enmlp := IB_MREQ.din(mtc_ibf_enmlp);
n.mtc_dsdrv := IB_MREQ.din(mtc_ibf_dsdrv);
end if;
 
when others => -- access to undefined AC code -------
null;
end case;
 
if unsigned(r.acr_ac) <= unsigned(ac_exc) then -- if ac 0,..,10
if IB_MREQ.rmw = '0' then -- if not 1st part of rmw
n.acr_ac := slv(unsigned(r.acr_ac) + 1); -- autoincrement
end if;
end if;
end if;
end if;
 
-- sanity timer
 
if tcnt256_end = '1' then -- if 256 usec expired (and enabled)
n.stc_count := slv(unsigned(r.stc_count) - 1);
if unsigned(r.stc_count) = 0 then -- if sanity timer expired
n.stc_tmo := '1'; -- set timeout flag
n.req_stsnd := '1'; -- request st transmit
if r.stc_lke = '1' then -- if lockup enabled
n.req_lock := '1'; -- request lockup
end if;
end if;
end if;
 
-- process iist bus inputs
 
if r.mtc_enmlp = '1' then -- if mainentance loop
for i in eff_bus'range loop
eff_bus(i) := iout; -- local signal on all input ports
eff_bus(i).dcf := '0'; -- all ports considered connected
end loop; -- i
end if;
for i in eff_bus'range loop
 
par_err := eff_bus(i).stf xor
eff_bus(i).imask(0) xor eff_bus(i).imask(1) xor
eff_bus(i).imask(2) xor eff_bus(i).imask(3) xor
eff_bus(i).bmask(0) xor eff_bus(i).bmask(1) xor
eff_bus(i).bmask(2) xor eff_bus(i).bmask(3) xor
not eff_bus(i).par;
act_ibit := eff_bus(i).imask(to_integer(unsigned(eff_id)));
act_bbit := eff_bus(i).bmask(to_integer(unsigned(eff_id)));
n.dcf_brk(i) := eff_bus(i).dcf; -- trace dcf state in brk
if eff_bus(i).dcf = '1' then -- if disconnected
if r.msk_im(i) = '0' then -- if not disabled
n.dcf_dcf(i) := '1'; -- set dcf flag
end if;
else -- if connected
if eff_bus(i).req = '1' then -- request received ?
if eff_bus(i).frm='1' or -- frame error seen ?
par_err='1' then -- parity error seen ?
if r.msk_im(i) = '0' then -- if not disabled
n.exc_rte(i) := '1'; -- set rte flag
end if;
else -- here if valid request seen
if act_ibit = '1' then -- interrupt request
if r.msk_im(i) = '1' then -- if disabled
n.exc_ui(i) := '1'; -- set ui flag
else -- if enabled
n.req_lock := '0'; -- release lock
if eff_bus(i).stf = '0' then -- and pg request
n.pgf_pif(i) := '1'; -- set pif flag
else -- and st request
n.stf_sif(i) := '1'; -- set sif flag
end if;
end if;
end if; -- act_ibit='1'
 
if act_bbit = '1' then -- boot request
if r.msk_bm(i) = '1' then -- if msk disabled
n.exc_ui(i) := '1'; -- set ui flag
else -- if msk enabled
if r.mtc_dsbt = '0' then -- if mtc enabled
n.req_lock := '0'; -- release lock
n.req_boot := '1'; -- request boot
end if;
if eff_bus(i).stf = '0' then -- and pg request
n.pgf_pbf(i) := '1'; -- set pbf flag
else -- and st request
n.stf_sbf(i) := '1'; -- set sbf flag
end if;
end if;
end if; -- act_bbit='1'
end if;
end if;
end if;
end loop;
-- process cpu->iist responses
if IIST_SRES.ack_lock = '1' then
n.req_lock := '0';
end if;
if IIST_SRES.ack_boot = '1' then
n.req_boot := '0';
end if;
 
N_REGS <= n;
 
IB_SRES.dout <= idout;
IB_SRES.ack <= r.ibsel and ibreq;
IB_SRES.busy <= ibhold and ibreq;
 
EI_REQ <= r.pgc_ie and int_or;
 
if r.mtc_dsdrv = '1' then -- if driver disconnected
iout.dcf := '1'; -- set dcf flag
iout.req := '0'; -- suppress requests
end if;
IIST_OUT <= iout; -- and finally send it out...
 
IIST_MREQ.lock <= r.req_lock;
IIST_MREQ.boot <= r.req_boot;
end process proc_next;
 
end syn;
/ib_sres_or_2.vbom
0,0 → 1,7
# libs
../vlib/slvtypes.vhd
iblib.vhd
# components
[sim]ib_sres_or_mon.vbom
# design
ib_sres_or_2.vhd
/ib_sres_or_4.vbom
0,0 → 1,7
# libs
../vlib/slvtypes.vhd
iblib.vhd
# components
[sim]ib_sres_or_mon.vbom
# design
ib_sres_or_4.vhd
/Makefile
0,0 → 1,31
# $Id: Makefile 639 2015-01-30 18:12:19Z mueller $
#
# Revision History:
# Date Rev Version Comment
# 2014-07-27 545 1.1.1 make reference board configurable via XTW_BOARD
# 2011-08-13 405 1.1 use includes from rtl/make
# 2008-08-22 161 1.0 Initial version
#
VBOM_all = $(wildcard *.vbom)
NGC_all = $(VBOM_all:.vbom=.ngc)
#
# reference board for test synthesis is Spartan-6 based Nexys3
ifndef XTW_BOARD
XTW_BOARD=nexys3
endif
include $(RETROBASE)/rtl/make_ise/xflow_default_$(XTW_BOARD).mk
#
.PHONY : all clean
#
all : $(NGC_all)
#
clean : ise_clean
#
#----
#
include $(RETROBASE)/rtl/make_ise/generic_xflow.mk
#
ifndef DONTINCDEP
include $(VBOM_all:.vbom=.dep_xst)
endif
#
/ibdr_rl11.vbom
0,0 → 1,9
# libs
../vlib/slvtypes.vhd
../vlib/memlib/memlib.vhd
iblib.vhd
# components
[sim]../vlib/memlib/ram_1swar_gen.vbom
[xst,vsyn]../vlib/memlib/ram_1swar_gen_unisim.vbom
# design
ibdr_rl11.vhd
/ib_intmap.vhd
0,0 → 1,139
-- $Id: ib_intmap.vhd 641 2015-02-01 22:12:15Z mueller $
--
-- Copyright 2006-2011 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: ib_intmap - syn
-- Description: pdp11: external interrupt mapper
--
-- Dependencies: -
-- Test bench: tb/tb_pdp11_core (implicit)
-- Target Devices: generic
-- Tool versions: ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31
-- Revision History:
-- Date Rev Version Comment
-- 2011-11-18 427 1.2.2 now numeric_std clean
-- 2008-08-22 161 1.2.1 renamed pdp11_ -> ib_; use iblib
-- 2008-01-20 112 1.2 add INTMAP generic to externalize config
-- 2008-01-06 111 1.1 add EI_ACK output lines, remove EI_LINE
-- 2007-10-12 88 1.0.2 avoid ieee.std_logic_unsigned, use cast to unsigned
-- 2007-06-14 56 1.0.1 Use slvtypes.all
-- 2007-05-12 26 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
use work.iblib.all;
 
-- ----------------------------------------------------------------------------
 
entity ib_intmap is -- external interrupt mapper
generic (
INTMAP : intmap_array_type := intmap_array_init);
port (
EI_REQ : in slv16_1; -- interrupt request lines
EI_ACKM : in slbit; -- interrupt acknowledge (from master)
EI_ACK : out slv16_1; -- interrupt acknowledge (to requestor)
EI_PRI : out slv3; -- interrupt priority
EI_VECT : out slv9_2 -- interrupt vector
);
end ib_intmap;
 
architecture syn of ib_intmap is
 
signal EI_LINE : slv4 := (others=>'0'); -- external interrupt line
 
type intp_type is array (15 downto 0) of slv3;
type intv_type is array (15 downto 0) of slv9;
 
constant conf_intp : intp_type :=
(slv(to_unsigned(INTMAP(15).pri,3)), -- line 15
slv(to_unsigned(INTMAP(14).pri,3)), -- line 14
slv(to_unsigned(INTMAP(13).pri,3)), -- line 13
slv(to_unsigned(INTMAP(12).pri,3)), -- line 12
slv(to_unsigned(INTMAP(11).pri,3)), -- line 11
slv(to_unsigned(INTMAP(10).pri,3)), -- line 10
slv(to_unsigned(INTMAP( 9).pri,3)), -- line 9
slv(to_unsigned(INTMAP( 8).pri,3)), -- line 8
slv(to_unsigned(INTMAP( 7).pri,3)), -- line 7
slv(to_unsigned(INTMAP( 6).pri,3)), -- line 6
slv(to_unsigned(INTMAP( 5).pri,3)), -- line 5
slv(to_unsigned(INTMAP( 4).pri,3)), -- line 4
slv(to_unsigned(INTMAP( 3).pri,3)), -- line 3
slv(to_unsigned(INTMAP( 2).pri,3)), -- line 2
slv(to_unsigned(INTMAP( 1).pri,3)), -- line 1
slv(to_unsigned( 0,3)) -- line 0 (always 0 !!)
);
 
constant conf_intv : intv_type :=
(slv(to_unsigned(INTMAP(15).vec,9)), -- line 15
slv(to_unsigned(INTMAP(14).vec,9)), -- line 14
slv(to_unsigned(INTMAP(13).vec,9)), -- line 13
slv(to_unsigned(INTMAP(12).vec,9)), -- line 12
slv(to_unsigned(INTMAP(11).vec,9)), -- line 11
slv(to_unsigned(INTMAP(10).vec,9)), -- line 10
slv(to_unsigned(INTMAP( 9).vec,9)), -- line 9
slv(to_unsigned(INTMAP( 8).vec,9)), -- line 8
slv(to_unsigned(INTMAP( 7).vec,9)), -- line 7
slv(to_unsigned(INTMAP( 6).vec,9)), -- line 6
slv(to_unsigned(INTMAP( 5).vec,9)), -- line 5
slv(to_unsigned(INTMAP( 4).vec,9)), -- line 4
slv(to_unsigned(INTMAP( 3).vec,9)), -- line 3
slv(to_unsigned(INTMAP( 2).vec,9)), -- line 2
slv(to_unsigned(INTMAP( 1).vec,9)), -- line 1
slv(to_unsigned( 0,9)) -- line 0 (always 0 !!)
);
 
-- attribute PRIORITY_EXTRACT : string;
-- attribute PRIORITY_EXTRACT of EI_LINE : signal is "force";
begin
 
EI_LINE <= "1111" when EI_REQ(15)='1' else
"1110" when EI_REQ(14)='1' else
"1101" when EI_REQ(13)='1' else
"1100" when EI_REQ(12)='1' else
"1011" when EI_REQ(11)='1' else
"1010" when EI_REQ(10)='1' else
"1001" when EI_REQ( 9)='1' else
"1000" when EI_REQ( 8)='1' else
"0111" when EI_REQ( 7)='1' else
"0110" when EI_REQ( 6)='1' else
"0101" when EI_REQ( 5)='1' else
"0100" when EI_REQ( 4)='1' else
"0011" when EI_REQ( 3)='1' else
"0010" when EI_REQ( 2)='1' else
"0001" when EI_REQ( 1)='1' else
"0000";
 
proc_intmap : process (EI_LINE, EI_ACKM)
variable iline : integer := 0;
variable iei_ack : slv16 := (others=>'0');
begin
 
iline := to_integer(unsigned(EI_LINE));
 
iei_ack := (others=>'0');
if EI_ACKM = '1' then
iei_ack(iline) := '1';
end if;
 
EI_ACK <= iei_ack(EI_ACK'range);
EI_PRI <= conf_intp(iline);
EI_VECT <= conf_intv(iline)(8 downto 2);
end process proc_intmap;
end syn;
/ibdr_sdreg.vhd
0,0 → 1,147
-- $Id: ibdr_sdreg.vhd 641 2015-02-01 22:12:15Z mueller $
--
-- Copyright 2007-2011 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_sdreg - syn
-- Description: ibus dev(rem): Switch/Display register
--
-- Dependencies: -
-- Test bench: -
-- Target Devices: generic
-- Tool versions: ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2010-10-17 333 12.1 M53d xc3s1000-4 34 40 0 30 s 4.0
-- 2009-07-11 232 10.1.03 K39 xc3s1000-4 32 39 0 29 s 2.5
--
-- Revision History:
-- Date Rev Version Comment
-- 2011-11-18 427 1.2.1 now numeric_std clean
-- 2010-10-17 333 1.2 use ibus V2 interface
-- 2010-06-11 303 1.1 use IB_MREQ.racc instead of RRI_REQ
-- 2008-08-22 161 1.0.4 use iblib
-- 2008-04-18 136 1.0.3 use RESET. Switch/Display not cleared by console
-- reset or reset instruction, only by cpu_reset
-- 2008-01-20 112 1.0.2 use BRESET
-- 2008-01-05 110 1.0.1 rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy)
-- reorganize code, all in state_type/proc_next
-- 2007-12-31 108 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
use work.iblib.all;
 
-- ----------------------------------------------------------------------------
entity ibdr_sdreg is -- ibus dev(rem): Switch/Display regs
-- fixed address: 177570
port (
CLK : in slbit; -- clock
RESET : in slbit; -- reset
IB_MREQ : in ib_mreq_type; -- ibus request
IB_SRES : out ib_sres_type; -- ibus response
DISPREG : out slv16 -- display register
);
end ibdr_sdreg;
 
architecture syn of ibdr_sdreg is
 
constant ibaddr_sdreg : slv16 := slv(to_unsigned(8#177570#,16));
 
type regs_type is record -- state registers
ibsel : slbit; -- ibus select
sreg : slv16; -- switch register
dreg : slv16; -- display register
end record regs_type;
 
constant regs_init : regs_type := (
'0', -- ibsel
(others=>'0'), -- sreg
(others=>'0') -- dreg
);
 
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
if RESET = '1' then
R_REGS <= regs_init;
else
R_REGS <= N_REGS;
end if;
end if;
end process proc_regs;
 
proc_next : process (R_REGS, IB_MREQ)
variable r : regs_type := regs_init;
variable n : regs_type := regs_init;
variable idout : slv16 := (others=>'0');
variable ibreq : slbit := '0';
begin
 
r := R_REGS;
n := R_REGS;
 
idout := (others=>'0');
ibreq := IB_MREQ.re or IB_MREQ.we;
 
-- ibus address decoder
n.ibsel := '0';
if IB_MREQ.aval='1' and
IB_MREQ.addr=ibaddr_sdreg(12 downto 1) then
n.ibsel := '1';
end if;
 
-- ibus output driver
if r.ibsel = '1' then
if IB_MREQ.racc = '0' then
idout := r.sreg; -- cpu will read switch register
else
idout := r.dreg; -- rri will read display register
end if;
end if;
 
-- ibus write transactions
if r.ibsel='1' and IB_MREQ.we='1' then
if IB_MREQ.racc = '0' then -- cpu will write display register
if IB_MREQ.be1 = '1' then
n.dreg(ibf_byte1) := IB_MREQ.din(ibf_byte1);
end if;
if IB_MREQ.be0 = '1' then
n.dreg(ibf_byte0) := IB_MREQ.din(ibf_byte0);
end if;
else -- rri will write switch register
n.sreg := IB_MREQ.din; -- byte write not supported
end if;
end if;
N_REGS <= n;
 
IB_SRES.dout <= idout;
IB_SRES.ack <= r.ibsel and ibreq;
IB_SRES.busy <= '0';
DISPREG <= r.dreg;
 
end process proc_next;
 
end syn;
/ib_sres_or_3.vbom
0,0 → 1,7
# libs
../vlib/slvtypes.vhd
iblib.vhd
# components
[sim]ib_sres_or_mon.vbom
# design
ib_sres_or_3.vhd
/ib_sel.vhd
0,0 → 1,69
-- $Id: ib_sel.vhd 641 2015-02-01 22:12:15Z mueller $
--
-- Copyright 2010- 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: ib_sel - syn
-- Description: ibus: address select logic
--
-- Dependencies: -
-- Test bench: tb/tb_pdp11_core (implicit)
-- Target Devices: generic
-- Tool versions: ise 12.1-14.7; viv 2014.4; ghdl 0.29-0.31
--
-- Revision History:
-- Date Rev Version Comment
-- 2010-10-23 335 1.0 Initial version (derived from rritb_sres_or_mon)
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
use work.slvtypes.all;
use work.iblib.all;
 
-- ----------------------------------------------------------------------------
 
entity ib_sel is -- ibus address select logic
generic (
IB_ADDR : slv16; -- ibus address base
SAWIDTH : natural := 0); -- device subaddress space width
port (
CLK : in slbit; -- clock
IB_MREQ : in ib_mreq_type; -- ibus request
SEL : out slbit -- select state bit
);
end ib_sel;
 
architecture syn of ib_sel is
signal R_SEL : slbit := '0';
begin
 
assert SAWIDTH<=10 -- at most 1k words devices
report "assert(SAWIDTH<=10)" severity failure;
proc_regs: process (CLK)
variable isel : slbit := '0';
begin
if rising_edge(CLK) then
isel := '0';
if IB_MREQ.aval='1' and
IB_MREQ.addr(12 downto SAWIDTH+1)=IB_ADDR(12 downto SAWIDTH+1) then
isel := '1';
end if;
R_SEL <= isel;
end if;
end process proc_regs;
 
SEL <= R_SEL;
end syn;
/ib_sel.vbom
0,0 → 1,6
# libs
../vlib/slvtypes.vhd
iblib.vhd
# components
# design
ib_sel.vhd
/ib_sres_or_mon.vbom
0,0 → 1,5
# libs
../vlib/slvtypes.vhd
iblib.vhd
# design
ib_sres_or_mon.vhd
/ibdr_lp11.vbom
0,0 → 1,5
# libs
../vlib/slvtypes.vhd
iblib.vhd
# design
ibdr_lp11.vhd
/ibd_kw11l.vbom
0,0 → 1,5
# libs
../vlib/slvtypes.vhd
iblib.vhd
# design
ibd_kw11l.vhd
/ibd_iist.vbom
0,0 → 1,6
# libs
../vlib/slvtypes.vhd
iblib.vhd
ibdlib.vhd
# design
ibd_iist.vhd
/ibdr_minisys.vbom
0,0 → 1,13
# libs
../vlib/slvtypes.vhd
iblib.vhd
ibdlib.vhd
# components
ibdr_sdreg.vbom
ibd_kw11l.vbom
ibdr_dl11.vbom
ibdr_rk11.vbom
ib_sres_or_4.vbom
ib_intmap.vbom
# design
ibdr_minisys.vhd
/ibdr_dl11.vbom
0,0 → 1,5
# libs
../vlib/slvtypes.vhd
iblib.vhd
# design
ibdr_dl11.vhd
/ib_intmap.vbom
0,0 → 1,5
# libs
../vlib/slvtypes.vhd
iblib.vhd
# design
ib_intmap.vhd
/ibdr_sdreg.vbom
0,0 → 1,5
# libs
../vlib/slvtypes.vhd
iblib.vhd
# design
ibdr_sdreg.vhd
/ibdr_pc11.vbom
0,0 → 1,5
# libs
../vlib/slvtypes.vhd
iblib.vhd
# design
ibdr_pc11.vhd
/.
. Property changes : Added: svn:ignore ## -0,0 +1,33 ## +*.dep_ghdl +*.dep_isim +*.dep_xst +work-obj93.cf +*.vcd +*.ghw +*.sav +*.tmp +*.exe +ise +xflow.his +*.ngc +*.ncd +*.pcf +*.bit +*.msk +isim +isim.log +isim.wdb +fuse.log +*_[sft]sim.vhd +*_tsim.sdf +*_xst.log +*_tra.log +*_twr.log +*_map.log +*_par.log +*_tsi.log +*_pad.log +*_bgn.log +*_svn.log +*_sum.log +*_[dsft]sim.log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.