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

Subversion Repositories sd_mmc_emulator

[/] [sd_mmc_emulator/] [trunk/] [rtl/] [registers.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jclaytons
// $Id: registers.v 912 2015-05-14 21:41:57Z nxp20190 $
2
//
3
// @brief Sango X7 Main SPI registers.
4
//
5
// @Author Roger Williams <roger.williams@nxp.com>
6
//
7
// (c) 2015 NXP Semiconductors. All rights reserved.
8
//
9
// PROPRIETARY INFORMATION
10
//
11
// The information contained in this file is the property of NXP Semiconductors.
12
// Except as specifically authorized in writing by NXP, the holder of this file:
13
// (1) shall keep all information contained herein confidential and shall protect
14
// same in whole or in part from disclosure and dissemination to all third parties
15
// and (2) shall use same for operation and maintenance purposes only.
16
// -----------------------------------------------------------------------------
17
// 0.03.1  2015-05-14 (RAW) Hard-code some parameters to get this working today
18
// 0.03.0  2015-05-13 (RAW) Adapted from XCtrl4 code for initial X7
19
//------------------------------------------------------------------------------
20
 
21
`include "registers_def.v"
22
`include "timescale.v"
23
 
24
module tg_registers
25
  (
26
   input                        clk_i, rst_i, we_i, oe_i, cs_i,
27
   input [3:0]                   adr_i,
28
   input [15:0]                  dat_i,
29
   output reg [15:0]             dat_o = 16'b0,
30
   input [`TG_REG_BITS_R]       reg_r,
31
   output [`TG_REG_BITS_W]      reg_w,
32
   output [`TG_REG_BITS_CTL]    reg_ctl
33
   );
34
 
35
   reg [15:0]                    dat_i_sync = 16'b0;
36
   reg [15:0]                    dat_i_dly = 16'b0;
37
   reg [3:0]                     addr_keep = 4'b0;
38
   reg                          wr_keep = 1'b0;
39
   reg                          rd_keep = 1'b0;
40
   reg                          wr_dly = 1'b0;
41
   reg                          wr_dly1 = 1'b0;
42
   reg                          w_strobe = 1'b0;
43
   reg                          w_strobe_dly = 1'b0;
44
   wire                         wr_strobe = wr_dly & ~wr_dly1;
45
 
46
   // RW registers, strobes
47
   reg [15:0]                    tctrl = 16'h0000;
48
   reg                          tctrl_ld = 1'b0;
49
/* -----\/----- EXCLUDED -----\/-----
50
   reg [31:0]                   tqueue = 32'h00000000;
51
 -----/\----- EXCLUDED -----/\----- */
52
   reg [15:0]                    tqueue = 16'h0000; // HACK!
53
   reg                          tqueue_ld = 1'b0;
54
/* -----\/----- EXCLUDED -----\/-----
55
   reg                          tqueue_ld_dly = 1'b0;
56
 -----/\----- EXCLUDED -----/\----- */
57
   reg [15:0]                    mctrl = 16'h0000;
58
   reg                          mctrl_ld = 1'b0;
59
   reg [15:0]                    mconf = 16'h0400;
60
   reg                          mconf_ld = 1'b0;
61
   reg [15:0]                    debug = 16'h0000;
62
   reg                          debug_ld = 1'b0;
63
/* -----\/----- EXCLUDED -----\/-----
64
   reg [15:0]                   wr_multi = 16'b00;
65
   reg                          wr_multi_ld = 1'b0;
66
   reg [15:0]                   rd_multi = 16'b0;
67
 -----/\----- EXCLUDED -----/\----- */
68
   reg                          mqueue_rd = 0;
69
 
70
   assign reg_w = {debug, mconf, mctrl, tqueue, tctrl, dat_i_dly};
71
/* -----\/----- EXCLUDED -----\/-----
72
   assign reg_ctl = {mqueue_rd, tqueue_ld | tqueue_ld_dly};
73
 -----/\----- EXCLUDED -----/\----- */
74
   assign reg_ctl = {mqueue_rd, tqueue_ld};     // HACK!
75
 
76
   // synchronise inputs
77
   always @ (posedge clk_i)
78
     if (rst_i) begin
79
        rd_keep <= 0;
80
        wr_keep <= 0;
81
        addr_keep <= 0;
82
     end
83
     else begin
84
        rd_keep <= cs_i & oe_i;
85
        wr_keep <= cs_i & we_i;
86
        if (rd_keep | wr_keep)
87
          addr_keep <= adr_i;
88
     end
89
 
90
   // write pipeline
91
   always @ (posedge clk_i)
92
     if (rst_i) begin
93
        wr_dly <= 0;
94
        wr_dly1 <= 0;
95
        dat_i_sync <= 0;
96
     end
97
     else begin
98
        wr_dly <= wr_keep;
99
        wr_dly1 <= wr_dly;
100
        dat_i_dly <= dat_i_sync;
101
        if (wr_keep)
102
          dat_i_sync <= dat_i;
103
     end
104
 
105
   // address decoding
106
   always @ (posedge clk_i)
107
     if (rst_i) begin
108
        tctrl_ld <= 0;
109
        tqueue_ld <= 0;
110
        mctrl_ld <= 0;
111
        debug_ld <= 0;
112
        mconf_ld <= 0;
113
/* -----\/----- EXCLUDED -----\/-----
114
        wr_multi_ld <= 0;
115
 -----/\----- EXCLUDED -----/\----- */
116
        mqueue_rd <= 0;
117
        w_strobe <= 0;
118
/* -----\/----- EXCLUDED -----\/-----
119
        tqueue_ld_dly <= 0;
120
 -----/\----- EXCLUDED -----/\----- */
121
     end
122
     else begin
123
        tctrl_ld <= wr_strobe & (addr_keep == `TG_TCTRL_AD);
124
/* -----\/----- EXCLUDED -----\/-----
125
        tqueue_ld <= wr_strobe & (addr_keep == (`TG_TQUEUE_AD | 5'd2));
126
 -----/\----- EXCLUDED -----/\----- */
127
        tqueue_ld <= wr_strobe & (addr_keep == `TG_TQUEUE_AD); // HACK!
128
        mctrl_ld <= wr_strobe & (addr_keep == `TG_MCTRL_AD);
129
        mconf_ld <= wr_strobe & (addr_keep == `TG_MCONF_AD);
130
        debug_ld <= wr_strobe & (addr_keep == `TG_DEBUG_AD);
131
/* -----\/----- EXCLUDED -----\/-----
132
        wr_multi_ld <= wr_strobe & (addr_keep == `TG_TQUEUE_AD);
133
 -----/\----- EXCLUDED -----/\----- */
134
        mqueue_rd <= rd_keep & (addr_keep == `TG_MQUEUE_AD);
135
        w_strobe <= tctrl_ld | mctrl_ld;
136
/* -----\/----- EXCLUDED -----\/-----
137
        tqueue_ld_dly <= tqueue_ld;
138
 -----/\----- EXCLUDED -----/\----- */
139
     end
140
 
141
   // W writes need to be valid for 2 clk200 cycles
142
   always @ (posedge clk_i)
143
     if (rst_i) begin
144
        tctrl <= 0;
145
        mctrl <= 0;
146
        w_strobe_dly <= 0;
147
     end
148
     else begin
149
        w_strobe_dly <= w_strobe;
150
        if (w_strobe_dly) begin
151
           tctrl <= 0;
152
           mctrl <= 0;
153
        end
154
        else begin
155
           if (tctrl_ld)
156
             tctrl <= dat_i_dly;
157
           if (mctrl_ld)
158
             mctrl <= dat_i_dly;
159
        end
160
     end
161
 
162
   // RW writes
163
   always @ (posedge clk_i)
164
     if (rst_i) begin
165
        mconf <= 16'h0400;
166
        debug <= 16'h0000;
167
/* -----\/----- EXCLUDED -----\/-----
168
        wr_multi <= 0;
169
        tqueue <= 32'h00000000;
170
 -----/\----- EXCLUDED -----/\----- */
171
        tqueue <= 16'h0000;                     // HACK!
172
     end
173
     else begin
174
        if (debug_ld)
175
          debug <= dat_i_dly;
176
        if (mconf_ld)
177
          mconf <= dat_i_dly;
178
/* -----\/----- EXCLUDED -----\/-----
179
        if (wr_multi_ld)
180
          wr_multi <= dat_i_dly;
181
 -----/\----- EXCLUDED -----/\----- */
182
        if (tqueue_ld) begin
183
/* -----\/----- EXCLUDED -----\/-----
184
           tqueue[31:16] <= dat_i_dly;
185
           tqueue[15:0] <= wr_multi;
186
 -----/\----- EXCLUDED -----/\----- */
187
           tqueue <= dat_i_dly;                 // HACK!
188
        end
189
     end
190
 
191
   // reads for RW and R registers
192
   always @ (posedge clk_i)
193
     if (rst_i) begin
194
        dat_o <= 0;
195
/* -----\/----- EXCLUDED -----\/-----
196
        rd_multi <= 0;
197
 -----/\----- EXCLUDED -----/\----- */
198
     end
199
     else if (rd_keep)
200
       case (addr_keep)
201
         `TG_TQ_STAT_AD: dat_o <= reg_r[`TG_TQ_STAT_INDEX];
202
         `TG_MQ_STAT_AD: dat_o <= reg_r[`TG_MQ_STAT_INDEX];
203
         `TG_DEBUG_AD: dat_o <= debug;
204
         `TG_MCONF_AD: dat_o <= mconf;
205
         `TG_MQUEUE_AD: dat_o <= reg_r[`TG_MQUEUE_INDEX];
206
/* -----\/----- EXCLUDED -----\/-----
207
         `TG_TQUEUE_AD: {rd_multi, dat_o} <= tqueue; // verify correct order
208
         `TG_TQUEUE_AD + 2: dat_o <= rd_multi;
209
 -----/\----- EXCLUDED -----/\----- */
210
         `TG_TQUEUE_AD: dat_o <= reg_r[`TG_TQUEUE_INDEX]; // HACK!
211
         default: dat_o <= 0;
212
       endcase
213
 
214
endmodule
215
 
216
module registers
217
  (
218
   input                        clk_i, rst_i, we_i, oe_i, cs_i,
219
   input [5:0]                   adr_i,
220
   input [15:0]                  dat_i,
221
   output reg [15:0]             dat_o = 16'b0,
222
   input [`REG_BITS_R]          reg_r,
223
   output [`REG_BITS_W]         reg_w
224
   );
225
 
226
   reg [15:0]                    dat_i_sync = 16'b0;
227
   reg [15:0]                    dat_i_dly = 16'b0;
228
   reg [5:0]                     addr_keep = 6'b0;
229
   reg                          wr_keep = 1'b0;
230
   reg                          rd_keep = 1'b0;
231
   reg                          wr_dly = 1'b0;
232
   reg                          wr_dly1 = 1'b0;
233
   reg                          w_strobe = 1'b0;
234
   reg                          w_strobe_dly = 1'b0;
235
   wire                         wr_strobe = wr_dly & ~wr_dly1;
236
 
237
   // RW registers, strobes
238
   reg [15:0]                    conf = 16'b0;
239
   reg                          conf_ld = 1'b0;
240
   reg [15:0]                    trig_src = 16'b0;
241
   reg                          trig_src_ld = 1'b0;
242
   reg [15:0]                    ctrl = 16'b0;
243
   reg                          ctrl_ld = 1'b0;
244
   reg [15:0]                    irq_mask = 16'b0;
245
   reg                          irq_mask_ld = 1'b0;
246
   reg [15:0]                    irq_clr = 16'b0;
247
   reg                          irq_clr_ld = 1'b0;
248
   reg [15:0]                    sync = 16'b0;
249
   reg                          sync_ld = 1'b0;
250
   reg [15:0]                    filter = 16'd10000;
251
   reg                          filter_ld = 1'b0;
252
 
253
   assign reg_w = {filter, sync, irq_clr, irq_mask, ctrl, trig_src, conf, dat_i_dly};
254
 
255
   // synchronise inputs
256
   always @ (posedge clk_i)
257
     if (rst_i) begin
258
        rd_keep <= 0;
259
        wr_keep <= 0;
260
        addr_keep <= 0;
261
     end
262
     else begin
263
        rd_keep <= cs_i & oe_i;
264
        wr_keep <= cs_i & we_i;
265
        if (rd_keep | wr_keep)
266
          addr_keep <= adr_i;
267
     end
268
 
269
   // write pipeline
270
   always @ (posedge clk_i)
271
     if (rst_i) begin
272
        wr_dly <= 0;
273
        wr_dly1 <= 0;
274
        dat_i_sync <= 0;
275
     end
276
     else begin
277
        wr_dly <= wr_keep;
278
        wr_dly1 <= wr_dly;
279
        dat_i_dly <= dat_i_sync;
280
        if (wr_keep)
281
          dat_i_sync <= dat_i;
282
     end
283
 
284
   // address decoding
285
   always @ (posedge clk_i)
286
     if (rst_i) begin
287
        conf_ld <= 0;
288
        trig_src_ld <= 0;
289
        ctrl_ld <= 0;
290
        irq_mask_ld <= 0;
291
        irq_clr_ld <= 0;
292
        sync_ld <= 0;
293
        filter_ld <= 0;
294
        w_strobe <= 0;
295
     end
296
     else begin
297
        conf_ld <= wr_strobe & (addr_keep == `CONF_AD);
298
        trig_src_ld <= wr_strobe & (addr_keep == `TRIG_SRC_AD);
299
        ctrl_ld <= wr_strobe & (addr_keep == `CTRL_AD);
300
        irq_mask_ld <= wr_strobe & (addr_keep == `IRQ_MASK_AD);
301
        irq_clr_ld <= wr_strobe & (addr_keep == `IRQ_CLR_AD);
302
        sync_ld <= wr_strobe & (addr_keep == `SYNC_AD);
303
        filter_ld <= wr_strobe & (addr_keep == `FILTER_AD);
304
        w_strobe <= ctrl_ld | irq_clr_ld;
305
     end
306
 
307
   // W writes
308
   always @ (posedge clk_i)
309
     if (rst_i) begin
310
        ctrl <= 0;
311
        irq_clr <= 0;
312
        w_strobe_dly <= 0;
313
     end
314
     else begin
315
        w_strobe_dly <= w_strobe;
316
        if (w_strobe_dly) begin
317
           ctrl <= 0;
318
           irq_clr <= 0;
319
        end
320
        else begin
321
           if (ctrl_ld)
322
             ctrl <= dat_i_dly;
323
           if (irq_clr_ld)
324
             irq_clr <= dat_i_dly;
325
        end
326
     end
327
 
328
   // RW writes
329
   always @ (posedge clk_i)
330
     if (rst_i) begin
331
        conf <= 16'h0000;
332
        trig_src <= 16'h0000;
333
        irq_mask <= 16'h0000;
334
        sync <= 16'h0000;
335
        filter <= 16'd10000;
336
     end
337
     else begin
338
        if (conf_ld)
339
          conf <= dat_i_dly;
340
        if (trig_src_ld)
341
          trig_src <= dat_i_dly;
342
        if (irq_mask_ld)
343
          irq_mask <= dat_i_dly;
344
        if (sync_ld)
345
          sync <= dat_i_dly;
346
        if (filter_ld)
347
          filter <= dat_i_dly;
348
     end
349
 
350
   // reads for RW and R registers
351
   always @ (posedge clk_i)
352
     if (rst_i) begin
353
        dat_o <= 0;
354
     end
355
     else if (rd_keep)
356
       case (addr_keep)
357
         `STAT_AD: dat_o <= reg_r[`STAT_INDEX];
358
         `IRQ_AD: dat_o <= reg_r[`IRQ_INDEX];
359
         `VERSION_AD: dat_o <= reg_r[`VERSION_INDEX];
360
         `CONF_AD: dat_o <= conf;
361
         `TRIG_SRC_AD: dat_o <= trig_src;
362
         `IRQ_MASK_AD: dat_o <= irq_mask;
363
         `SYNC_AD: dat_o <= sync;
364
         `FILTER_AD: dat_o <= filter;
365
         default: dat_o <= 0;
366
       endcase
367
 
368
endmodule

powered by: WebSVN 2.1.0

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