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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.74/] [rtl/] [sys_gen/] [tst_sram/] [tst_sram.vhd] - Blame information for rev 40

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 37 wfjm
-- $Id: tst_sram.vhd 785 2016-07-10 12:22:41Z mueller $
2
--
3
-- Copyright 2007-2016 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4
--
5
-- This program is free software; you may redistribute and/or modify it under
6
-- the terms of the GNU General Public License as published by the Free
7
-- Software Foundation, either version 2, or at your option any later version.
8
--
9
-- This program is distributed in the hope that it will be useful, but
10
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
-- for complete details.
13
--
14
------------------------------------------------------------------------------
15
-- Module Name:    tst_sram - syn
16
-- Description:    test of s3board sram and its controller
17
--
18
-- Dependencies:   vlib/memlib/ram_1swsr_wfirst_gen
19
--                 vlib/memlib/ram_2swsr_wfirst_gen
20
--                 vlib/rlink/rlink_base_serport
21
--
22
-- Test bench:     nexys4/tb/tb_tst_sram_n4       (with cram)
23
--                 nexys3/tb/tb_tst_sram_n3       (with cram)
24
--                 nexys2/tb/tb_tst_sram_n2       (with cram)
25
--                 s3board/tb/tb_tst_sram_s3      (with sram)
26
--
27
-- Target Devices: generic
28
-- Tool versions:  xst 8.2-14.7; viv 2014.4-2016.2; ghdl 0.18-0.33
29
--
30
-- Revision History: 
31
-- Date         Rev Version  Comment
32
-- 2016-07-10   785   1.5.1  std SWI layout: now (7:4) disp select, SWI(1)->XON
33
-- 2016-07-09   784   1.5    AWIDTH generic, add 22bit support for cram
34
-- 2016-05-22   767   1.4.1  don't init N_REGS (vivado fix for fsm inference)
35
-- 2014-09-05   591   1.4    use new rlink v4 iface and 4 bit STAT
36
-- 2014-08-15   583   1.3    rb_mreq addr now 16 bit
37
-- 2011-11-21   432   1.2.0  now numeric_std clean
38
-- 2010-12-31   352   1.2    port to rbv3
39
-- 2010-10-23   335   1.1.3  rename RRI_LAM->RB_LAM;
40
-- 2010-06-18   306   1.1.2  rename rbus data fields to _rbf_
41
-- 2010-06-03   299   1.1.1  correct rbus init logic (use we, RB_ADDR)
42
-- 2010-05-24   294   1.1    Correct _al->_dl logic, remove BUSY=0 condition
43
-- 2010-05-21   292   1.0.1  move memory controler to top level entity
44
-- 2010-05-16   291   1.0    Initial version (extracted from sys_tst_sram)
45
--                           now RB_SRES only driven when selected
46
------------------------------------------------------------------------------
47
--
48
-- rbus registers:
49
--
50
-- Address   Bits Name        r/w/f  Function
51
-- bbb00000 15:00 mdih        r/w/-  Memory data input register, high word
52
-- bbb00001 15:00 mdil        r/w/-  Memory data input register,  low word
53
-- bbb00010 15:00 mdoh        r/-/-  Memory data output register, high word
54
-- bbb00011 15:00 mdol        r/-/-  Memory data output register,  low word
55
-- bbb00100 01:00 maddrh      r/w/-  Memory address register, high word
56
-- bbb00101 15:00 maddrl      r/w/-  Memory address register,  low word
57
--
58
-- bbb00110       mcmd        -/-/f  Immediate memory command register
59
--             14   ld        -/-/f    if 1 load addrh field to maddr high word
60
--             13   inc       -/-/f    if 1 post-increment maddr
61
--             12   we        -/-/f    if 1 do write cycle, otherwise read
62
--          11:08   be        -/-/f    byte enables (used for writes)
63
--           *:00   addrh     -/-/f    maddr high word (loaded of ld=1)
64
--
65
-- bbb00111 15:00 mblk        r/w/-  Memory block read/write
66
--                                     pairs of r/w to access memory directly
67
--                                     read access logic:
68
--                                       than mdo is read from mem(maddr)
69
--                                       1st read gives mdoh, 2nd loads mdol
70
--                                       maddr is post-incrememted
71
--                                     write access logic:
72
--                                       1st write loads mdih, 2nd loads mdil
73
--                                       than mdi is written to mem(maddr)
74
--                                       maddr is post-incrememted
75
--
76
-- bbb01000 10:00 slim        r/w/-  Sequencer range register
77
-- bbb01001 10:00 saddr       r/w/-  Sequencer address register
78
-- bbb01010 15:00 sblk        r/w/-  Sequencer memory block read/write
79
--                                     groups of 4 r/w to access sequencer mem
80
--                                     access order: 11,10,01,00
81
-- bbb01011 15:00 sblkc       r/w/-  Like sblk, access to command part
82
--                                     groups of 2 r/w to access sequencer mem
83
--                                     access order: 11,10
84
-- bbb01100 15:00 sblkd       r/w/-  Like sblk, access to data part
85
--                                     groups of 2 r/w to access sequencer mem
86
--                                     access order: 01,00
87
-- bbb01101       sstat       r/w/-  Sequencer status register
88
--             15   wide      r/-/-    1 if AWIDTH=22
89
--             09   wswap     r/w/-    enable swap of upper 4 addr bits
90
--             08   wloop     r/w/-    enable wide (22bit) loop (default 18bit)
91
--             07   loop      r/w/-    loop till maddr=<all-ones>
92
--             06   xord      r/w/-    xor memory address with maddr
93
--             05   xora      r/w/-    xor memory data with mdi
94
--             04   veri      r/w/-    verify memory reads
95
--             01   fail      r/-/-    1 if sequencer stopped after failure
96
--             00   run       r/-/-    1 if sequencer running
97
-- bbb01110       sstart      -/-/f  Start sequencer (sstat.run=1, .fail=0)
98
-- bbb01111       sstop       -/-/f  Stop sequencer  (sstat.run=0)
99
-- bbb10000 10:00 seaddr      r/-/-  Current sequencer address
100
-- bbb10001 15:00 sedath      r/-/-  Current sequencer data (high word)
101
-- bbb10010 15:00 sedatl      r/-/-  Current sequencer data ( low word)
102
--
103
-- Sequencer memory format
104
--   64 bit wide, upper 32 bits sequencer command, lower 32 bits data
105
--   Item    Bits Name        Function
106
--   scmd   31:28   wait      number of wait cycles
107
--             24   we        write enable
108
--          23:20   be        byte enables
109
--          17:00   addr      address
110
--
111
------------------------------------------------------------------------------
112
--
113
-- Usage of S3BOARD Switches, Buttons, LEDs:
114
--
115
--    BTN(3:0): unused
116
--
117
--    SWI(7:4): determine data displayed
118
--          SWI 3210
119
--              0000  mdil
120
--              0001  mdih
121
--              0010  mem_do.l
122
--              0011  mem_do.h
123
--              0100  maddr.l
124
--              0101  maddr.h
125
--              0110  slim
126
--              0111  saddr
127
--              1000  sstat
128
--              1001  seaddr
129
--              1010  sedatl
130
--              1011  sedath
131
--              1100  smem_b0  data.l
132
--              1101  smem_b1  data.h
133
--              1110  smem_b2  cmd.l
134
--              1111  smem_b3  cmd.h
135
--    SWI(3:2): unused
136
--    SWI(1):   1 enable XON
137
--    SWI(0):   RS232 port select (on some boards)
138
--
139
--    LED(7):   or of all unused BTNs and SWI
140
--    LED(6):   R_REGS.sloop
141
--    LED(5):   R_REGS.sveri
142
--    LED(4):   R_REGS.sfail
143
--    LED(3):   R_REGS.srun
144
--    LED(2):   MEM_ACT_W
145
--    LED(1):   MEM_ACT_R
146
--    LED(0):   MEM_BUSY
147
--
148
--    DSP:      data as selected by SWI(7..4)
149
--
150
--    DP(3):    not SER_MONI.txok       (shows tx back preasure)
151
--    DP(2):    SER_MONI.txact          (shows tx activity)
152
--    DP(1):    not SER_MONI.rxok       (shows rx back preasure)
153
--    DP(0):    SER_MONI.rxact          (shows rx activity)
154
--
155
 
156
library ieee;
157
use ieee.std_logic_1164.all;
158
use ieee.numeric_std.all;
159
 
160
use work.slvtypes.all;
161
use work.memlib.all;
162
use work.rblib.all;
163
 
164
-- ----------------------------------------------------------------------------
165
 
166
entity tst_sram is                      -- tester for sram memctl
167
  generic (
168
    RB_ADDR : slv16 := slv(to_unsigned(2#0000000000000000#,16));
169
    AWIDTH : natural := 18);
170
  port (
171
    CLK : in slbit;                     -- clock
172
    RESET : in slbit;                   -- reset
173
    RB_MREQ : in rb_mreq_type;          -- rbus: request
174
    RB_SRES : out rb_sres_type;         -- rbus: response
175
    RB_STAT : out slv4;                 -- rbus: status flags
176
    RB_LAM : out slbit;                 -- remote attention
177
    SWI : in slv8;                      -- hio switches
178
    BTN : in slv4;                      -- hio buttons
179
    LED : out slv8;                     -- hio leds
180
    DSP_DAT : out slv16;                -- hio display data
181
    MEM_RESET : out slbit;              -- mem: reset
182
    MEM_REQ   : out slbit;              -- mem: request
183
    MEM_WE    : out slbit;              -- mem: write enable
184
    MEM_BUSY : in slbit;                -- mem: controller busy
185
    MEM_ACK_R : in slbit;               -- mem: acknowledge read
186
    MEM_ACK_W : in slbit;               -- mem: acknowledge write
187
    MEM_ACT_R : in slbit;               -- mem: signal active read
188
    MEM_ACT_W : in slbit;               -- mem: signal active write
189
    MEM_ADDR : out slv(AWIDTH-1 downto 0); -- mem: address
190
    MEM_BE : out slv4;                  -- mem: byte enable
191
    MEM_DI : out slv32;                 -- mem: data in  (memory view)
192
    MEM_DO : in slv32                   -- mem: data out (memory view)
193
  );
194
end tst_sram;
195
 
196
architecture syn of tst_sram is
197
 
198
  signal SEQ_RESET : slbit := '0';
199
 
200
  signal SMEM_CEA : slbit := '0';
201
  signal SMEM_B3_WE : slbit := '0';
202
  signal SMEM_B2_WE : slbit := '0';
203
  signal SMEM_B1_WE : slbit := '0';
204
  signal SMEM_B0_WE : slbit := '0';
205
  signal SMEM_WEB  : slbit := '0';
206
  signal SMEM_CMD  : slv32 := (others=>'0');
207
  signal SMEM_DATA : slv32 := (others=>'0');
208
 
209
  type state_type is (
210
    s_idle,                             -- s_idle: wait for input
211
    s_mcmd,                             -- s_mcmd: immediate memory r/w
212
    s_mcmd_read,                        -- s_mcmd_read: wait for read completion
213
    s_mblk_wr1,                         -- s_mblk_wr1: mem blk write, get datal
214
    s_mblk_wr2,                         -- s_mblk_wr2: mem blk write, do write
215
    s_mblk_rd1,                         -- s_mblk_rd1: mem blk read, wait, datah
216
    s_mblk_rd2,                         -- s_mblk_rd2: mem blk read, datal
217
    s_sblk_rd,                          -- s_sblk_rd: read smem for sblk
218
    s_sblk,                             -- s_sblk: process sblk transfers
219
    s_sstart,                           -- s_sstart: sequencer startup 
220
    s_sload,                            -- s_sload: sequencer load data
221
    s_srun,                             -- s_srun: run sequencer commands
222
    s_sloop                             -- s_sloop: stop or loop
223
  );
224
 
225
  type regs_type is record
226
    state  : state_type;                -- state
227
    rbsel  : slbit;                     -- rbus select
228
    maddr  : slv(AWIDTH-1 downto 0);    -- memory address
229
    mdi    : slv32;                     -- memory data input
230
    saddr  : slv11;                     -- sequencer address
231
    slim   : slv11;                     -- sequencer range
232
    sbank  : slv2;                      -- current sblk bank
233
    srun   : slbit;                     -- seq: run flag
234
    slast  : slbit;                     -- seq: last cmd flag
235
    sfail  : slbit;                     -- seq: fail flag
236
    swcnt  : slv4;                      -- seq: wait counter
237
    scaddr : slv11;                     -- seq: current address
238
    sveri  : slbit;                     -- seq: verify mode (check data)
239
    sxora  : slbit;                     -- seq: xor maddr into address
240
    sxord  : slbit;                     -- seq: xor mdi   into data
241
    sloop  : slbit;                     -- seq: loop over maddr
242
    swloop : slbit;                     -- seq: enable wide loop (22bit)
243
    swswap : slbit;                     -- seq: enable top 4 bit addr swap
244
    mrp_val_al : slbit;                 -- mrp: valid flag,   addr latch stage
245
    mrp_adr_al : slv11;                 -- mrp: seq address,  addr latch stage
246
    mrp_dat_al : slv32;                 -- mrp: exp mem data, addr latch stage
247
    mrp_val_dl : slbit;                 -- mrp: valid flag,   data latch stage
248
    mrp_adr_dl : slv11;                 -- mrp: seq address,  data latch stage
249
    mrp_dat_dl : slv32;                 -- mrp: exp mem data, data latch stage
250
    se_addr : slv11;                    -- seq err: seq address
251
    se_data : slv32;                    -- seq err: memory data
252
    dispval : slv16;                    -- data for display
253
  end record regs_type;
254
 
255
  constant maddrzero : slv(AWIDTH-1 downto 0) := (others=>'0');
256
 
257
  constant regs_init : regs_type := (
258
    s_idle,                             -- state
259
    '0',                                -- rbsel
260
    maddrzero,                          -- maddr
261
    (others=>'0'),                      -- mdi
262
    (others=>'0'),                      -- saddr
263
    (others=>'0'),                      -- slim
264
    (others=>'0'),                      -- sbank
265
    '0','0','0',                        -- srun, slast, sfail
266
    (others=>'0'),                      -- swcnt
267
    (others=>'0'),                      -- scaddr
268
    '0','0','0',                        -- sveri,sxora,sxord
269
    '0','0','0',                        -- sloop,swloop,swswap
270
    '0',                                -- mrp_val_al
271
    (others=>'0'),                      -- mrp_adr_al
272
    (others=>'0'),                      -- mrp_dat_al
273
    '0',                                -- mrp_val_dl
274
    (others=>'0'),                      -- mrp_adr_dl
275
    (others=>'0'),                      -- mrp_dat_dl
276
    (others=>'0'),                      -- se_addr
277
    (others=>'0'),                      -- se_data
278
    (others=>'0')                       -- dispval
279
  );
280
 
281
  signal R_REGS : regs_type := regs_init;
282
  signal N_REGS : regs_type;            -- don't init (vivado fix for fsm infer)
283
 
284
  subtype  maddr_f_wh      is integer range  AWIDTH-1 downto 16;
285
  subtype  maddr_f_wl      is integer range  15 downto  0;
286
 
287
  subtype  maddr_f_scmd    is integer range  17 downto  0;
288
  subtype  maddr_f_top4    is integer range  AWIDTH-1   downto AWIDTH-1-3;
289
  subtype  maddr_f_mid4    is integer range  AWIDTH-1-4 downto AWIDTH-1-7;
290
  subtype  maddr_f_bot     is integer range  AWIDTH-1-8 downto          0;
291
 
292
  subtype  df_word0        is integer range  15 downto  0;
293
  subtype  df_word1        is integer range  31 downto 16;
294
 
295
  subtype  maddrh_rbf_h    is integer range  AWIDTH-1-16 downto 0;
296
 
297
  constant mcmd_rbf_ld:    integer :=  14;
298
  constant mcmd_rbf_inc:   integer :=  13;
299
  constant mcmd_rbf_we:    integer :=  12;
300
  subtype  mcmd_rbf_be     is integer range 11 downto  8;
301
  subtype  mcmd_rbf_addrh  is integer range AWIDTH-1-16 downto  0;
302
 
303
  constant sstat_rbf_wide:  integer :=  15;
304
  constant sstat_rbf_wswap: integer :=   9;
305
  constant sstat_rbf_wloop: integer :=   8;
306
  constant sstat_rbf_loop:  integer :=   7;
307
  constant sstat_rbf_xord:  integer :=   6;
308
  constant sstat_rbf_xora:  integer :=   5;
309
  constant sstat_rbf_veri:  integer :=   4;
310
  constant sstat_rbf_fail:  integer :=   1;
311
  constant sstat_rbf_run:   integer :=   0;
312
 
313
  subtype  scmd_rbf_wait   is integer range 31 downto 28;
314
  constant scmd_rbf_we:    integer :=  24;
315
  subtype  scmd_rbf_be     is integer range 23 downto 20;
316
  subtype  scmd_rbf_addr   is integer range 17 downto  0;
317
 
318
  constant rbaddr_mdih:   slv5 := "00000";  --  0    -/r/w
319
  constant rbaddr_mdil:   slv5 := "00001";  --  1    -/r/w
320
  constant rbaddr_mdoh:   slv5 := "00010";  --  2    -/r/-
321
  constant rbaddr_mdol:   slv5 := "00011";  --  3    -/r/-
322
  constant rbaddr_maddrh: slv5 := "00100";  --  4    -/r/w
323
  constant rbaddr_maddrl: slv5 := "00101";  --  5    -/r/w
324
  constant rbaddr_mcmd:   slv5 := "00110";  --  6    -/-/w
325
  constant rbaddr_mblk:   slv5 := "00111";  --  7    -/r/w
326
  constant rbaddr_slim:   slv5 := "01000";  --  8    -/r/w
327
  constant rbaddr_saddr:  slv5 := "01001";  --  9    -/r/w
328
  constant rbaddr_sblk:   slv5 := "01010";  -- 10    -/r/w
329
  constant rbaddr_sblkc:  slv5 := "01011";  -- 11    -/r/w
330
  constant rbaddr_sblkd:  slv5 := "01100";  -- 12    -/r/w
331
  constant rbaddr_sstat:  slv5 := "01101";  -- 13    -/r/w
332
  constant rbaddr_sstart: slv5 := "01110";  -- 14    f/-/-
333
  constant rbaddr_sstop:  slv5 := "01111";  -- 15    f/-/-
334
  constant rbaddr_seaddr: slv5 := "10000";  -- 16    -/r/-
335
  constant rbaddr_sedath: slv5 := "10001";  -- 17    -/r/-
336
  constant rbaddr_sedatl: slv5 := "10010";  -- 18    -/r/-
337
 
338
  constant omux_mdil:    slv4 := "0000";
339
  constant omux_mdih:    slv4 := "0001";
340
  constant omux_memdol:  slv4 := "0010";
341
  constant omux_memdoh:  slv4 := "0011";
342
  constant omux_maddrl:  slv4 := "0100";
343
  constant omux_maddrh:  slv4 := "0101";
344
  constant omux_slim:    slv4 := "0110";
345
  constant omux_saddr:   slv4 := "0111";
346
  constant omux_sstat:   slv4 := "1000";
347
  constant omux_seaddr:  slv4 := "1001";
348
  constant omux_sedatl:  slv4 := "1010";
349
  constant omux_sedath:  slv4 := "1011";
350
  constant omux_smemb0:  slv4 := "1100";
351
  constant omux_smemb1:  slv4 := "1101";
352
  constant omux_smemb2:  slv4 := "1110";
353
  constant omux_smemb3:  slv4 := "1111";
354
 
355
begin
356
 
357
  assert AWIDTH=18 or AWIDTH=22
358
    report "assert(AWIDTH=18 or AWIDTH=22): unsupported AWIDTH"
359
    severity failure;
360
 
361
  SMEM_B3 : ram_1swsr_wfirst_gen
362
    generic map (
363
      AWIDTH => 11,
364
      DWIDTH => 16)
365
    port map (
366
      CLK  => CLK,
367
      EN   => SMEM_CEA,
368
      WE   => SMEM_B3_WE,
369
      ADDR => R_REGS.saddr,
370
      DI   => RB_MREQ.din,
371
      DO   => SMEM_CMD(df_word1)
372
    );
373
 
374
  SMEM_B2 : ram_1swsr_wfirst_gen
375
    generic map (
376
      AWIDTH => 11,
377
      DWIDTH => 16)
378
    port map (
379
      CLK  => CLK,
380
      EN   => SMEM_CEA,
381
      WE   => SMEM_B2_WE,
382
      ADDR => R_REGS.saddr,
383
      DI   => RB_MREQ.din,
384
      DO   => SMEM_CMD(df_word0)
385
    );
386
 
387
  SMEM_B1 : ram_2swsr_wfirst_gen
388
    generic map (
389
      AWIDTH => 11,
390
      DWIDTH => 16)
391
    port map (
392
      CLKA  => CLK,
393
      CLKB  => CLK,
394
      ENA   => SMEM_CEA,
395
      ENB   => SMEM_WEB,
396
      WEA   => SMEM_B1_WE,
397
      WEB   => SMEM_WEB,
398
      ADDRA => R_REGS.saddr,
399
      ADDRB => R_REGS.mrp_adr_dl,
400
      DIA   => RB_MREQ.din,
401
      DIB   => MEM_DO(df_word1),
402
      DOA   => SMEM_DATA(df_word1),
403
      DOB   => open
404
    );
405
 
406
  SMEM_B0 : ram_2swsr_wfirst_gen
407
    generic map (
408
      AWIDTH => 11,
409
      DWIDTH => 16)
410
    port map (
411
      CLKA  => CLK,
412
      CLKB  => CLK,
413
      ENA   => SMEM_CEA,
414
      ENB   => SMEM_WEB,
415
      WEA   => SMEM_B0_WE,
416
      WEB   => SMEM_WEB,
417
      ADDRA => R_REGS.saddr,
418
      ADDRB => R_REGS.mrp_adr_dl,
419
      DIA   => RB_MREQ.din,
420
      DIB   => MEM_DO(df_word0),
421
      DOA   => SMEM_DATA(df_word0),
422
      DOB   => open
423
    );
424
 
425
  -- look for init's against the rbus base address
426
  -- generate subsystem resets depending in data bits
427
  proc_reset: process (RESET, RB_MREQ)
428
  begin
429
 
430
    SEQ_RESET <= RESET;
431
    MEM_RESET <= RESET;
432
 
433
    if RB_MREQ.init='1' and RB_MREQ.addr=RB_ADDR then
434
      SEQ_RESET <= RB_MREQ.din(0);
435
      MEM_RESET <= RB_MREQ.din(1);
436
    end if;
437
 
438
  end process proc_reset;
439
 
440
  proc_regs: process (CLK)
441
  begin
442
 
443
    if rising_edge(CLK) then
444
      if SEQ_RESET = '1' then
445
        R_REGS <= regs_init;
446
      else
447
        R_REGS <= N_REGS;
448
      end if;
449
    end if;
450
 
451
  end process proc_regs;
452
 
453
  proc_next: process (R_REGS, RB_MREQ,
454
                      MEM_BUSY, MEM_ACT_R, MEM_ACK_R, MEM_DO,
455
                      SMEM_CMD, SMEM_DATA,
456
                      SWI)
457
 
458
    variable r : regs_type := regs_init;
459
    variable n : regs_type := regs_init;
460
 
461
    variable irb_ack  : slbit := '0';
462
    variable irb_busy : slbit := '0';
463
    variable irb_err  : slbit := '0';
464
    variable irb_dout : slv16 := (others=>'0');
465
    variable irbena : slbit := '0';     -- re or we           -> rbus request
466
    variable irbact : slbit := '0';     -- sel and (re or we) -> device active
467
 
468
    variable imem_reqr : slbit := '0';
469
    variable imem_reqw : slbit := '0';
470
    variable imem_be :   slv4  := (others=>'0');
471
    variable imem_addr : slv(AWIDTH-1 downto 0) := (others=>'0');
472
    variable imem_di :   slv32 := (others=>'0');
473
 
474
    variable ixor_addr : slv(AWIDTH-1 downto 0) := (others=>'0');
475
    variable ixor_data : slv32 := (others=>'0');
476
    variable imaddr_chk: slv(AWIDTH-1 downto 0) := (others=>'0');
477
 
478
    variable isblk_ok  : slbit := '0';
479
    variable isbank    : slv2  := "11";
480
 
481
    variable maddr_inc : slbit := '0';
482
    variable saddr_inc : slbit := '0';
483
    variable saddr_next : slbit := '0';
484
    variable saddr_last : slbit := '0';
485
    variable swcnt_inc : slbit := '0';
486
 
487
    variable ilam : slbit := '0';
488
 
489
    variable omux_sel : slv4  := "0000";
490
    variable omux_dat : slv16 := (others=>'0');
491
 
492
    constant c_maddr_ones : slv(AWIDTH-1 downto 0) := (others=>'1');
493
 
494
  begin
495
 
496
    r := R_REGS;
497
    n := R_REGS;
498
 
499
    irb_ack  := '0';
500
    irb_busy := '0';
501
    irb_err  := '0';
502
    irb_dout := (others=>'0');
503
 
504
    irbena  := RB_MREQ.re or RB_MREQ.we;
505
    irbact  := '0';
506
 
507
    imem_reqr := '0';
508
    imem_reqw := '0';
509
    imem_be   := (others=>'1');
510
    imem_addr := r.maddr;
511
    imem_di   := r.mdi;
512
 
513
    ixor_addr := (others=>'0');
514
    ixor_data := (others=>'0');
515
 
516
    isblk_ok := '0';
517
    isbank   := "11";
518
 
519
    maddr_inc := '0';
520
    saddr_inc := '0';
521
    saddr_next := '0';
522
    saddr_last := '0';
523
    swcnt_inc := '0';
524
 
525
    ilam := '0';
526
 
527
    omux_sel := omux_mdil;
528
    omux_dat := (others=>'0');
529
 
530
    SMEM_CEA   <= '0';
531
    SMEM_B3_WE <= '0';
532
    SMEM_B2_WE <= '0';
533
    SMEM_B1_WE <= '0';
534
    SMEM_B0_WE <= '0';
535
    SMEM_WEB   <= '0';
536
 
537
    if r.saddr = r.slim then
538
      saddr_last := '1';
539
    end if;
540
 
541
    if r.mrp_val_dl='1' and MEM_ACK_R='1' then
542
      n.mrp_val_dl := '0';
543
      if r.sveri = '1' then
544
        if r.mrp_dat_dl /= MEM_DO and                  -- mismatch
545
           r.sfail='0' then                              -- and no fail set yet
546
          ilam := '1';
547
          n.sfail := '1';
548
          n.srun  := '0';
549
          n.se_addr := r.mrp_adr_dl;
550
          n.se_data := MEM_DO;
551
        end if;
552
      else
553
        SMEM_WEB <= '1';
554
      end if;
555
    end if;
556
    if r.mrp_val_al='1' and MEM_ACT_R='1' then
557
      n.mrp_val_al := '0';
558
      n.mrp_val_dl := r.mrp_val_al;
559
      n.mrp_adr_dl := r.mrp_adr_al;
560
      n.mrp_dat_dl := r.mrp_dat_al;
561
    end if;
562
 
563
    -- rbus address decoder
564
    n.rbsel := '0';
565
    if RB_MREQ.aval='1' and RB_MREQ.addr(15 downto 5)=RB_ADDR(15 downto 5) then
566
      n.rbsel := '1';
567
    end if;
568
 
569
    if r.rbsel='1' and irbena='1' then
570
      irb_ack := '1';                     -- ack all (maybe rejected later)
571
      irbact := '1';                      -- signal device active
572
    end if;
573
 
574
    case r.state is
575
 
576
      when s_idle =>                    -- s_idle: wait for rbus requests ----
577
 
578
        if r.rbsel = '1' then             -- rbus select
579
 
580
          case RB_MREQ.addr(4 downto 0) is  -- rbus address decoder
581
 
582
            when rbaddr_mdih =>
583
              omux_sel := omux_mdih;
584
              if RB_MREQ.we = '1' then
585
                n.mdi(df_word1) := RB_MREQ.din;
586
              end if;
587
 
588
            when rbaddr_mdil =>
589
              omux_sel := omux_mdil;
590
              if RB_MREQ.we = '1' then
591
                n.mdi(df_word0) := RB_MREQ.din;
592
              end if;
593
 
594
            when rbaddr_mdoh =>
595
              omux_sel := omux_memdoh;
596
              if RB_MREQ.we = '1' then
597
                irb_err := '1';             -- read-only reg
598
              end if;
599
 
600
            when rbaddr_mdol =>
601
              omux_sel := omux_memdol;
602
              if RB_MREQ.we = '1' then
603
                irb_err := '1';             -- read-only reg
604
              end if;
605
 
606
            when rbaddr_maddrh =>
607
              omux_sel := omux_maddrh;
608
              if RB_MREQ.we = '1' then
609
                n.maddr(maddr_f_wh) := RB_MREQ.din(maddrh_rbf_h);
610
              end if;
611
 
612
            when rbaddr_maddrl =>
613
              omux_sel := omux_maddrl;
614
              if RB_MREQ.we = '1' then
615
                n.maddr(maddr_f_wl) := RB_MREQ.din;
616
              end if;
617
 
618
            when rbaddr_mcmd =>
619
              if RB_MREQ.we = '1' then
620
                if RB_MREQ.din(mcmd_rbf_ld) = '1' then
621
                  n.maddr(maddr_f_wh) := RB_MREQ.din(mcmd_rbf_addrh);
622
                end if;
623
                irb_busy := '1';
624
                n.state := s_mcmd;
625
              end if;
626
              if RB_MREQ.re = '1' then
627
                irb_err := '1';         -- write-only reg
628
              end if;
629
 
630
            when rbaddr_mblk =>
631
              imem_addr := r.maddr;
632
 
633
              if RB_MREQ.we = '1' then
634
                n.mdi(df_word1) := RB_MREQ.din;
635
                n.state := s_mblk_wr1;
636
              end if;
637
              if RB_MREQ.re = '1' then
638
                irb_busy := '1';
639
                imem_reqr := '1';
640
                if MEM_BUSY = '0' then
641
                  maddr_inc := '1';
642
                  n.state := s_mblk_rd1;
643
                end if;
644
              end if;
645
 
646
            when rbaddr_slim =>
647
              omux_sel := omux_slim;
648
              if RB_MREQ.we = '1' then
649
                n.slim := RB_MREQ.din(r.slim'range);
650
              end if;
651
 
652
            when rbaddr_saddr =>
653
              omux_sel := omux_saddr;
654
              if RB_MREQ.we = '1' then
655
                n.saddr := RB_MREQ.din(r.saddr'range);
656
              end if;
657
 
658
            when rbaddr_sblk|rbaddr_sblkc|rbaddr_sblkd =>
659
              if RB_MREQ.we = '1' then
660
                n.sbank := "11";
661
                irb_busy := '1';
662
                n.state := s_sblk;
663
              end if;
664
              if RB_MREQ.re = '1' then
665
                n.sbank := "11";
666
                irb_busy := '1';
667
                n.state := s_sblk_rd;
668
              end if;
669
 
670
            when rbaddr_sstat =>
671
              omux_sel := omux_sstat;
672
              if RB_MREQ.we = '1' then
673
                n.swswap := RB_MREQ.din(sstat_rbf_wswap);
674
                n.swloop := RB_MREQ.din(sstat_rbf_wloop);
675
                n.sloop  := RB_MREQ.din(sstat_rbf_loop);
676
                n.sxord  := RB_MREQ.din(sstat_rbf_xord);
677
                n.sxora  := RB_MREQ.din(sstat_rbf_xora);
678
                n.sveri  := RB_MREQ.din(sstat_rbf_veri);
679
              end if;
680
 
681
            when rbaddr_sstart =>
682
              if RB_MREQ.we = '1' then
683
                n.sfail := '0';
684
                n.state := s_sstart;
685
              end if;
686
              if RB_MREQ.re = '1' then
687
                irb_err := '1';         -- write-only reg
688
              end if;
689
 
690
            when rbaddr_sstop =>
691
              if RB_MREQ.we = '1' then
692
                n.srun  := '0';
693
              end if;
694
              if RB_MREQ.re = '1' then
695
                irb_err := '1';         -- write-only reg
696
              end if;
697
 
698
            when rbaddr_seaddr =>
699
              omux_sel := omux_seaddr;
700
              if RB_MREQ.we = '1' then
701
                irb_err := '1';         -- read-only reg
702
              end if;
703
 
704
            when rbaddr_sedath =>
705
              omux_sel := omux_sedath;
706
              if RB_MREQ.we = '1' then
707
                irb_err := '1';         -- read-only reg
708
              end if;
709
 
710
            when rbaddr_sedatl =>
711
              omux_sel := omux_sedatl;
712
              if RB_MREQ.we = '1' then
713
                irb_err := '1';         -- read-only reg
714
              end if;
715
 
716
            when others =>
717
              irb_ack := '0';           -- refuse ack in case of bad addr
718
          end case;
719
 
720
        else                            -- no rbus request (rb_mreq.ack='0')
721
 
722
          if r.srun = '1' then
723
            n.state := s_srun;
724
          end if;
725
 
726
        end if;
727
 
728
      when s_mcmd=>                     -- s_mcmd: immediate memory r/w ------
729
        if RB_MREQ.din(mcmd_rbf_we) = '1' then  -- write command 
730
          imem_reqw := '1';
731
        else                              -- read command
732
          imem_reqr := '1';
733
        end if;
734
        imem_be   := RB_MREQ.din(mcmd_rbf_be);
735
        imem_addr := r.maddr;
736
        imem_di   := r.mdi;
737
 
738
        if irbact = '0' then              -- rbus cycle abort
739
          n.state := s_idle;                -- quit
740
        else
741
          if MEM_BUSY = '0' then         -- command accepted ?
742
            if RB_MREQ.din(mcmd_rbf_inc) = '1' then -- maddr inc requested
743
              maddr_inc := '1';
744
            end if;
745
            if RB_MREQ.din(mcmd_rbf_we) = '1' then  -- write command 
746
              n.state := s_idle;
747
            else                              -- read command
748
              irb_busy := '1';
749
              n.state := s_mcmd_read;
750
            end if;
751
          else                                -- otherwise
752
            irb_busy := '1';                    -- hold and wait
753
          end if;
754
        end if;
755
 
756
      when s_mcmd_read =>              -- s_mcmd_read: wait for read completion
757
 
758
        if irbact = '0' then              -- rbus cycle abort
759
          n.state := s_idle;                -- quit
760
        else
761
          if MEM_ACK_R = '1' then           -- read acknowledge seen
762
            n.state := s_idle;
763
          else                              -- otherwise
764
            irb_busy := '1';                  -- hold and wait
765
          end if;
766
        end if;
767
 
768
      when s_mblk_wr1 =>                -- s_mblk_wr1: mem blk write, get datal
769
        if irbact = '1' then              -- wait for rbus request
770
          if RB_MREQ.we = '1' and           -- write access and cmd ok ?
771
             RB_MREQ.addr(4 downto 0)=rbaddr_mblk then
772
            n.mdi(df_word0) := RB_MREQ.din;   -- latch datal
773
            irb_busy := '1';
774
            n.state := s_mblk_wr2;            -- next: issue mem write
775
          else
776
            irb_err := '1';                   -- signal error
777
            n.state := s_idle;                -- return to dispatch            
778
          end if;
779
        end if;
780
 
781
      when s_mblk_wr2 =>                -- s_mblk_wr2: mem blk write, do write
782
        n.state := s_mblk_wr2;             -- needed to prevent vivado iSTATE
783
        imem_reqw := '1';
784
        imem_be   := (others=>'1');
785
        imem_addr := r.maddr;
786
        imem_di   := r.mdi;
787
 
788
        if irbact = '0' then              -- rbus cycle abort
789
          n.state := s_idle;                -- quit
790
        else
791
          if MEM_BUSY = '0' then            -- command accepted ?
792
            maddr_inc := '1';
793
            n.state := s_idle;
794
          else                              -- otherwise
795
            irb_busy := '1';                  -- hold and wait
796
          end if;
797
        end if;
798
 
799
      when s_mblk_rd1 =>                -- s_mblk_rd1: mem blk read, wait, datah
800
        omux_sel := omux_memdoh;          -- return mem datah
801
        if irbact = '0' then              -- rbus cycle abort
802
          n.state := s_idle;                -- quit
803
        else
804
          if MEM_ACK_R = '1' then           -- read acknowledge seen
805
            n.state := s_mblk_rd2;
806
          else                              -- otherwise
807
            irb_busy := '1';                  -- hold and wait
808
          end if;
809
        end if;
810
 
811
      when s_mblk_rd2 =>                -- s_mblk_rd2: mem blk read, datal ---
812
        omux_sel := omux_memdol;          -- return mem datal
813
        if irbact = '1' then              -- wait for rbus request
814
          if RB_MREQ.re = '1' and           -- read access and cmd ok ?
815
             RB_MREQ.addr(4 downto 0)=rbaddr_mblk then
816
            n.state := s_idle;
817
          else                              -- write if unexpected cmd addr
818
            irb_err := '1';                   -- signal error
819
            n.state := s_idle;                -- return to dispatch
820
          end if;
821
        end if;
822
 
823
      when s_sblk_rd =>                 -- s_sblk_rd: read smem for sblk -----
824
        if irbact = '0' then              -- rbus cycle abort
825
          n.state := s_idle;                -- quit
826
        else
827
          irb_busy := '1';
828
          SMEM_CEA <= '1';
829
          n.state := s_sblk;
830
        end if;
831
 
832
      when s_sblk =>                    -- s_sblk: process sblk transfers ----
833
 
834
        isblk_ok := irbact;
835
 
836
        case RB_MREQ.addr(4 downto 0) is
837
          when rbaddr_sblk =>
838
            isbank := r.sbank;
839
            if r.sbank = "00" then
840
              saddr_next := irbact;
841
            end if;
842
          when rbaddr_sblkc =>
843
            isbank := '1' & r.sbank(0);
844
            if r.sbank(0) = '0' then
845
              saddr_next := irbact;
846
            end if;
847
          when rbaddr_sblkd =>
848
            isbank := '0' & r.sbank(0);
849
            if r.sbank(0) = '0' then
850
              saddr_next := irbact;
851
            end if;
852
          when others =>
853
            isblk_ok := '0';
854
        end case;
855
 
856
        if isblk_ok='1' and RB_MREQ.we='1' then
857
          SMEM_CEA <= '1';
858
          case isbank is
859
            when "11" => SMEM_B3_WE <= '1';
860
            when "10" => SMEM_B2_WE <= '1';
861
            when "01" => SMEM_B1_WE <= '1';
862
            when "00" => SMEM_B0_WE <= '1';
863
            when others => null;
864
          end case;
865
        end if;
866
 
867
        case isbank is
868
          when "11" => omux_sel := omux_smemb3;
869
          when "10" => omux_sel := omux_smemb2;
870
          when "01" => omux_sel := omux_smemb1;
871
          when "00" => omux_sel := omux_smemb0;
872
          when others => null;
873
        end case;
874
 
875
        if isblk_ok = '1' then            -- in active sblk cycle ?
876
          n.sbank := slv(unsigned(r.sbank) - 1);
877
          if saddr_next = '1' then
878
            saddr_inc := '1';
879
            if RB_MREQ.re = '1' then
880
              n.state := s_sblk_rd;
881
            end if;
882
          end if;
883
        else                              -- not in active sblk cycle
884
          if irbact = '1' then              -- if request than other address
885
            irb_busy := '1';                  -- hold interface and
886
            n.state := s_idle;                -- back to dispatcher to handle
887
          end if;
888
        end if;
889
 
890
      when s_sstart =>                  -- s_sstart: sequencer startup -------
891
        irb_busy := irbact;
892
        n.slast := '0';
893
        n.srun  := '1';
894
        n.saddr := (others=>'0');
895
        n.se_addr := (others=>'0');
896
        n.se_data := (others=>'0');
897
        n.state := s_sload;
898
 
899
      when s_sload =>                   -- s_sload: sequencer load data ------
900
        irb_busy := irbact;
901
        SMEM_CEA <= '1';
902
        n.scaddr := r.saddr;
903
        saddr_inc := '1';
904
        if saddr_last = '1' then
905
          n.slast := '1';
906
        end if;
907
        n.state := s_srun;
908
 
909
      when s_srun =>                    -- s_srun: run sequencer commands ----
910
        irb_busy := irbact;
911
        ixor_addr := r.maddr;
912
        if r.sxora = '0' then
913
          ixor_addr(maddr_f_scmd) := SMEM_CMD(scmd_rbf_addr);
914
        else
915
          ixor_addr(maddr_f_scmd) := SMEM_CMD(scmd_rbf_addr) xor
916
                                       r.maddr(maddr_f_scmd);
917
        end if;
918
 
919
        if r.swswap = '1' then
920
          ixor_addr := ixor_addr(maddr_f_mid4) & ixor_addr(maddr_f_top4) &
921
                         ixor_addr(maddr_f_bot);
922
        end if;
923
 
924
        if r.sxord = '0' then
925
          ixor_data := SMEM_DATA;
926
        else
927
          ixor_data := SMEM_DATA xor r.mdi;
928
        end if;
929
        imem_addr := ixor_addr;
930
        imem_be   := SMEM_CMD(scmd_rbf_be);
931
        imem_di   := ixor_data;
932
 
933
        if SMEM_CMD(scmd_rbf_wait) /= r.swcnt then
934
          swcnt_inc := '1';
935
        else
936
          if SMEM_CMD(scmd_rbf_we) = '1' then
937
            imem_reqw := '1';
938
          else
939
            imem_reqr := '1';
940
          end if;
941
          if MEM_BUSY = '0' then
942
            if imem_reqr = '1' then
943
              n.mrp_val_al := '1';
944
              n.mrp_adr_al := r.scaddr;
945
              n.mrp_dat_al := ixor_data;
946
            end if;
947
            if r.srun = '0' then
948
              n.state := s_idle;
949
            elsif r.slast = '1' then
950
              n.state := s_sloop;
951
            else
952
              SMEM_CEA <= '1';
953
              n.scaddr := r.saddr;
954
              saddr_inc := '1';
955
              if saddr_last = '1' then
956
                n.slast := '1';
957
              end if;
958
              if irbact = '1' then        -- pending rbus request ?
959
                n.state := s_idle;          -- than goto dispatcher
960
              end if;
961
            end if;
962
          end if;
963
        end if;
964
 
965
      when s_sloop =>                   -- s_sloop: stop or loop -------------
966
        irb_busy := irbact;
967
        imaddr_chk := r.maddr;
968
        if AWIDTH = 22 and r.swloop = '0' then
969
          imaddr_chk(maddr_f_top4) := (others=>'1');
970
        end if;
971
        if MEM_ACT_R='0' and MEM_ACK_R='0' then  -- wait here till mem read done
972
          if r.sfail='0' and r.sloop='1' and     -- no fail and loop requested ?
973
            imaddr_chk/=c_maddr_ones then        -- and not wrapping
974
              maddr_inc := '1';             -- increment maddr 
975
              n.state := s_sstart;          -- and restart
976
          else                            -- otherwise
977
            ilam   := not r.sfail;          -- signal attention unless fail set
978
            n.srun := '0';                  -- stop sequencer
979
            n.state := s_idle;              -- goto dispatcher
980
          end if;
981
        end if;
982
 
983
      when others => null;
984
    end case;
985
 
986
    if maddr_inc = '1' then
987
      n.maddr := slv(unsigned(r.maddr) + 1);
988
    end if;
989
 
990
    if saddr_inc = '1' then
991
      n.saddr := slv(unsigned(r.saddr) + 1);
992
    end if;
993
 
994
    if swcnt_inc = '1' then
995
      n.swcnt := slv(unsigned(r.swcnt) + 1);
996
    else
997
      n.swcnt := (others=>'0');
998
    end if;
999
 
1000
    if irbact = '0' then                -- if no rbus request, use SWI for mux
1001
      omux_sel := SWI(7 downto 4);
1002
    end if;
1003
 
1004
    case omux_sel is
1005
      when omux_mdil   =>
1006
        omux_dat := r.mdi(df_word0);
1007
      when omux_mdih   =>
1008
        omux_dat := r.mdi(df_word1);
1009
      when omux_memdoh =>
1010
        omux_dat := MEM_DO(df_word1);
1011
      when omux_memdol =>
1012
        omux_dat := MEM_DO(df_word0);
1013
      when omux_maddrh =>
1014
        omux_dat := (others=>'0');
1015
        omux_dat(maddrh_rbf_h) := r.maddr(maddr_f_wh);
1016
      when omux_maddrl =>
1017
        omux_dat := r.maddr(maddr_f_wl);
1018
      when omux_slim =>
1019
        omux_dat := (others=>'0');
1020
        omux_dat(r.slim'range) := r.slim;
1021
      when omux_saddr =>
1022
        omux_dat := (others=>'0');
1023
        omux_dat(r.saddr'range) := r.saddr;
1024
      when omux_sstat =>
1025
        omux_dat := (others=>'0');
1026
        if AWIDTH = 22 then
1027
          omux_dat(sstat_rbf_wide) := '1';
1028
        end if;
1029
        omux_dat(sstat_rbf_wswap) := r.swswap;
1030
        omux_dat(sstat_rbf_wloop) := r.swloop;
1031
        omux_dat(sstat_rbf_loop)  := r.sloop;
1032
        omux_dat(sstat_rbf_xord)  := r.sxord;
1033
        omux_dat(sstat_rbf_xora)  := r.sxora;
1034
        omux_dat(sstat_rbf_veri)  := r.sveri;
1035
        omux_dat(sstat_rbf_fail)  := r.sfail;
1036
        omux_dat(sstat_rbf_run)   := r.srun;
1037
      when omux_seaddr =>
1038
        omux_dat := (others=>'0');
1039
        omux_dat(r.se_addr'range) := r.se_addr;
1040
      when omux_sedath =>
1041
        omux_dat := r.se_data(df_word1);
1042
      when omux_sedatl =>
1043
        omux_dat := r.se_data(df_word0);
1044
      when omux_smemb0 =>
1045
        omux_dat := SMEM_DATA(df_word0);
1046
      when omux_smemb1 =>
1047
        omux_dat := SMEM_DATA(df_word1);
1048
      when omux_smemb2 =>
1049
        omux_dat := SMEM_CMD(df_word0);
1050
      when omux_smemb3 =>
1051
        omux_dat := SMEM_CMD(df_word1);
1052
 
1053
      when others => null;
1054
    end case;
1055
 
1056
    if irbact = '1' then
1057
      irb_dout  := omux_dat;            -- if rbus request, drive dout
1058
    else
1059
      n.dispval := omux_dat;            -- if no rbus request, display mux value
1060
    end if;
1061
 
1062
    N_REGS       <= n;
1063
 
1064
    RB_SRES      <= rb_sres_init;
1065
    RB_SRES.ack  <= irb_ack;
1066
    RB_SRES.busy <= irb_busy;
1067
    RB_SRES.err  <= irb_err;
1068
    RB_SRES.dout <= irb_dout;
1069
 
1070
    MEM_REQ  <= imem_reqr or imem_reqw;
1071
    MEM_WE   <= imem_reqw;
1072
    MEM_BE   <= imem_be;
1073
    MEM_ADDR <= imem_addr;
1074
    MEM_DI   <= imem_di;
1075
 
1076
    RB_LAM   <= ilam;
1077
 
1078
  end process proc_next;
1079
 
1080
  RB_STAT(3) <= '0';
1081
  RB_STAT(2) <= '0';
1082
  RB_STAT(1) <= R_REGS.sfail;
1083
  RB_STAT(0) <= R_REGS.srun;
1084
 
1085
  DSP_DAT   <= R_REGS.dispval;
1086
 
1087
  LED(0) <= MEM_BUSY;
1088
  LED(1) <= MEM_ACT_R;
1089
  LED(2) <= MEM_ACT_W;
1090
  LED(3) <= R_REGS.srun;
1091
  LED(4) <= R_REGS.sfail;
1092
  LED(5) <= R_REGS.sveri;
1093
  LED(6) <= R_REGS.sloop;
1094
  LED(7) <= SWI(3) or SWI(2) or SWI(1) or SWI(0) or
1095
            BTN(0) or BTN(1) or BTN(2) or BTN(3);
1096
 
1097
end syn;

powered by: WebSVN 2.1.0

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