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