From d14626ce29397dd83bd26589ed30a8e22ae2c62b Mon Sep 17 00:00:00 2001 From: "Walter F.J. Mueller" Date: Sun, 23 Apr 2017 18:13:52 +0200 Subject: [PATCH] dmcmon: new interface, proper wait handling, vivado friendly - dmcmon has now the sta,sto,sus,res logic as rbmon and ibmon - dmcmon does not depend on full state number generation anymore - dmcmon missed WAIT instructions so far, has been fixed - related changes: - pdp11_sequencer can now return a simple instruction type based snum - sys_w11a_n4 includes dmcmon again (now independent of dmscnt!) --- rtl/sys_gen/w11a/nexys4/sys_conf.vhd | 7 +- rtl/sys_gen/w11a/nexys4/sys_w11a_n4.vmfset | 8 +- rtl/sys_gen/w11a/nexys4/tb/sys_conf_sim.vhd | 7 +- rtl/w11a/pdp11.vhd | 21 +- rtl/w11a/pdp11_dmcmon.vhd | 129 ++++++++---- rtl/w11a/pdp11_sequencer.vhd | 217 ++++++++++++++++++-- rtl/w11a/pdp11_sys70.vhd | 9 +- tools/tbench/w11a_cmon/test_cmon_imon.tcl | 18 +- tools/tbench/w11a_cmon/test_cmon_logs.tcl | 12 +- tools/tbench/w11a_cmon/test_cmon_regs.tcl | 132 +++++++----- tools/tcl/ibd_ibmon/util.tcl | 7 +- tools/tcl/rbmoni/util.tcl | 3 +- tools/tcl/rw11/dmcmon.tcl | 119 ++++++++--- tools/tcl/rw11/shell.tcl | 44 +--- 14 files changed, 518 insertions(+), 215 deletions(-) diff --git a/rtl/sys_gen/w11a/nexys4/sys_conf.vhd b/rtl/sys_gen/w11a/nexys4/sys_conf.vhd index 26d45070..457b7f7e 100644 --- a/rtl/sys_gen/w11a/nexys4/sys_conf.vhd +++ b/rtl/sys_gen/w11a/nexys4/sys_conf.vhd @@ -1,4 +1,4 @@ --- $Id: sys_conf.vhd 858 2017-03-05 17:41:37Z mueller $ +-- $Id: sys_conf.vhd 884 2017-04-22 16:35:42Z mueller $ -- -- Copyright 2013-2017 by Walter F.J. Mueller -- @@ -16,9 +16,10 @@ -- Description: Definitions for sys_w11a_n4 (for synthesis) -- -- Dependencies: - --- Tool versions: ise 14.5-14.7; viv 2014.4-2016.4; ghdl 0.29-0.33 +-- Tool versions: ise 14.5-14.7; viv 2014.4-2017.1; ghdl 0.29-0.34 -- Revision History: -- Date Rev Version Comment +-- 2017-04-22 884 1.5.3 re-enable dmcmon -- 2017-03-04 858 1.5.2 enable deuna -- 2017-01-29 847 1.5.1 add sys_conf_ibd_deuna -- 2016-07-16 788 1.5 use cram_*delay functions to determine delays @@ -67,7 +68,7 @@ package sys_conf is constant sys_conf_ibmon_awidth : integer := 9; -- use 0 to disable constant sys_conf_dmscnt : boolean := false; constant sys_conf_dmhbpt_nunit : integer := 2; -- use 0 to disable - constant sys_conf_dmcmon_awidth : integer := 0; -- use 0 to disable, 9 to use + constant sys_conf_dmcmon_awidth : integer := 8; -- use 0 to disable, 8 to use constant sys_conf_rbd_sysmon : boolean := true; -- SYSMON(XADC) -- configure w11 cpu core -------------------------------------------------- diff --git a/rtl/sys_gen/w11a/nexys4/sys_w11a_n4.vmfset b/rtl/sys_gen/w11a/nexys4/sys_w11a_n4.vmfset index 8696945c..9ca0deb7 100644 --- a/rtl/sys_gen/w11a/nexys4/sys_w11a_n4.vmfset +++ b/rtl/sys_gen/w11a/nexys4/sys_w11a_n4.vmfset @@ -1,14 +1,10 @@ -# $Id: sys_w11a_n4.vmfset 774 2016-06-12 17:08:47Z mueller $ +# $Id: sys_w11a_n4.vmfset 885 2017-04-23 15:54:01Z mueller $ # # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ [syn] # false_path -hold ignored by synth ---------------------------- I [Designutils 20-1567] -# net without driver ------------------------------------------- -# --> snum currently disabled # OK 2016-05-28 -i [Synth 8-3848] DM_STAT_SE[snum].*pdp11_sequencer - # port driven by constant -------------------------------------- # --> RGBLED0 currently unused # OK 2016-05-28 i [Synth 8-3917] O_RGBLED0[\d] @@ -42,6 +38,8 @@ i [Synth 8-3332] SEQ/R_IDSTAT_reg[res_sel][2] # --> monitor outputs moneop,monattn currently not used # OK 2016-05-28 i [Synth 8-3332] RLINK/CORE/RL/R_LREGS_reg[moneop] i [Synth 8-3332] RLINK/CORE/RL/R_LREGS_reg[monattn] +# --> scnt disabled, thus 3 SNUM bits '0' # OK 2017-04-22 +i [Synth 8-3332] R_REGS_reg[se_snum][(4|5|6)] # INFO: encoded FSM with state register as -------------------- # test for sys_w11a_n4 that all FSMs are one_hot diff --git a/rtl/sys_gen/w11a/nexys4/tb/sys_conf_sim.vhd b/rtl/sys_gen/w11a/nexys4/tb/sys_conf_sim.vhd index 49844045..3987ddba 100644 --- a/rtl/sys_gen/w11a/nexys4/tb/sys_conf_sim.vhd +++ b/rtl/sys_gen/w11a/nexys4/tb/sys_conf_sim.vhd @@ -1,4 +1,4 @@ --- $Id: sys_conf_sim.vhd 847 2017-01-29 22:38:42Z mueller $ +-- $Id: sys_conf_sim.vhd 884 2017-04-22 16:35:42Z mueller $ -- -- Copyright 2013-2017 by Walter F.J. Mueller -- @@ -16,9 +16,10 @@ -- Description: Definitions for sys_w11a_n4 (for simulation) -- -- Dependencies: - --- Tool versions: xst 14.5-14.7; viv 2016.1-2016.4; ghdl 0.29-0.33 +-- Tool versions: xst 14.5-14.7; viv 2016.1-2017.1; ghdl 0.29-0.34 -- Revision History: -- Date Rev Version Comment +-- 2017-04-22 884 1.5.2 re-enable dmcmon -- 2017-01-29 847 1.5.1 add sys_conf_ibd_deuna -- 2016-07-16 788 1.5 use cram_*delay functions to determine delays -- 2016-06-18 775 1.4.5 use PLL for clkser_gentype @@ -66,7 +67,7 @@ package sys_conf is constant sys_conf_ibmon_awidth : integer := 9; -- use 0 to disable constant sys_conf_dmscnt : boolean := false; constant sys_conf_dmhbpt_nunit : integer := 2; -- use 0 to disable - constant sys_conf_dmcmon_awidth : integer := 0; -- use 0 to disable, 9 to use + constant sys_conf_dmcmon_awidth : integer := 8; -- use 0 to disable, 8 to use constant sys_conf_rbd_sysmon : boolean := true; -- SYSMON(XADC) -- configure w11 cpu core -------------------------------------------------- diff --git a/rtl/w11a/pdp11.vhd b/rtl/w11a/pdp11.vhd index 57270e21..e7704b87 100644 --- a/rtl/w11a/pdp11.vhd +++ b/rtl/w11a/pdp11.vhd @@ -1,6 +1,6 @@ --- $Id: pdp11.vhd 829 2016-12-26 18:56:17Z mueller $ +-- $Id: pdp11.vhd 884 2017-04-22 16:35:42Z mueller $ -- --- Copyright 2006-2016 by Walter F.J. Mueller +-- Copyright 2006-2017 by Walter F.J. Mueller -- -- 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 @@ -16,10 +16,11 @@ -- Description: Definitions for pdp11 components -- -- Dependencies: - --- Tool versions: ise 8.2-14.7; viv 2016.2; ghdl 0.18-0.33 +-- Tool versions: ise 8.2-14.7; viv 2016.2-2017.1; ghdl 0.18-0.34 -- -- Revision History: -- Date Rev Version Comment +-- 2017-04-22 884 1.6.7 dm_stat_se: add idle; pdp11_dmcmon: add SNUM generic -- 2016-12-26 829 1.6.6 BUGFIX: psw init with pri=0, as on real 11/70 -- 2015-11-01 712 1.6.5 define sbcntl_sbf_tmu := 12; use for pdp11_tmu_sb -- 2015-07-19 702 1.6.4 change DM_STAT_(DP|CO); add DM_STAT_SE @@ -603,6 +604,7 @@ package pdp11 is -- debug and monitoring port definitions ------------------------------------- type dm_stat_se_type is record -- debug and monitor status - sequencer + idle : slbit; -- sequencer ideling istart : slbit; -- instruction start idone : slbit; -- instruction done vfetch : slbit; -- vector fetch @@ -610,10 +612,16 @@ package pdp11 is end record dm_stat_se_type; constant dm_stat_se_init : dm_stat_se_type := ( - '0','0','0', -- istart,idone,vfetch + '0','0','0','0', -- idle,istart,idone,vfetch (others=>'0') -- snum ); - + + constant c_snum_f_con: integer := 0; -- control state flag + constant c_snum_f_ins: integer := 1; -- instruction state flag + constant c_snum_f_vec: integer := 2; -- vector state flag + constant c_snum_f_err: integer := 3; -- error state flag + constant c_snum_f_vmw: integer := 7; -- vm wait flag + type dm_stat_dp_type is record -- debug and monitor status - dpath pc : slv16; -- pc psw : psw_type; -- psw @@ -1302,7 +1310,8 @@ end component; component pdp11_dmcmon is -- debug&moni: cpu monitor generic ( RB_ADDR : slv16 := slv(to_unsigned(16#0048#,16)); - AWIDTH : natural := 8); + AWIDTH : natural := 8; + SNUM : boolean := false); port ( CLK : in slbit; -- clock RESET : in slbit; -- reset diff --git a/rtl/w11a/pdp11_dmcmon.vhd b/rtl/w11a/pdp11_dmcmon.vhd index 98bbb037..c4d200cb 100644 --- a/rtl/w11a/pdp11_dmcmon.vhd +++ b/rtl/w11a/pdp11_dmcmon.vhd @@ -1,6 +1,6 @@ --- $Id: pdp11_dmcmon.vhd 709 2015-08-06 18:08:49Z mueller $ +-- $Id: pdp11_dmcmon.vhd 885 2017-04-23 15:54:01Z mueller $ -- --- Copyright 2015- by Walter F.J. Mueller +-- Copyright 2015-2017 by Walter F.J. Mueller -- -- 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 @@ -20,7 +20,7 @@ -- Test bench: - -- -- Target Devices: generic --- Tool versions: ise 14.7; viv 2014.4; ghdl 0.31 +-- Tool versions: ise 14.7; viv 2014.4-2017.1; ghdl 0.31-0.34 -- -- Synthesized (xst): -- Date Rev ise Target flop lutl lutm slic t peri @@ -28,6 +28,7 @@ -- -- Revision History: - -- Date Rev Version Comment +-- 2017-04-22 884 2.0 use DM_STAT_SE.idle; revised interface, add suspend -- 2015-08-03 709 1.0 Initial version -- 2015-07-05 697 0.1 First draft ------------------------------------------------------------------------------ @@ -36,15 +37,22 @@ -- -- Addr Bits Name r/w/f Function -- 000 cntl r/w/f Control register --- 04 mwsup r/w/- mem wait suppress (used when start=1) --- 03 imode r/w/- instruction mode (used when start=1) --- 02 wena r/w/- wrap enabled (") --- 01 stop r/w/f writing 1 stops moni --- 00 start r/w/f writing 1 starts moni and clears addr +-- 05 mwsup r/w/- mem wait suppress +-- 04 imode r/w/- instruction mode +-- 03 wstop r/w/- stop on wrap +-- 02:00 func 0/-/f change run status if != noop +-- 0xx noop +-- 100 sto stop +-- 101 sta start and latch all options +-- 110 sus suspend (noop if not started) +-- 111 res resume (noop if not started) -- 001 stat r/-/- Status register -- 15:13 bsize r/-/- buffer size (AWIDTH-8) -- 12:09 malcnt r/-/- valid entries in memory access log --- 00 wrap r/-/- line address wrapped (cleared on go) +-- 08 snum r/-/- snum support +-- 02 wrap r/-/- line address wrapped (cleared on start) +-- 01 susp r/-/- suspended +-- 00 run r/-/- running (can be suspended) -- 010 addr r/w/- Address register (writable when stopped) -- *:04 laddr r/w/- line address -- 03:00 waddr r/w/- word address (0000 to 1000) @@ -133,7 +141,8 @@ use work.pdp11.all; entity pdp11_dmcmon is -- debug&moni: cpu monitor generic ( RB_ADDR : slv16 := slv(to_unsigned(16#0048#,16)); - AWIDTH : natural := 8); + AWIDTH : natural := 8; + SNUM : boolean := false); port ( CLK : in slbit; -- clock RESET : in slbit; -- reset @@ -158,14 +167,18 @@ architecture syn of pdp11_dmcmon is constant rbaddr_ireg : slv3 := "110"; -- ireg address offset constant rbaddr_imal : slv3 := "111"; -- imal address offset - constant cntl_rbf_mwsup : integer := 4; - constant cntl_rbf_imode : integer := 3; - constant cntl_rbf_wena : integer := 2; - constant cntl_rbf_stop : integer := 1; - constant cntl_rbf_start : integer := 0; + constant cntl_rbf_mwsup : integer := 5; + constant cntl_rbf_imode : integer := 4; + constant cntl_rbf_wstop : integer := 3; + subtype cntl_rbf_func is integer range 2 downto 0; + subtype stat_rbf_bsize is integer range 15 downto 13; - subtype stat_rbf_malcnt is integer range 12 downto 09; - constant stat_rbf_wrap : integer := 0; + subtype stat_rbf_malcnt is integer range 12 downto 9; + constant stat_rbf_snum : integer := 8; + constant stat_rbf_wrap : integer := 2; + constant stat_rbf_susp : integer := 1; + constant stat_rbf_run : integer := 0; + subtype addr_rbf_laddr is integer range 4+AWIDTH-1 downto 4; subtype addr_rbf_waddr is integer range 3 downto 0; @@ -226,6 +239,11 @@ architecture syn of pdp11_dmcmon is constant dat5_ibf_tflag : integer := 4; subtype dat5_ibf_cc is integer range 3 downto 0; + constant func_sto : slv3 := "100"; -- func: stop + constant func_sta : slv3 := "101"; -- func: start + constant func_sus : slv3 := "110"; -- func: suspend + constant func_res : slv3 := "111"; -- func: resume + constant laddrzero : slv(AWIDTH-1 downto 0) := (others=>'0'); constant laddrlast : slv(AWIDTH-1 downto 0) := (others=>'1'); @@ -233,8 +251,9 @@ architecture syn of pdp11_dmcmon is rbsel : slbit; -- rbus select mwsup : slbit; -- mwsup flag (mem wait suppress) imode : slbit; -- imode flag - wena : slbit; -- wena flag (wrap enable) - go : slbit; -- go flag + wstop : slbit; -- wstop flag (stop on wrap) + susp : slbit; -- suspended flag + go : slbit; -- go flag (actively running) active : slbit; -- active flag wrap : slbit; -- laddr wrap flag laddr : slv(AWIDTH-1 downto 0); -- line address @@ -277,6 +296,7 @@ architecture syn of pdp11_dmcmon is vm_trap_ysv : slbit; -- vm.vmstat.trap_ysv vm_trap_mmu : slbit; -- vm.vmstat.trap_mmu vm_pend : slbit; -- vm req pending + se_idle : slbit; -- se.idle se_istart : slbit; -- se.istart se_istart_1 : slbit; -- se.istart last cycle se_idone : slbit; -- se.idone @@ -286,8 +306,8 @@ architecture syn of pdp11_dmcmon is end record regs_type; constant regs_init : regs_type := ( '0', -- rbsel - '0','1', -- mwsup,imode - '1','1','0', -- wena,go,active + '0','1','0', -- mwsup,imode,wstop + '0','1','0', -- susp,go,active '0', -- wrap laddrzero, -- laddr "0000", -- waddr @@ -311,7 +331,8 @@ architecture syn of pdp11_dmcmon is '0','0','0','0','0', -- vm_err_* '0','0', -- vm_trap_* '0', -- vm_pend - '0','0','0','0', -- se_istart(_1),se_idone,se_vfetch + '0','0','0', -- se_idle,se_istart(_1) + '0','0', -- se_idone,se_vfetch (others=>'0'), -- se_snum '0' -- mwdrop ); @@ -467,20 +488,31 @@ architecture syn of pdp11_dmcmon is if r.rbsel = '1' then irb_ack := irbena; -- ack all accesses case RB_MREQ.addr(2 downto 0) is - when rbaddr_cntl => -- cntl ------------------ + when rbaddr_cntl => -- cntl ------------------ if RB_MREQ.we = '1' then - if RB_MREQ.din(cntl_rbf_start) = '1' then - n.mwsup := RB_MREQ.din(cntl_rbf_mwsup); - n.imode := RB_MREQ.din(cntl_rbf_imode); - n.wena := RB_MREQ.din(cntl_rbf_wena); - n.go := '1'; - n.wrap := '0'; - n.laddr := laddrzero; - n.waddr := "0000"; - end if; - if RB_MREQ.din(cntl_rbf_stop) = '1' then - n.go := '0'; - end if; + case RB_MREQ.din(cntl_rbf_func) is + when func_sto => -- func: stop ------------ + n.go := '0'; + n.susp := '0'; + when func_sta => -- func: start ----------- + n.mwsup := RB_MREQ.din(cntl_rbf_mwsup); + n.imode := RB_MREQ.din(cntl_rbf_imode); + n.wstop := RB_MREQ.din(cntl_rbf_wstop); + n.go := '1'; + n.susp := '0'; + n.wrap := '0'; + n.laddr := laddrzero; + n.waddr := "0000"; + when func_sus => -- func: susp ------------ + if r.go = '1' then -- noop unless running + n.go := '0'; + n.susp := r.go; + end if; + when func_res => -- func: resu ------------ + n.go := r.susp; + n.susp := '0'; + when others => null; -- <> -------------------- + end case; end if; when rbaddr_stat => -- stat ------------------ @@ -488,18 +520,21 @@ architecture syn of pdp11_dmcmon is when rbaddr_addr => -- addr ------------------ if RB_MREQ.we = '1' then - if r.go='0' then + if r.go = '0' then -- if not active OK n.laddr := RB_MREQ.din(addr_rbf_laddr); n.waddr := RB_MREQ.din(addr_rbf_waddr); else - irb_err := '1'; -- error + irb_err := '1'; -- otherwise error end if; end if; when rbaddr_data => -- data ------------------ - if r.go='1' or RB_MREQ.we='1' then + -- write to data is an error + if RB_MREQ.we='1' then irb_err := '1'; -- error - elsif RB_MREQ.re = '1' then + end if; + -- read to data always allowed, addr only incremented when not active + if RB_MREQ.re = '1' and r.go = '0' then if r.waddr(3) = '1' then -- equivalent waddr>=1000 n.waddr := (others=>'0'); laddr_inc := '1'; @@ -532,13 +567,17 @@ architecture syn of pdp11_dmcmon is when rbaddr_cntl => -- cntl ------------------ irb_dout(cntl_rbf_mwsup) := r.mwsup; irb_dout(cntl_rbf_imode) := r.imode; - irb_dout(cntl_rbf_wena) := r.wena; - irb_dout(cntl_rbf_start) := r.go; + irb_dout(cntl_rbf_wstop) := r.wstop; when rbaddr_stat => -- stat ------------------ irb_dout(stat_rbf_bsize) := slv(to_unsigned(AWIDTH-8,3)); irb_dout(stat_rbf_malcnt) := r.mal_waddr; + if SNUM then + irb_dout(stat_rbf_snum) := '1'; + end if; irb_dout(stat_rbf_wrap) := r.wrap; + irb_dout(stat_rbf_susp) := r.susp; -- started and suspended + irb_dout(stat_rbf_run) := r.go or r.susp; -- started when rbaddr_addr => -- addr ------------------ irb_dout(addr_rbf_laddr) := r.laddr; @@ -637,6 +676,7 @@ architecture syn of pdp11_dmcmon is end if; n.se_istart_1 := r.se_istart; + n.se_idle := DM_STAT_SE.idle; n.se_istart := DM_STAT_SE.istart; n.se_idone := DM_STAT_SE.idone; n.se_vfetch := DM_STAT_SE.vfetch; @@ -654,7 +694,7 @@ architecture syn of pdp11_dmcmon is end if; iactive := r.active; - if unsigned(r.se_snum) = 0 then -- in idle state + if r.se_idle = '1' then -- in idle state if igoeff = '0' then -- if goeff=0 stop running n.active := '0'; end if; @@ -694,9 +734,8 @@ architecture syn of pdp11_dmcmon is 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.wrap := '1'; + if r.wstop = '1' then n.go := '0'; end if; end if; diff --git a/rtl/w11a/pdp11_sequencer.vhd b/rtl/w11a/pdp11_sequencer.vhd index 4afdad76..e4d2c3e7 100644 --- a/rtl/w11a/pdp11_sequencer.vhd +++ b/rtl/w11a/pdp11_sequencer.vhd @@ -1,6 +1,6 @@ --- $Id: pdp11_sequencer.vhd 831 2016-12-27 16:51:12Z mueller $ +-- $Id: pdp11_sequencer.vhd 885 2017-04-23 15:54:01Z mueller $ -- --- Copyright 2006-2016 by Walter F.J. Mueller +-- Copyright 2006-2017 by Walter F.J. Mueller -- -- 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 @@ -18,10 +18,12 @@ -- Dependencies: ib_sel -- Test bench: tb/tb_pdp11_core (implicit) -- Target Devices: generic --- Tool versions: ise 8.2-14.7; viv 2014.4-2016.2; ghdl 0.18-0.33 +-- Tool versions: ise 8.2-14.7; viv 2014.4-2017.1; ghdl 0.18-0.34 -- -- Revision History: -- Date Rev Version Comment +-- 2017-04-23 885 1.6.9 not sys_conf_dmscnt: set SNUM from state category; +-- change waitsusp logic; add WAIT to idm_idone -- 2016-12-27 831 1.6.8 CPUERR now cleared with creset -- 2016-10-03 812 1.6.7 always define DM_STAT_SE.snum -- 2016-05-26 768 1.6.6 don't init N_REGS (vivado fix for fsm inference) @@ -270,6 +272,8 @@ architecture syn of pdp11_sequencer is signal R_VMSTAT : vm_stat_type := vm_stat_init; signal IBSEL_CPUERR : slbit := '0'; + + signal VM_CNTL_L : vm_cntl_type := vm_cntl_init; begin @@ -365,6 +369,7 @@ begin variable int_pending : slbit := '0'; -- an interrupt is pending + variable idm_idle : slbit := '0'; -- idle for dm_stat_se variable idm_idone : slbit := '0'; -- idone for dm_stat_se variable idm_vfetch : slbit := '0'; -- vfetch for dm_stat_se @@ -614,6 +619,7 @@ begin int_pending := '1'; end if; + idm_idle := '0'; idm_idone := '0'; idm_vfetch := '0'; @@ -705,15 +711,15 @@ begin case R_STATE is -- idle and command port states --------------------------------------------- - - -- Note: s_idle was entered from suspended WAIT when waitsusp='1' - -- --> all exits must check this and either return to s_op_wait - -- or abort the WAIT and set waitsusp='0' when s_idle => + -- Note: s_idle was entered from suspended WAIT when waitsusp='1' + -- --> all exits must check this and either return to s_op_wait + -- or abort the WAIT and set waitsusp='0' ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST (do mux early) nstatus.cpustep := '0'; + idm_idle := '1'; -- signal sequencer idle if R_STATUS.cmdbusy = '1' then case R_STATUS.cpfunc is @@ -835,8 +841,7 @@ begin end case; elsif R_STATUS.waitsusp = '1' then - nstatus.waitsusp := '0'; - nstate := s_op_wait; + nstate := s_op_wait; --waitsusp is cleared in s_op_wait elsif R_STATUS.cpugo = '1' and -- running R_STATUS.cpususp='0' then -- and not suspended @@ -1557,10 +1562,22 @@ begin end if; when s_op_wait => -- WAIT + -- Note: wait is the only interruptable instruction. The CPU spins + -- in s_op_wait until an interrupt or a control command is seen. + -- In case of a control command R_STATUS.waitsusp is set and + -- control transfered to s_idle. If the control command returns + -- to s_op_wait, waitsusp is cleared here. This ensures that the + -- idm_idone logic (for dmcmon) sees only one WAIT even if it is + -- interrupted by control commands. ndpcntl.gpr_asrc := "000"; -- load R0 in DSRC for DR emulation ndpcntl.dsrc_sel := c_dpath_dsrc_src; - ndpcntl.dsrc_we := '1'; - + ndpcntl.dsrc_we := '1'; + nstatus.waitsusp := '0'; -- in case of returning from s_idle + + -- signal idone in the first cycle of a WAIT instruction to dmcmon + -- ensures that a WAIT is logged once and only once + idm_idone := not (R_STATUS.waitsusp or R_STATUS.cpuwait); + nstate := s_op_wait; -- spin here if is_kmode = '0' then -- but act as nop if not in kernel nstate := s_idle; @@ -2384,13 +2401,15 @@ begin ESUSP_O <= R_STATUS.suspint; -- FIXME_code: handle masking later ITIMER <= R_STATUS.itimer; - DP_CNTL <= ndpcntl; - VM_CNTL <= nvmcntl; + DP_CNTL <= ndpcntl; + VM_CNTL <= nvmcntl; + VM_CNTL_L <= nvmcntl; nmmumoni.regnum := ndpcntl.gpr_adst; nmmumoni.delta := ndpcntl.ounit_const(3 downto 0); MMU_MONI <= nmmumoni; + DM_STAT_SE.idle <= idm_idle; DM_STAT_SE.istart <= nmmumoni.istart; DM_STAT_SE.idone <= idm_idone; DM_STAT_SE.vfetch <= idm_vfetch; @@ -2413,8 +2432,8 @@ begin CP_STAT.suspext <= R_STATUS.suspext; end process proc_cpstat; - -- state number creation logic is conditional, only done when monitor - -- enabled. Due to sythnesis impact in vivado + -- SNUM creation logic is conditional due to synthesis impact in vivado. + -- SNUM = 'full state number' only available when dmscnt unit enabled. SNUM1 : if sys_conf_dmscnt generate begin proc_snum : process (R_STATE) @@ -2556,9 +2575,175 @@ begin end process proc_snum; end generate SNUM1; + -- if dmscnt not enable setup SNUM based on state categories (currently 4) + -- and a 'wait' indicator determined from monitoring VM_CNTL and VM_STAT SNUM0 : if not sys_conf_dmscnt generate + signal R_VMWAIT : slbit := '0'; -- vmwait flag begin - DM_STAT_SE.snum <= (others=>'0'); + + proc_vmwait: process (CLK) + begin + if rising_edge(CLK) then + if GRESET = '1' then + R_VMWAIT <= '0'; + else + if VM_CNTL_L.req = '1' then + R_VMWAIT <= '1'; + elsif VM_STAT.ack = '1' or VM_STAT.err = '1' or VM_STAT.fail='1' then + R_VMWAIT <= '0'; + end if; + end if; + end if; + end process proc_vmwait; + + proc_snum : process (R_STATE, R_VMWAIT) + variable isnum_con : slbit := '0'; + variable isnum_ins : slbit := '0'; + variable isnum_vec : slbit := '0'; + variable isnum_err : slbit := '0'; + begin + isnum_con := '0'; + isnum_ins := '0'; + isnum_vec := '0'; + isnum_err := '0'; + case R_STATE is + when s_idle => null; + when s_cp_regread => isnum_con := '1'; + when s_cp_rps => isnum_con := '1'; + when s_cp_memr_w => isnum_con := '1'; + when s_cp_memw_w => isnum_con := '1'; + when s_ifetch => isnum_ins := '1'; + when s_ifetch_w => isnum_ins := '1'; + when s_idecode => isnum_ins := '1'; + + when s_srcr_def => isnum_ins := '1'; + when s_srcr_def_w => isnum_ins := '1'; + when s_srcr_inc => isnum_ins := '1'; + when s_srcr_inc_w => isnum_ins := '1'; + when s_srcr_dec => isnum_ins := '1'; + when s_srcr_dec1 => isnum_ins := '1'; + when s_srcr_ind => isnum_ins := '1'; + when s_srcr_ind1_w => isnum_ins := '1'; + when s_srcr_ind2 => isnum_ins := '1'; + when s_srcr_ind2_w => isnum_ins := '1'; + + when s_dstr_def => isnum_ins := '1'; + when s_dstr_def_w => isnum_ins := '1'; + when s_dstr_inc => isnum_ins := '1'; + when s_dstr_inc_w => isnum_ins := '1'; + when s_dstr_dec => isnum_ins := '1'; + when s_dstr_dec1 => isnum_ins := '1'; + when s_dstr_ind => isnum_ins := '1'; + when s_dstr_ind1_w => isnum_ins := '1'; + when s_dstr_ind2 => isnum_ins := '1'; + when s_dstr_ind2_w => isnum_ins := '1'; + + when s_dstw_def => isnum_ins := '1'; + when s_dstw_def_w => isnum_ins := '1'; + when s_dstw_inc => isnum_ins := '1'; + when s_dstw_inc_w => isnum_ins := '1'; + when s_dstw_incdef_w => isnum_ins := '1'; + when s_dstw_dec => isnum_ins := '1'; + when s_dstw_dec1 => isnum_ins := '1'; + when s_dstw_ind => isnum_ins := '1'; + when s_dstw_ind_w => isnum_ins := '1'; + when s_dstw_def246 => isnum_ins := '1'; + + when s_dsta_inc => isnum_ins := '1'; + when s_dsta_incdef_w => isnum_ins := '1'; + when s_dsta_dec => isnum_ins := '1'; + when s_dsta_dec1 => isnum_ins := '1'; + when s_dsta_ind => isnum_ins := '1'; + when s_dsta_ind_w => isnum_ins := '1'; + + when s_op_halt => isnum_ins := '1'; + when s_op_wait => isnum_ins := '1'; + when s_op_trap => isnum_ins := '1'; + when s_op_reset => isnum_ins := '1'; + when s_op_rts => isnum_ins := '1'; + when s_op_rts_pop => isnum_ins := '1'; + when s_op_rts_pop_w => isnum_ins := '1'; + when s_op_spl => isnum_ins := '1'; + when s_op_mcc => isnum_ins := '1'; + when s_op_br => isnum_ins := '1'; + when s_op_mark => isnum_ins := '1'; + when s_op_mark1 => isnum_ins := '1'; + when s_op_mark_pop => isnum_ins := '1'; + when s_op_mark_pop_w => isnum_ins := '1'; + when s_op_sob => isnum_ins := '1'; + when s_op_sob1 => isnum_ins := '1'; + + when s_opg_gen => isnum_ins := '1'; + when s_opg_gen_rmw_w => isnum_ins := '1'; + when s_opg_mul => isnum_ins := '1'; + when s_opg_mul1 => isnum_ins := '1'; + when s_opg_div => isnum_ins := '1'; + when s_opg_div_cn => isnum_ins := '1'; + when s_opg_div_cr => isnum_ins := '1'; + when s_opg_div_sq => isnum_ins := '1'; + when s_opg_div_sr => isnum_ins := '1'; + when s_opg_div_quit => isnum_ins := '1'; + when s_opg_ash => isnum_ins := '1'; + when s_opg_ash_cn => isnum_ins := '1'; + when s_opg_ashc => isnum_ins := '1'; + when s_opg_ashc_cn => isnum_ins := '1'; + when s_opg_ashc_wl => isnum_ins := '1'; + + when s_opa_jsr => isnum_ins := '1'; + when s_opa_jsr1 => isnum_ins := '1'; + when s_opa_jsr_push => isnum_ins := '1'; + when s_opa_jsr_push_w => isnum_ins := '1'; + when s_opa_jsr2 => isnum_ins := '1'; + when s_opa_jmp => isnum_ins := '1'; + when s_opa_mtp => isnum_ins := '1'; + when s_opa_mtp_pop_w => isnum_ins := '1'; + when s_opa_mtp_reg => isnum_ins := '1'; + when s_opa_mtp_mem => isnum_ins := '1'; + when s_opa_mtp_mem_w => isnum_ins := '1'; + when s_opa_mfp_reg => isnum_ins := '1'; + when s_opa_mfp_mem => isnum_ins := '1'; + when s_opa_mfp_mem_w => isnum_ins := '1'; + when s_opa_mfp_dec => isnum_ins := '1'; + when s_opa_mfp_push => isnum_ins := '1'; + when s_opa_mfp_push_w => isnum_ins := '1'; + + when s_trap_4 => isnum_ins := '1'; + when s_trap_10 => isnum_ins := '1'; + when s_trap_disp => isnum_ins := '1'; + + when s_int_ext => isnum_vec := '1'; + + when s_int_getpc => isnum_vec := '1'; + when s_int_getpc_w => isnum_vec := '1'; + when s_int_getps => isnum_vec := '1'; + when s_int_getps_w => isnum_vec := '1'; + when s_int_getsp => isnum_vec := '1'; + when s_int_decsp => isnum_vec := '1'; + when s_int_pushps => isnum_vec := '1'; + when s_int_pushps_w => isnum_vec := '1'; + when s_int_pushpc => isnum_vec := '1'; + when s_int_pushpc_w => isnum_vec := '1'; + + when s_rti_getpc => isnum_vec := '1'; + when s_rti_getpc_w => isnum_vec := '1'; + when s_rti_getps => isnum_vec := '1'; + when s_rti_getps_w => isnum_vec := '1'; + when s_rti_newpc => isnum_vec := '1'; + + when s_vmerr => isnum_err := '1'; + when s_cpufail => isnum_err := '1'; + + when others => null; + end case; + + DM_STAT_SE.snum <= (others=>'0'); + DM_STAT_SE.snum(c_snum_f_con) <= isnum_con; + DM_STAT_SE.snum(c_snum_f_ins) <= isnum_ins; + DM_STAT_SE.snum(c_snum_f_vec) <= isnum_vec; + DM_STAT_SE.snum(c_snum_f_err) <= isnum_err; + DM_STAT_SE.snum(c_snum_f_vmw) <= R_VMWAIT; + + end process proc_snum; end generate SNUM0; end syn; diff --git a/rtl/w11a/pdp11_sys70.vhd b/rtl/w11a/pdp11_sys70.vhd index 44ad58aa..2deda316 100644 --- a/rtl/w11a/pdp11_sys70.vhd +++ b/rtl/w11a/pdp11_sys70.vhd @@ -1,6 +1,6 @@ --- $Id: pdp11_sys70.vhd 750 2016-03-24 23:11:51Z mueller $ +-- $Id: pdp11_sys70.vhd 884 2017-04-22 16:35:42Z mueller $ -- --- Copyright 2015-2016 by Walter F.J. Mueller +-- Copyright 2015-2017 by Walter F.J. Mueller -- -- 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 @@ -31,6 +31,7 @@ -- -- Revision History: -- Date Rev Version Comment +-- 2017-04-22 884 1.2.1 pdp11_dmcmon: use SNUM and AWIDTH generics -- 2016-03-22 750 1.2 pdp11_cache now configurable size -- 2015-11-01 712 1.1.4 use sbcntl_sbf_tmu -- 2015-07-19 702 1.1.3 use DM_STAT_SE @@ -249,7 +250,9 @@ begin begin I0: pdp11_dmcmon generic map ( - RB_ADDR => slv(to_unsigned(16#0048#,16))) + RB_ADDR => slv(to_unsigned(16#0048#,16)), + AWIDTH => sys_conf_dmcmon_awidth, + SNUM => sys_conf_dmscnt) port map ( CLK => CLK, RESET => RESET, diff --git a/tools/tbench/w11a_cmon/test_cmon_imon.tcl b/tools/tbench/w11a_cmon/test_cmon_imon.tcl index 3a06ba0f..c7629fe7 100644 --- a/tools/tbench/w11a_cmon/test_cmon_imon.tcl +++ b/tools/tbench/w11a_cmon/test_cmon_imon.tcl @@ -1,10 +1,11 @@ -# $Id: test_cmon_imon.tcl 830 2016-12-26 20:25:49Z mueller $ +# $Id: test_cmon_imon.tcl 885 2017-04-23 15:54:01Z mueller $ # -# Copyright 2015- by Walter F.J. Mueller +# Copyright 2015-2017 by Walter F.J. Mueller # License disclaimer see License.txt in $RETROBASE directory # # Revision History: # Date Rev Version Comment +# 2017-04-23 885 2.0 adopt to revised interface # 2015-07-18 701 1.0 Initial version # # Test register response @@ -18,8 +19,13 @@ if {[$cpu get hascmon] == 0} { } # reset cmon -$cpu cp -wreg cm.cntl [regbld rw11::CM_CNTL start stop] \ - -rreg cm.cntl -edata 0 +$cpu cp \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "STA"}] \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "STO"}] \ + -rreg cm.cntl -edata 0 + +# remember mask for malcnt +set malcntmsk [regbld rw11::CM_STAT {malcnt -1}] # -- Section A --------------------------------------------------------------- rlc log " A: simple linear code, word access ------------------------" @@ -145,7 +151,7 @@ foreach {ipc mal} $edata { lappend clist -step lappend clist -rreg "cm.ipc" -edata $ipc lappend clist -rreg "cm.stat" \ - -edata [regbldkv rw11::CM_STAT malcnt $malcnt] + -edata [regbldkv rw11::CM_STAT malcnt $malcnt] $malcntmsk if {$malcnt > 0} { lappend clist -rblk "cm.imal" $malcnt -edata $mal } @@ -217,7 +223,7 @@ foreach {ipc data} $edata { lappend clist -step lappend clist -rreg "cm.ipc" -edata $ipc lappend clist -rreg "cm.stat" \ - -edata [regbldkv rw11::CM_STAT malcnt $malcnt] + -edata [regbldkv rw11::CM_STAT malcnt $malcnt] $malcntmsk if {$malcnt > 0} { lappend clist -rblk "cm.imal" $malcnt -edata $data } diff --git a/tools/tbench/w11a_cmon/test_cmon_logs.tcl b/tools/tbench/w11a_cmon/test_cmon_logs.tcl index 8041f600..66a0ded2 100644 --- a/tools/tbench/w11a_cmon/test_cmon_logs.tcl +++ b/tools/tbench/w11a_cmon/test_cmon_logs.tcl @@ -1,10 +1,11 @@ -# $Id: test_cmon_logs.tcl 830 2016-12-26 20:25:49Z mueller $ +# $Id: test_cmon_logs.tcl 885 2017-04-23 15:54:01Z mueller $ # -# Copyright 2015- by Walter F.J. Mueller +# Copyright 2015-2017 by Walter F.J. Mueller # License disclaimer see License.txt in $RETROBASE directory # # Revision History: # Date Rev Version Comment +# 2017-04-23 885 2.0 adopt to revised interface # 2015-08-02 707 1.0 Initial version # # Test cm_print @@ -18,8 +19,11 @@ if {[$cpu get hascmon] == 0} { } # reset cmon -$cpu cp -wreg cm.cntl [regbld rw11::CM_CNTL start stop] \ - -rreg cm.cntl -edata 0 +# reset cmon +$cpu cp \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "STA"}] \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "STO"}] \ + -rreg cm.cntl -edata 0 # define tmpproc for executing tests proc tmpproc_dotest {cpu code tname} { diff --git a/tools/tbench/w11a_cmon/test_cmon_regs.tcl b/tools/tbench/w11a_cmon/test_cmon_regs.tcl index 01bba3ac..51647694 100644 --- a/tools/tbench/w11a_cmon/test_cmon_regs.tcl +++ b/tools/tbench/w11a_cmon/test_cmon_regs.tcl @@ -1,10 +1,11 @@ -# $Id: test_cmon_regs.tcl 830 2016-12-26 20:25:49Z mueller $ +# $Id: test_cmon_regs.tcl 885 2017-04-23 15:54:01Z mueller $ # -# Copyright 2015- by Walter F.J. Mueller +# Copyright 2015-2017 by Walter F.J. Mueller # License disclaimer see License.txt in $RETROBASE directory # # Revision History: # Date Rev Version Comment +# 2017-04-23 885 2.0 adopt to revised interface # 2015-07-18 701 1.0 Initial version # # Test register response @@ -20,55 +21,93 @@ if {[$cpu get hascmon] == 0} { # -- Section A --------------------------------------------------------------- rlc log " A basic register access tests -----------------------------" -rlc log " A1: test cntl --------------------------------------" -# reset cmon -$cpu cp -wreg cm.cntl [regbld rw11::CM_CNTL start stop] \ - -rreg cm.cntl -edata 0 +rlc log " A1: write/read cntl---------------------------------" +# test that starting caputes option flags, and that stoping keeps them +$cpu cp \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "STA"}] \ + -rreg cm.cntl -edata [regbld rw11::CM_CNTL] \ + -wreg cm.cntl [regbld rw11::CM_CNTL wstop {func "STA"}] \ + -rreg cm.cntl -edata [regbld rw11::CM_CNTL wstop] \ + -wreg cm.cntl [regbld rw11::CM_CNTL imode {func "STA"}] \ + -rreg cm.cntl -edata [regbld rw11::CM_CNTL imode] \ + -wreg cm.cntl [regbld rw11::CM_CNTL mwsup {func "STA"}] \ + -rreg cm.cntl -edata [regbld rw11::CM_CNTL mwsup] \ + -wreg cm.cntl [regbld rw11::CM_CNTL wstop mwsup {func "STA"}] \ + -rreg cm.cntl -edata [regbld rw11::CM_CNTL wstop mwsup] \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "STO"}] \ + -rreg cm.cntl -edata [regbld rw11::CM_CNTL wstop mwsup] -# test imode, wena bits (set only when start=1) - $cpu cp -wreg cm.cntl [regbld rw11::CM_CNTL start] \ - -rreg cm.cntl -edata [regbld rw11::CM_CNTL start] \ - -wreg cm.cntl [regbld rw11::CM_CNTL wena start] \ - -rreg cm.cntl -edata [regbld rw11::CM_CNTL wena start] \ - -wreg cm.cntl [regbld rw11::CM_CNTL imode wena start] \ - -rreg cm.cntl -edata [regbld rw11::CM_CNTL imode wena start] -# test imode, wena bits (kept when start=0) - $cpu cp -wreg cm.cntl [regbld rw11::CM_CNTL stop] \ - -rreg cm.cntl -edata [regbld rw11::CM_CNTL imode wena] \ - -wreg cm.cntl [regbld rw11::CM_CNTL start stop] \ - -rreg cm.cntl -edata 0 \ - -wreg cm.cntl [regbld rw11::CM_CNTL imode] \ - -rreg cm.cntl -edata 0 \ - -wreg cm.cntl [regbld rw11::CM_CNTL wena] \ - -rreg cm.cntl -edata 0 +rlc log " A2: write cntl, read stat --------------------------" +# test that susp/run follow functions set to cntl +set statmsk [regbld rw11::CM_STAT wrap susp run] +$cpu cp \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "STA"}] \ + -rreg cm.stat -edata [regbld rw11::CM_STAT run] $statmsk \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "SUS"}] \ + -rreg cm.stat -edata [regbld rw11::CM_STAT susp run] $statmsk \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "RES"}] \ + -rreg cm.stat -edata [regbld rw11::CM_STAT run] $statmsk \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "STO"}] \ + -rreg cm.stat -edata [regbld rw11::CM_STAT] $statmsk +# test that suspend/resume of a stopped system is a noop +$cpu cp \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "SUS"}] \ + -rreg cm.stat -edata [regbld rw11::CM_STAT] $statmsk \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "RES"}] \ + -rreg cm.stat -edata [regbld rw11::CM_STAT] $statmsk +# test that start of a suspended system clears suspend +$cpu cp \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "STA"}] \ + -rreg cm.stat -edata [regbld rw11::CM_STAT run] $statmsk \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "SUS"}] \ + -rreg cm.stat -edata [regbld rw11::CM_STAT susp run] $statmsk \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "STA"}] \ + -rreg cm.stat -edata [regbld rw11::CM_STAT run] $statmsk +# test that suspend of a suspended system is a noop +# test that stop of a suspended system clears suspend +$cpu cp \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "STA"}] \ + -rreg cm.stat -edata [regbld rw11::CM_STAT run] $statmsk \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "SUS"}] \ + -rreg cm.stat -edata [regbld rw11::CM_STAT susp run] $statmsk \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "SUS"}] \ + -rreg cm.stat -edata [regbld rw11::CM_STAT susp run] $statmsk \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "STO"}] \ + -rreg cm.stat -edata [regbld rw11::CM_STAT] $statmsk +# get amax for later usage +$cpu cp \ + -rreg cm.stat rstat +set bsize [regget rbmoni::STAT(bsize) $rstat] +set amax [expr {( 256 << $bsize ) - 1}] -# start cmon -$cpu cp -wreg cm.cntl [regbld rw11::CM_CNTL start] \ - -rreg cm.cntl -edata [regbld rw11::CM_CNTL start] +rlc log " A3: test addr --------------------------------------" +rlc log " A3.1: write/read addr when stopped -----------------" +foreach {laddr waddr} [list 0x0000 0 0x0000 7 $amax 0 $amax 8] { + set addr [regbld rw11::CM_ADDR [list laddr $laddr] [list waddr $waddr]] + $cpu cp \ + -wreg cm.addr $addr \ + -rreg cm.addr -edata $addr +} -rlc log " A2: test stat --------------------------------------" -# is read only -$cpu cp -rreg cm.stat \ - -wreg cm.stat 0 -estaterr +rlc log " A3.2: verify that starting clears addr -------------" +$cpu cp \ + -wreg cm.cntl [regbldkv rw11::CM_CNTL func "STO"] \ + -wreg cm.addr [regbldkv rw11::CM_ADDR laddr $amax] \ + -rreg cm.addr -edata [regbldkv rw11::CM_ADDR laddr $amax] \ + -wreg cm.cntl [regbldkv rw11::CM_CNTL func "STA"] \ + -rreg cm.addr -edata 0x00 \ + -wreg cm.cntl [regbldkv rw11::CM_CNTL func "STO"] -rlc log " A3: test addr ---------------------------------------" -rlc log " A3.1: when stopped ----------------------------------" -# start will clear addr -$cpu cp -wreg cm.cntl [regbld rw11::CM_CNTL stop] \ - -rreg cm.cntl -edata 0 \ - -wreg cm.addr [regbld rw11::CM_ADDR {laddr 017} {waddr 03}] \ - -rreg cm.addr -edata [regbld rw11::CM_ADDR {laddr 017} {waddr 03}] \ - -wreg cm.cntl [regbld rw11::CM_CNTL start] \ - -rreg cm.cntl -edata [regbld rw11::CM_CNTL start] \ - -rreg cm.addr -edata [regbld rw11::CM_ADDR {laddr 0} {waddr 0}] -rlc log " A3.2: test err when started and written ------------" -$cpu cp -wreg cm.cntl [regbld rw11::CM_CNTL start] \ - -wreg cm.addr 0x1234 -estaterr +rlc log " A3.3: test err when started and addr written -------" +$cpu cp \ + -wreg cm.cntl [regbldkv rw11::CM_CNTL func "STA"] \ + -wreg cm.addr 0x100 -estaterr \ + -wreg cm.cntl [regbldkv rw11::CM_CNTL func "STO"] rlc log " A4: test data --------------------------------------" rlc log " A4.1: when stopped ---------------------------------" # stop, set addr, and nine times data, check addr -$cpu cp -wreg cm.cntl [regbld rw11::CM_CNTL stop] \ +$cpu cp -wreg cm.cntl [regbld rw11::CM_CNTL {func "STO"}] \ -wreg cm.addr [regbld rw11::CM_ADDR {laddr 010} {waddr 0}] \ -rreg cm.data \ -rreg cm.addr -edata [regbld rw11::CM_ADDR {laddr 010} {waddr 001}] \ @@ -90,11 +129,8 @@ $cpu cp -rreg cm.data \ -rreg cm.data \ -rreg cm.addr -edata [regbld rw11::CM_ADDR {laddr 011} {waddr 000}] -rlc log " A4.2: test err when started or written -------------" -$cpu cp -wreg cm.cntl [regbld rw11::CM_CNTL start] \ - -rreg cm.data -estaterr \ - -wreg cm.cntl [regbld rw11::CM_CNTL stop] \ - -wreg cm.data 0 -estaterr +rlc log " A4.2: test err when written ------------------------" +$cpu cp -wreg cm.data 0x100 -estaterr rlc log " A5: test imon section; readable, not writable ------" $cpu cp -rreg cm.iaddr \ diff --git a/tools/tcl/ibd_ibmon/util.tcl b/tools/tcl/ibd_ibmon/util.tcl index 54e46461..d679db04 100644 --- a/tools/tcl/ibd_ibmon/util.tcl +++ b/tools/tcl/ibd_ibmon/util.tcl @@ -1,4 +1,4 @@ -# $Id: util.tcl 883 2017-04-22 11:57:38Z mueller $ +# $Id: util.tcl 885 2017-04-23 15:54:01Z mueller $ # # Copyright 2015-2017 by Walter F.J. Mueller # @@ -76,7 +76,7 @@ namespace eval ibd_ibmon { -wibr im.addr 0x0000 } # - # start: setup filter window ----------------------------------------------- + # filter: setup filter window ---------------------------------------------- # proc filter {{cpu "cpu0"} {lolim 0160000} {hilim 0177776}} { if {$lolim < 0160000 || $hilim < 0160000} { @@ -148,7 +148,6 @@ namespace eval ibd_ibmon { if {[regget ibd_ibmon::STAT(wrap) $rstat]} { set nval $nmax } if {$nent > $nval} {set nent $nval} - if {$nent == 0} { return {} } # if wstop set use first nent items, otherwise last nent items set caddr 0 @@ -208,7 +207,7 @@ namespace eval ibd_ibmon { # restore address and resume # resume only if not already suspended before - set rfu [expr {[regget ibd_ibmon::::STAT(susp) $rstatpre] ? "NOOP" : "RES"}] + set rfu [expr {[regget ibd_ibmon::STAT(susp) $rstatpre] ? "NOOP" : "RES"}] $cpu cp -wibr im.addr $raddr \ -wibr im.cntl [regbldkv ibd_ibmon::CNTL func $rfu] diff --git a/tools/tcl/rbmoni/util.tcl b/tools/tcl/rbmoni/util.tcl index c90be6ed..7f0fd209 100644 --- a/tools/tcl/rbmoni/util.tcl +++ b/tools/tcl/rbmoni/util.tcl @@ -1,4 +1,4 @@ -# $Id: util.tcl 883 2017-04-22 11:57:38Z mueller $ +# $Id: util.tcl 885 2017-04-23 15:54:01Z mueller $ # # Copyright 2011-2017 by Walter F.J. Mueller # @@ -130,7 +130,6 @@ namespace eval rbmoni { if {[regget rbmoni::STAT(wrap) $rstat]} { set nval $nmax } if {$nent > $nval} {set nent $nval} - if {$nent == 0} { return {} } # if wstop set use first nent items, otherwise last nent items set caddr 0 diff --git a/tools/tcl/rw11/dmcmon.tcl b/tools/tcl/rw11/dmcmon.tcl index d060bb4f..04fe8bb5 100644 --- a/tools/tcl/rw11/dmcmon.tcl +++ b/tools/tcl/rw11/dmcmon.tcl @@ -1,4 +1,4 @@ -# $Id: dmcmon.tcl 837 2017-01-02 19:23:34Z mueller $ +# $Id: dmcmon.tcl 885 2017-04-23 15:54:01Z mueller $ # # Copyright 2015-2017 by Walter F.J. Mueller # @@ -13,6 +13,7 @@ # # Revision History: # Date Rev Version Comment +# 2017-04-23 885 2.0 revised interface, add suspend # 2017-01-02 837 1.0.2 add procs cme,cml # 2016-12-29 833 1.0.1 cm_print: protect against empty lists # 2015-08-05 708 1.0 Initial version @@ -28,11 +29,14 @@ namespace eval rw11 { # # setup dmcmon unit register descriptions for w11a ------------------------- # - regdsc CM_CNTL {mwsup 4} {imode 3} {wena 2} {stop 1} {start 0} - regdsc CM_STAT {bsize 15 3} {malcnt 12 4} {wrap 0} + regdsc CM_CNTL {mwsup 5} {imode 4} {wstop 3} \ + {func 2 3 "s:NOOP:NOOP1:NOOP2:NOOP3:STO:STA:SUS:RES"} + regdsc CM_STAT {bsize 15 3} {malcnt 12 4} {snum 8} {wrap 2} {susp 1} {run 0} regdsc CM_ADDR {laddr 15 12} {waddr 3 4} regdsc CM_IADDR {laddr 15 12} + regdsc CM_FSNUM {vmw 7} {err 3} {vec 2} {ins 1} {con 0} + regdsc CM_D8 {xnum 7 8} {req 15} {istart 9} {idone 8} regdsc CM_D8REQ {wacc 14} {macc 13} {cacc 12} {bytop 11} {dspace 10} regdsc CM_D8ACK {ack 14} {err 13} {tysv 12} {tmmu 11} {mwdrop 10} @@ -56,17 +60,36 @@ namespace eval rw11 { # cm_start: start the dmcmon ----------------------------------------------- # proc cm_start {{cpu "cpu0"} args} { - args2opts opts { mwsup 0 imode 0 wena 1 } {*}$args - $cpu cp -wreg cm.cntl [regbldkv rw11::CM_CNTL start 1 \ - mwsup $opts(mwsup) imode $opts(imode) \ - wena $opts(wena) ] + args2opts opts { mwsup 0 imode 0 wstop 0 } {*}$args + $cpu cp -wreg cm.cntl [regbldkv rw11::CM_CNTL func "STA" \ + mwsup $opts(mwsup) \ + imode $opts(imode) \ + wstop $opts(wstop) ] } # # cm_stop: stop the dmcmon ------------------------------------------------- # proc cm_stop {{cpu "cpu0"}} { - $cpu cp -wreg cm.cntl [regbld rw11::CM_CNTL stop] + $cpu cp -wreg cm.cntl [regbld rw11::CM_CNTL {func "STO"}] + } + + # + # suspend: suspend the dmcmon ---------------------------------------------- + # returns 1 if already suspended + # that allows to implement nested suspend/resume properly + # + proc cm_susp {{cpu "cpu0"}} { + $cpu cp -rreg cm.stat rstat \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "SUS"}] + return [regget rw11::CM_STAT(susp) $rstat] + } + + # + # resume: resume the dmcmon ------------------------------------------------ + # + proc cm_resu {{cpu "cpu0"}} { + $cpu cp -wreg cm.cntl [regbld rw11::CM_CNTL {func "RES"}] } # @@ -74,22 +97,31 @@ namespace eval rw11 { # returns a list, 1st entry descriptor, rest 9-tuples in d0,..,d8 order # proc cm_read {{cpu "cpu0"} {nent -1}} { - $cpu cp -rreg cm.cntl rcntl \ - -rreg cm.stat rstat \ - -rreg cm.addr raddr + # suspend and get address and status + $cpu cp -rreg cm.stat rstatpre \ + -wreg cm.cntl [regbld rw11::CM_CNTL {func "SUS"}] \ + -rreg cm.cntl rcntl \ + -rreg cm.addr raddr \ + -rreg cm.stat rstat set bsize [regget rw11::CM_STAT(bsize) $rstat] set amax [expr {( 256 << $bsize ) - 1}] - if {$nent == -1} { set nent $amax } + set nmax [expr { $amax + 1 } ] + if {$nent == -1} { set nent $nmax } + if {$nent > $nmax} { set nent $nmax } + # determine number of available items (check wrap flag) set laddr [regget rw11::CM_ADDR(laddr) $raddr] set nval $laddr - if {[regget rw11::CM_STAT(wrap) $rstat]} { set nval $amax } + if {[regget rw11::CM_STAT(wrap) $rstat]} { set nval $nmax } if {$nent > $nval} {set nent $nval} - if {$nent == 0} { return {} } - set caddr [expr {( $laddr - $nent ) & $amax}] + # if wstop set use first nent items, otherwise last nent items + set caddr 0 + if {![regget rw11::CM_CNTL(wstop) $rcntl]} { + set caddr [expr {( $laddr - $nent ) & $amax}] + } $cpu cp -wreg cm.addr [regbld rw11::CM_ADDR [list laddr $caddr]] set rval {} @@ -110,7 +142,11 @@ namespace eval rw11 { set nrest [expr {$nrest - $nget }] } - $cpu cp -wreg cm.addr $raddr + # restore address and resume + # resume only if not already suspended before + set rfu [expr {[regget rw11::CM_STAT(susp) $rstatpre] ? "NOOP" : "RES"}] + $cpu cp -wreg cm.addr $raddr \ + -wreg cm.cntl [regbldkv rw11::CM_CNTL func $rfu] return $rval } @@ -119,12 +155,22 @@ namespace eval rw11 { # cm_print: convert raw into human readable format ------------------------- # proc cm_print {cmraw} { - if {![llength $cmraw]} {return;} - set imode [regget rw11::CM_CNTL(imode) [lindex $cmraw 0 0]] + if {[llength $cmraw] <= 1} {return;} + set rcntl [lindex $cmraw 0 0]; # get im.cntl + set rstat [lindex $cmraw 0 1]; # get im.stat + set imode [regget rw11::CM_CNTL(imode) $rcntl] + set rsnum [regget rw11::CM_STAT(snum) $rstat] set rval {} set line {} - if { $imode} {append line " nc"} - if {!$imode} {append line "state "} + if {$imode} { + append line " nc" + } else { + if {$rsnum} { + append line "state " + } else { + append line "c WS" + } + } if {$imode} { append line " ....pc" @@ -209,8 +255,19 @@ namespace eval rw11 { if {$first} {set ccnt 0} append line [format %3d $ccnt] } else { - set snam [lindex $snum2state $d8_xnum] - append line [format %-14s $snam] + if {$rsnum} { + set snam [lindex $snum2state $d8_xnum] + append line [format %-14s $snam] + } else { + set snumcat "-" + if {[regget rw11::CM_FSNUM(con) $d8_xnum]} {set snumcat "c"} + if {[regget rw11::CM_FSNUM(ins) $d8_xnum]} {set snumcat "i"} + if {[regget rw11::CM_FSNUM(vec) $d8_xnum]} {set snumcat "v"} + if {[regget rw11::CM_FSNUM(err) $d8_xnum]} {set snumcat "e"} + set snumvmw " " + if {[regget rw11::CM_FSNUM(vmw) $d8_xnum]} {set snumvmw "W"} + append line "$snumcat $snumvmw " + } } if {$imode} { @@ -467,17 +524,18 @@ namespace eval rw11 { # # cme: dmcmon enable ------------------------------------------------------- # - proc cme {{cpu "cpu0"} {mode "i"}} { - if {![regexp {^[is]?n?$} $mode]} { - error "cme-E: bad mode '$mode', only i,s and n allowed" + proc cme {{cpu "cpu0"} {mode ""}} { + if {![regexp {^n?[isS]?$} $mode]} { + error "cme-E: bad mode '$mode', only n plus [isS] allowed" } - set imode [string match *i* $mode] - set mwsup [string match *s* $mode] - set wena 1 - if {[string match *n* $mode]} {set wena 0} + set wstop [string match *n* $mode] + set imode 1 + set mwsup 0 + if {[string match *s* $mode]} {set imode 0; set mwsup 1} + if {[string match *S* $mode]} {set imode 0; set mwsup 0} - rw11::cm_start $cpu imode $imode mwsup $mwsup wena $wena + rw11::cm_start $cpu imode $imode mwsup $mwsup wstop $wstop return "" } @@ -485,7 +543,6 @@ namespace eval rw11 { # cml: dmcmon list --------------------------------------------------------- # proc cml {{cpu "cpu0"} {nent -1}} { - rw11::cm_stop $cpu return [rw11::cm_print [rw11::cm_read $cpu $nent]] } diff --git a/tools/tcl/rw11/shell.tcl b/tools/tcl/rw11/shell.tcl index f5c55b96..a0978701 100644 --- a/tools/tcl/rw11/shell.tcl +++ b/tools/tcl/rw11/shell.tcl @@ -1,4 +1,4 @@ -# $Id: shell.tcl 883 2017-04-22 11:57:38Z mueller $ +# $Id: shell.tcl 885 2017-04-23 15:54:01Z mueller $ # # Copyright 2015-2017 by Walter F.J. Mueller # @@ -13,6 +13,7 @@ # # Revision History: # Date Rev Version Comment +# 2017-04-23 885 2.2.4 adopt .cm* to new interface # 2017-04-22 883 2.2.3 integrate rbmon: add .rme,.rmd,.rmf,.rml # 2017-04-16 879 2.2.2 rename .cres->.crst and .cr->.cres (more intuitive) # 2017-04-09 872 2.2.1 adopt .ime to new interface @@ -35,8 +36,6 @@ namespace eval rw11 { variable shell_depth 0; # recursion stopper variable shell_cpu "cpu0"; # current cpu command variable shell_cpu_stat ""; # cpu status - variable shell_cme_pend 1; # .cme pending - variable shell_cme_mode "i"; # mode for pending .cme variable shell_attnhdl_added 0 variable shell_eofchar_save {puts {}} @@ -243,8 +242,6 @@ namespace eval rw11 { proc shell_cs {{nstep 1}} { variable shell_cpu - shell_cme_ifpend - set rval {} for {set i 0} {$i < $nstep} {incr i} { rw11::hb_clear $shell_cpu @@ -265,7 +262,6 @@ namespace eval rw11 { variable shell_cpu variable shell_cpu_stat - shell_cme_ifpend set shell_cpu_stat "g:"; rw11::hb_clear $shell_cpu @@ -311,7 +307,6 @@ namespace eval rw11 { variable shell_cpu variable shell_cpu_stat - shell_cme_ifpend set shell_cpu_stat "g:"; if {$pc == -1} { @@ -322,37 +317,14 @@ namespace eval rw11 { return "" } - # - # shell_cme_ifpend: do cme if pending and cmon available ------------------- - # - proc shell_cme_ifpend {} { - variable shell_cpu - variable shell_cme_pend - variable shell_cme_mode - - if {$shell_cme_pend} { - if {[$shell_cpu rmap -testname "cm.cntl"]} { - shell_cme $shell_cme_mode - } else { - set shell_cme_pend 0 - } - } - return ""; - } - # # shell_cme: cmon enable --------------------------------------------------- # - proc shell_cme {{mode "i"}} { + proc shell_cme {{mode ""}} { variable shell_cpu - variable shell_cme_pend - variable shell_cme_mode if {![shell_test_cpurmap $shell_cpu "cme" "cm.cntl" "dmcmon"]} {return ""} - rw11::cme $shell_cpu $mode - set shell_cme_pend 0 - set shell_cme_mode $mode return "" } @@ -361,11 +333,8 @@ namespace eval rw11 { # proc shell_cmd {} { variable shell_cpu - variable shell_cme_pend if {![shell_test_cpurmap $shell_cpu "cmd" "cm.cntl" "dmcmon"]} {return ""} - - set shell_cme_pend 0 rw11::cm_stop $shell_cpu return "" } @@ -375,10 +344,7 @@ namespace eval rw11 { # proc shell_cml {{nent -1}} { variable shell_cpu - variable shell_cme_pend - if {![shell_test_cpurmap $shell_cpu "cml" "cm.cntl" "dmcmon"]} {return ""} - - set shell_cme_pend 1 + if {![shell_test_cpurmap $shell_cpu "cml" "cm.cntl" "dmcmon"]} {return ""} return [rw11::cml $shell_cpu $nent] } @@ -607,7 +573,7 @@ namespace eval rw11 { append rval "\n .bl ; list bpt" if {[$shell_cpu get hascmon]} { append rval "\nCPU monitor:" - append rval "\n .cme ?mode? ; cmon enable; mode:\[is\]?n?" + append rval "\n .cme ?mode? ; cmon enable; mode:n?\[isS\]?" append rval "\n .cmd ; cmon disable" append rval "\n .cml ?nent? ; cmon list" }