w11 - vhd 0.794
W11 CPU core and support modules
Loading...
Searching...
No Matches
pdp11_dmscnt.vhd
Go to the documentation of this file.
1-- $Id: pdp11_dmscnt.vhd 1181 2019-07-08 17:00:50Z mueller $
2-- SPDX-License-Identifier: GPL-3.0-or-later
3-- Copyright 2015-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4--
5------------------------------------------------------------------------------
6-- Module Name: pdp11_dmscnt - syn
7-- Description: pdp11: debug&moni: state counter
8--
9-- Dependencies: memlib/ram_2swsr_rfirst_gen
10-- Test bench: -
11--
12-- Target Devices: generic
13-- Tool versions: ise 14.7; viv 2014.4-2019.1; ghdl 0.31-0.35
14--
15-- Synthesized (xst):
16-- Date Rev ise Target flop lutl lutm slic t peri
17-- 2015-06-26 695 14.7 131013 xc6slx16-2 91 107 0 41 s 5.4
18--
19-- Revision History: -
20-- Date Rev Version Comment
21-- 2019-06-02 1159 1.1.2 use rbaddr_ constants
22-- 2016-05-22 767 1.1.1 don't init N_REGS (vivado fix for fsm inference)
23-- 2015-12-28 721 1.1 use laddr/waddr; use ena instead of cnt;
24-- 2015-07-19 702 1.0 Initial version
25-- 2015-06-26 695 0.1 First draft
26------------------------------------------------------------------------------
27--
28-- rbus registers:
29--
30-- Addr Bits Name r/w/f Function
31--
32-- 00 cntl r/w/- control
33-- 01 clr r/w/- if 1 starts mem clear
34-- 00 ena r/w/- if 1 enables counting
35-- 01 addr r/w/- memory address
36-- 10:02 laddr r/w/- line address (state number)
37-- 01:00 waddr r/-/- word address (cleared on write)
38-- 10 15:00 data r/-/- memory data
39--
40
41library ieee;
42use ieee.std_logic_1164.all;
43use ieee.numeric_std.all;
44
45use work.slvtypes.all;
46use work.memlib.all;
47use work.rblib.all;
48use work.pdp11.all;
49
50-- ----------------------------------------------------------------------------
51
52entity pdp11_dmscnt is -- debug&moni: state counter
53 generic (
54 RB_ADDR : slv16 := rbaddr_dmscnt_off);
55 port (
56 CLK : in slbit; -- clock
57 RESET : in slbit; -- reset
58 RB_MREQ : in rb_mreq_type; -- rbus: request
59 RB_SRES : out rb_sres_type; -- rbus: response
60 DM_STAT_SE : in dm_stat_se_type; -- debug and monitor status - sequencer
61 DM_STAT_DP : in dm_stat_dp_type; -- debug and monitor status - data path
62 DM_STAT_CO : in dm_stat_co_type -- debug and monitor status - core
63 );
64end pdp11_dmscnt;
65
66
67architecture syn of pdp11_dmscnt is
68
69 constant rbaddr_cntl : slv2 := "00"; -- cntl address offset
70 constant rbaddr_addr : slv2 := "01"; -- addr address offset
71 constant rbaddr_data : slv2 := "10"; -- data address offset
72
73 constant cntl_rbf_clr : integer := 1;
74 constant cntl_rbf_ena : integer := 0;
75 subtype addr_rbf_mem is integer range 10 downto 2;
76 subtype addr_rbf_word is integer range 1 downto 0;
77
78 type state_type is (
79 s_idle, -- s_idle: rbus access or count
80 s_mread -- s_mread: memory read
81 );
82
83 type regs_type is record
84 state : state_type; -- state
85 rbsel : slbit; -- rbus select
86 clr : slbit; -- clr flag
87 ena0 : slbit; -- ena flag
88 ena1 : slbit; -- ena flag (delayed)
89 snum0 : slv9; -- snum stage 0
90 snum1 : slv9; -- snum stage 1
91 same : slbit; -- same snum flag
92 laddr : slv9; -- line addr
93 waddr : slv2; -- word addr
94 scnt : slv(35 downto 0); -- scnt buffer
95 mbuf : slv20; -- lsb memory buffer
96 end record regs_type;
97
98 constant regs_init : regs_type := (
99 s_idle, -- state
100 '0', -- rbsel
101 '0','0','0', -- clr,ena0,ena1
102 (others=>'0'), -- snum0
103 (others=>'0'), -- snum1
104 '0', -- same
105 (others=>'0'), -- laddr
106 (others=>'0'), -- waddr
107 (others=>'0'), -- scnt
108 (others=>'0') -- mbuf
109 );
110
112 signal N_REGS : regs_type; -- don't init (vivado fix for fsm infer)
113
114 signal CMEM_CEA : slbit := '0';
115 signal CMEM_CEB : slbit := '0';
116 signal CMEM_WEA : slbit := '0';
117 signal CMEM_WEB : slbit := '0';
118 signal CMEM_ADDRA : slv9 := (others=>'0');
119 signal CMEM_DIB : slv(35 downto 0) := (others=>'0');
120 signal CMEM_DOA : slv(35 downto 0) := (others=>'0');
121
122 constant cmem_data_zero : slv(35 downto 0) := (others=>'0');
123
124 begin
125
127 generic map (
128 AWIDTH => 9,
129 DWIDTH => 36)
130 port map (
131 CLKA => CLK,
132 CLKB => CLK,
133 ENA => CMEM_CEA,
134 ENB => CMEM_CEB,
135 WEA => CMEM_WEA,
136 WEB => CMEM_WEB,
137 ADDRA => CMEM_ADDRA,
138 ADDRB => R_REGS.snum1,
140 DIB => CMEM_DIB,
141 DOA => CMEM_DOA,
142 DOB => open
143 );
144
145 proc_regs: process (CLK)
146 begin
147
148 if rising_edge(CLK) then
149 if RESET = '1' then
150 R_REGS <= regs_init;
151 else
152 R_REGS <= N_REGS;
153 end if;
154 end if;
155
156 end process proc_regs;
157
158 proc_next: process (R_REGS, RB_MREQ, DM_STAT_SE,
159 DM_STAT_DP, DM_STAT_DP.psw, -- xst needs sub-records
161
162 variable r : regs_type := regs_init;
163 variable n : regs_type := regs_init;
164
165 variable irb_ack : slbit := '0';
166 variable irb_busy : slbit := '0';
167 variable irb_err : slbit := '0';
168 variable irb_dout : slv16 := (others=>'0');
169 variable irbena : slbit := '0';
170
171 variable icea : slbit := '0';
172 variable iwea : slbit := '0';
173 variable iweb : slbit := '0';
174 variable iaddra : slv9 := (others=>'0');
175 variable iscnt0 : slv(35 downto 0) := (others=>'0');
176 variable iscnt1 : slv(35 downto 0) := (others=>'0');
177
178 begin
179
180 r := R_REGS;
181 n := R_REGS;
182
183 irb_ack := '0';
184 irb_busy := '0';
185 irb_err := '0';
186 irb_dout := (others=>'0');
187 irbena := RB_MREQ.re or RB_MREQ.we;
188
189 icea := '0';
190 iwea := '0';
191 iweb := '0';
192 iaddra := r.snum0;
193
194 -- rbus address decoder
195 n.rbsel := '0';
196 if RB_MREQ.aval='1' then
197 if RB_MREQ.addr(15 downto 2)=RB_ADDR(15 downto 2) then
198 n.rbsel := '1';
199 end if;
200 end if;
201
202 case r.state is
203
204 when s_idle => -- s_idle: rbus access or count ------
205 -- rbus transactions
206 if r.rbsel = '1' then
207 irb_ack := irbena; -- ack all accesses
208
209 case RB_MREQ.addr(1 downto 0) is
210
211 when rbaddr_cntl => -- cntl ------------------
212 if RB_MREQ.we = '1' then
213 n.clr := RB_MREQ.din(cntl_rbf_clr);
214 if RB_MREQ.din(cntl_rbf_clr) = '1' then -- if clr set
215 n.laddr := (others=>'0'); -- reset mem addr
216 end if;
217 n.ena0 := RB_MREQ.din(cntl_rbf_ena);
218 end if;
219
220 when rbaddr_addr => -- addr ------------------
221 if RB_MREQ.we = '1' then
222 if r.clr = '1' then -- if clr active
223 irb_err := '1'; -- block addr writes
224 else -- otherwise
225 n.laddr := RB_MREQ.din(addr_rbf_mem); -- set mem addr
226 n.waddr := (others=>'0'); -- clr word addr
227 end if;
228 end if;
229
230 when rbaddr_data => -- data ------------------
231 if RB_MREQ.we = '1' then -- writes not allowed
232 irb_err := '1';
233 end if;
234 if RB_MREQ.re = '1' then
235 if r.clr = '1' then -- if clr active
236 irb_err := '1'; -- block data reads
237 else -- otherwise
238 case r.waddr is -- handle word addr
239 when "00" => -- 1st access
240 icea := '1'; -- enable mem read
241 iaddra := r.laddr; -- of current line
242 irb_busy := '1';
243 n.state := s_mread;
244 when "01" => -- 2nd part
245 n.waddr := "10"; -- inc word addr
246 when "10" => -- 3rd part
247 n.waddr := "00"; -- wrap to next line
248 n.laddr := slv(unsigned(r.laddr) + 1);
249 when others => null;
250 end case;
251 end if;
252 end if;
253
254 when others => -- <> --------------------
255 irb_err := '1';
256 end case;
257 end if;
258
259 when s_mread => --s_mread: memory read ---------------
260 irb_ack := irbena; -- ack access
261 n.waddr := "01"; -- inc word addr
262 n.mbuf := CMEM_DOA(35 downto 16); -- capture msb part
263 n.state := s_idle;
264
265 when others => null;
266
267 end case;
268
269 -- rbus output driver
270 if r.rbsel = '1' then
271 case RB_MREQ.addr(1 downto 0) is
272 when rbaddr_cntl => -- cntl ------------------
273 irb_dout(cntl_rbf_clr) := r.clr;
274 irb_dout(cntl_rbf_ena) := r.ena0;
275 when rbaddr_addr => -- addr ------------------
276 irb_dout(addr_rbf_mem) := r.laddr;
277 irb_dout(addr_rbf_word) := r.waddr;
278 when rbaddr_data => -- data ------------------
279 case r.waddr is
280 when "00" => irb_dout := CMEM_DOA(15 downto 0);
281 when "01" => irb_dout := r.mbuf(15 downto 0);
282 when "10" => irb_dout(3 downto 0) := r.mbuf(19 downto 16);
283 when others => null;
284 end case;
285 when others => null;
286 end case;
287 end if;
288
289 -- latch state number
290 -- 1 msb determined from cpu mode: 0 if kernel and 1 when user or super
291 -- 8 lsb taken from sequencer snum
292 n.snum0(8) := '0';
293 if DM_STAT_DP.psw.cmode /= c_psw_kmode then
294 n.snum0(8) := '1';
295 end if;
296 n.snum0(7 downto 0) := DM_STAT_SE.snum;
297 n.snum1 := r.snum0;
298
299 -- incrementer pipeline
300 n.same := '0';
301 if r.snum0=r.snum1 and r.ena1 ='1' then -- in same state ?
302 n.same := '1'; -- don't read mem and remember
303 else -- otherwise
304 icea := '1'; -- enable mem read
305 end if;
306
307 -- increment state count
308 if r.same = '0' then -- was mem read ?
309 iscnt0 := CMEM_DOA; -- take memory value
310 else -- otherwise
311 iscnt0 := r.scnt; -- use scnt reg
312 end if;
313 iscnt1 := slv(unsigned(iscnt0) + 1); -- increment
314 n.scnt := iscnt1; -- and store
315
316 -- finally setup memory access
317 n.ena1 := r.ena0;
318 if r.clr = '1' then -- mem clear action
319 icea := '1';
320 iwea := '1';
321 iaddra := r.laddr;
322 n.laddr := slv(unsigned(r.laddr) + 1);
323 if r.laddr = "111111111" then
324 n.clr := '0';
325 end if;
326 elsif r.ena1 = '1' then -- state count action
327 iweb := '1';
328 end if;
329
330 N_REGS <= n;
331
332 CMEM_CEA <= icea;
333 CMEM_CEB <= iweb;
334 CMEM_WEA <= iwea;
335 CMEM_WEB <= iweb;
336 CMEM_ADDRA <= iaddra;
337 CMEM_DIB <= iscnt1;
338
339 RB_SRES.ack <= irb_ack;
340 RB_SRES.err <= irb_err;
341 RB_SRES.busy <= irb_busy;
342 RB_SRES.dout <= irb_dout;
343
344 end process proc_next;
345
346end syn;
slv( 35 downto 0) :=( others => '0') CMEM_DIB
regs_type :=( s_idle, '0', '0', '0', '0',( others => '0'),( others => '0'), '0',( others => '0'),( others => '0'),( others => '0'),( others => '0')) regs_init
slv2 := "01" rbaddr_addr
(s_idle,s_mread) state_type
integer := 0 cntl_rbf_ena
slv2 := "10" rbaddr_data
integer range 10 downto 2 addr_rbf_mem
slbit := '0' CMEM_WEA
slv( 35 downto 0) :=( others => '0') cmem_data_zero
slv( 35 downto 0) :=( others => '0') CMEM_DOA
integer := 1 cntl_rbf_clr
slbit := '0' CMEM_CEA
slbit := '0' CMEM_WEB
slv9 :=( others => '0') CMEM_ADDRA
slv2 := "00" rbaddr_cntl
integer range 1 downto 0 addr_rbf_word
regs_type := regs_init R_REGS
slbit := '0' CMEM_CEB
in RESET slbit
in DM_STAT_DP dm_stat_dp_type
in DM_STAT_CO dm_stat_co_type
in DM_STAT_SE dm_stat_se_type
in CLK slbit
in RB_MREQ rb_mreq_type
out RB_SRES rb_sres_type
RB_ADDR slv16 := rbaddr_dmscnt_off
Definition: pdp11.vhd:123
in DIA slv( DWIDTH- 1 downto 0)
in ADDRB slv( AWIDTH- 1 downto 0)
in ADDRA slv( AWIDTH- 1 downto 0)
out DOB slv( DWIDTH- 1 downto 0)
in DIB slv( DWIDTH- 1 downto 0)
out DOA slv( DWIDTH- 1 downto 0)
Definition: rblib.vhd:32
std_logic_vector( 19 downto 0) slv20
Definition: slvtypes.vhd:53
std_logic_vector( 8 downto 0) slv9
Definition: slvtypes.vhd:41
std_logic_vector( 15 downto 0) slv16
Definition: slvtypes.vhd:48
std_logic slbit
Definition: slvtypes.vhd:30
std_logic_vector( 1 downto 0) slv2
Definition: slvtypes.vhd:34
std_logic_vector slv
Definition: slvtypes.vhd:31