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

Subversion Repositories wb_lpc

[/] [wb_lpc/] [trunk/] [rtl/] [verilog/] [wb_lpc_host.v] - Blame information for rev 3

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

Line No. Rev Author Line
1 3 hharte
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  $Id: wb_lpc_host.v,v 1.1 2008-03-02 20:46:40 hharte Exp $
4
////  wb_lpc_host.v - Wishbone Slave to LPC Host Bridge           ////
5
////                                                              ////
6
////  This file is part of the Wishbone LPC Bridge project        ////
7
////  http://www.opencores.org/projects/wb_lpc/                   ////
8
////                                                              ////
9
////  Author:                                                     ////
10
////      - Howard M. Harte (hharte@opencores.org)                ////
11
////                                                              ////
12
//////////////////////////////////////////////////////////////////////
13
////                                                              ////
14
//// Copyright (C) 2008 Howard M. Harte                           ////
15
////                                                              ////
16
//// This source file may be used and distributed without         ////
17
//// restriction provided that this copyright statement is not    ////
18
//// removed from the file and that any derivative work contains  ////
19
//// the original copyright notice and the associated disclaimer. ////
20
////                                                              ////
21
//// This source file is free software; you can redistribute it   ////
22
//// and/or modify it under the terms of the GNU Lesser General   ////
23
//// Public License as published by the Free Software Foundation; ////
24
//// either version 2.1 of the License, or (at your option) any   ////
25
//// later version.                                               ////
26
////                                                              ////
27
//// This source is distributed in the hope that it will be       ////
28
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
29
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
30
//// PURPOSE.  See the GNU Lesser General Public License for more ////
31
//// details.                                                     ////
32
////                                                              ////
33
//// You should have received a copy of the GNU Lesser General    ////
34
//// Public License along with this source; if not, download it   ////
35
//// from http://www.opencores.org/lgpl.shtml                     ////
36
////                                                              ////
37
//////////////////////////////////////////////////////////////////////
38
 
39
`timescale 1 ns / 1 ns
40
 
41
`include "../../rtl/verilog/wb_lpc_defines.v"
42
 
43
//                                      I/O Write               I/O Read                        DMA Read                        DMA Write
44
//                                                                                                                      
45
//      States - 1. H Start                     H Start                 H Start                 H Start
46
//                              2. H CYCTYPE+DIR        H CYCTYPE+DIR   H CYCTYPE+DIR   H CYCTYPE+DIR
47
//                              3. H Addr (4)           H Addr (4)              H CHAN+TC               H CHAN+TC
48
//                                                                                                                      H SIZE                  H SIZE
49
//                              4. H Data (2)           H TAR  (2)       +-H DATA (2)           H TAR  (2)
50
//                              5. H TAR  (2)           P SYNC (1+)      |      H TAR  (2)       +-P SYNC (1+)
51
//                              6. P SYNC (1+)          P DATA (2)       | H SYNC (1+)   +-P DATA (2)
52
//                              7. P TAR  (2)           P TAR  (2)       +-P TAR  (2)           P TAR
53
//                                                                                                                      
54
module wb_lpc_host(clk_i, nrst_i, wbs_adr_i, wbs_dat_o, wbs_dat_i, wbs_sel_i, wbs_tga_i, wbs_we_i,
55
                                                   wbs_stb_i, wbs_cyc_i, wbs_ack_o,
56
                                                        dma_chan_i, dma_tc_i,
57
                                                   lframe_o, lad_i, lad_o, lad_oe
58
);
59
        // Wishbone Slave Interface
60
        input                   clk_i;
61
        input           nrst_i;                         // Active low reset.
62
        input           [31:0] wbs_adr_i;
63
        output          [31:0] wbs_dat_o;
64
        input           [31:0] wbs_dat_i;
65
        input           [3:0]     wbs_sel_i;
66
        input                   [1:0]     wbs_tga_i;
67
        input           wbs_we_i;
68
        input           wbs_stb_i;
69
        input           wbs_cyc_i;
70
        output reg      wbs_ack_o;
71
 
72
        // LPC Master Interface
73
        output reg      lframe_o;                       // LPC Frame output (active high)
74
        output reg      lad_oe;                         // LPC AD Output Enable
75
        input   [3:0]    lad_i;                          // LPC AD Input Bus
76
        output reg      [3:0] lad_o;             // LPC AD Output Bus
77
 
78
        // DMA-Specific sideband signals
79
        input   [2:0]    dma_chan_i;                     // DMA Channel
80
        input                   dma_tc_i;                       // DMA Terminal Count
81
 
82
        reg     [12:0] state;                            // Current state
83
        reg     [2:0] adr_cnt;                           // Address nibbe counter
84
        reg     [3:0] dat_cnt;                           // Data nibble counter
85
        reg     [2:0] xfr_len;                           // Number of nibbls for transfer
86
        wire    [2:0] byte_cnt = dat_cnt[3:1];   // Byte Counter
87
        wire                    nibble_cnt = dat_cnt[0]; // Nibble counter
88
        reg     [31:0] lpc_dat_i;                        // Temporary storage for input word.
89
 
90
        //
91
        // generate wishbone register signals
92
        wire wbs_acc = wbs_cyc_i & wbs_stb_i;    // Wishbone access
93
        wire wbs_wr  = wbs_acc & wbs_we_i;       // Wishbone write access
94
 
95
        // Memory Cycle (tga== 1'b00) is bit 2=1 for LPC Cycle Type.
96
        wire    mem_xfr = (wbs_tga_i == `WB_TGA_MEM);
97
        wire    dma_xfr = (wbs_tga_i == `WB_TGA_DMA);
98
        wire    fw_xfr  = (wbs_tga_i == `WB_TGA_FW);
99
 
100
        assign wbs_dat_o[31:0] = lpc_dat_i;
101
 
102
        always @(posedge clk_i or negedge nrst_i)
103
                if(~nrst_i)
104
                begin
105
                        state <= `LPC_ST_IDLE;
106
                        lframe_o <= 1'b0;
107
                        wbs_ack_o <= 1'b0;
108
                        lad_oe <= 1'b0;
109
                        lad_o <= 4'b0;
110
                        adr_cnt <= 3'b0;
111
                        dat_cnt <= 4'h0;
112
                        xfr_len <= 3'b000;
113
                        lpc_dat_i <= 32'h00000000;
114
                end
115
                else begin
116
                        case(state)
117
                                `LPC_ST_IDLE:
118
                                        begin
119
                                                wbs_ack_o <= 1'b0;
120
                                                lframe_o <= 1'b0;
121
                                                dat_cnt <= 4'h0;
122
 
123
                                                if(wbs_acc)             // Wishbone access starts LPC transaction
124
                                                        state <= `LPC_ST_START;
125
                                                else
126
                                                        state <= `LPC_ST_IDLE;
127
                                        end
128
                                `LPC_ST_START:
129
                                        begin
130
                                                lframe_o <= 1'b1;
131
                                                if(~fw_xfr) begin               // For Memory and I/O Cycles
132
                                                        lad_o   <= `LPC_START;
133
                                                        state   <= `LPC_ST_CYCTYP;
134
                                                end
135
                                                else begin                              // Firmware Read and Write Cycles
136
                                                        if(wbs_wr)
137
                                                                lad_o <= `LPC_FW_WRITE;
138
                                                        else
139
                                                                lad_o <= `LPC_FW_READ;
140
 
141
                                                        state   <= `LPC_ST_ADDR;
142
                                                end
143
                                                lad_oe  <= 1'b1;
144
                                                adr_cnt <= ((mem_xfr | fw_xfr) ? 3'b000 : 3'b100);
145
                                        end
146
                                `LPC_ST_CYCTYP:
147
                                        begin
148
                                                lframe_o        <= 1'b0;
149
                                                lad_oe  <= 1'b1;
150
 
151
                                                if(~dma_xfr)
152
                                                        begin
153
                                                                lad_o   <= {1'b0,mem_xfr,wbs_wr,1'b0};          // Cycle Type/Direction for I/O or MEM
154
                                                                state           <= `LPC_ST_ADDR;
155
                                                        end
156
                                                else // it is DMA
157
                                                        begin
158
                                                                lad_o   <= {1'b1,1'b0,~wbs_wr,1'b0};            // Cycle Type/Direction for DMA, r/w is inverted for DMA
159
                                                                state           <= `LPC_ST_CHAN;
160
                                                        end
161
                                        end
162
                                `LPC_ST_ADDR:   // Output four nubbles of address.
163
                                        begin
164
                                                lframe_o <= 1'b0;               // In case we came here from a Firmware cycle, which skips CYCTYP.
165
 
166
                                                // The LPC Bus Address is sent across the bus a nibble at a time;
167
                                                // however, the most significant nibble is sent first.  For firmware and
168
                                                // memory cycles, the address is 32-bits.  Actually, for memeory accesses,
169
                                                // the most significant nibble is known as the IDSEL field.  For I/O,
170
                                                // the address is only 16-bits wide.
171
                                                case(adr_cnt)
172
                                                        3'h0:
173
                                                                lad_o <= wbs_adr_i[31:28];
174
                                                        3'h1:
175
                                                                lad_o <= wbs_adr_i[27:24];
176
                                                        3'h2:
177
                                                                lad_o <= wbs_adr_i[23:20];
178
                                                        3'h3:
179
                                                                lad_o <= wbs_adr_i[19:16];
180
                                                        3'h4:
181
                                                                lad_o <= wbs_adr_i[15:12];
182
                                                        3'h5:
183
                                                                lad_o <= wbs_adr_i[11:8];
184
                                                        3'h6:
185
                                                                lad_o <= wbs_adr_i[7:4];
186
                                                        3'h7:
187
                                                                lad_o <= wbs_adr_i[3:0];
188
                                                endcase
189
 
190
                                                adr_cnt <= adr_cnt + 1;
191
 
192
                                                if(adr_cnt == 4'h7) // Last address nibble.
193
                                                        begin
194
                                                                if(~fw_xfr)
195
                                                                        if(wbs_wr)
196
                                                                                state <= `LPC_ST_H_DATA;
197
                                                                        else
198
                                                                                state <= `LPC_ST_H_TAR1;
199
                                                                else    // For firmware read/write, we need to transfer the MSIZE nibble
200
                                                                        state <= `LPC_ST_SIZE;
201
                                                        end
202
                                                else
203
                                                        state <= `LPC_ST_ADDR;
204
 
205
                                                lad_oe  <= 1'b1;
206
                                                xfr_len         <= 3'b001;              // One Byte Transfer
207
                                        end
208
                                `LPC_ST_CHAN:
209
                                        begin
210
                                                lad_o   <= {dma_tc_i, dma_chan_i};
211
                                                state <= `LPC_ST_SIZE;
212
                                        end
213
                                `LPC_ST_SIZE:
214
                                        begin
215
                                                case(wbs_sel_i)
216
                                                        `WB_SEL_BYTE:
217
                                                                begin
218
                                                                        xfr_len <= 3'b001;
219
                                                                        lad_o <= 4'h0;
220
                                                                end
221
                                                        `WB_SEL_SHORT:
222
                                                                begin
223
                                                                        xfr_len <= 3'b010;
224
                                                                        lad_o <= 4'h1;
225
                                                                end
226
                                                        `WB_SEL_WORD:
227
                                                                begin
228
                                                                        xfr_len <= 3'b100;
229
                                                                        if(fw_xfr)                              // Firmware transfer uses '2' for 4-byte transfer.
230
                                                                                lad_o <= 4'h2;
231
                                                                        else                                            // DMA uses '3' for 4-byte transfer.
232
                                                                                lad_o <= 4'h3;
233
                                                                end
234
                                                        default:
235
                                                                begin
236
                                                                        xfr_len <= 3'b001;
237
                                                                        lad_o <= 4'h0;
238
                                                                end
239
                                                endcase
240
                                                if(wbs_wr)
241
                                                        state <= `LPC_ST_H_DATA;
242
                                                else
243
                                                        state <= `LPC_ST_H_TAR1;
244
                                        end
245
 
246
                                `LPC_ST_H_DATA:
247
                                        begin
248
                                                lad_oe  <= 1'b1;
249
                                                case(dat_cnt)   // We only support a single byte for I/O.
250
                                                        4'h0:
251
                                                                lad_o <= wbs_dat_i[3:0];
252
                                                        4'h1:
253
                                                                lad_o <= wbs_dat_i[7:4];
254
                                                        4'h2:
255
                                                                lad_o <= wbs_dat_i[11:8];
256
                                                        4'h3:
257
                                                                lad_o <= wbs_dat_i[15:12];
258
                                                        4'h4:
259
                                                                lad_o <= wbs_dat_i[19:16];
260
                                                        4'h5:
261
                                                                lad_o <= wbs_dat_i[23:20];
262
                                                        4'h6:
263
                                                                lad_o <= wbs_dat_i[27:24];
264
                                                        4'h7:
265
                                                                lad_o <= wbs_dat_i[31:28];
266
                                                        default:
267
                                                                lad_o <= 4'hx;
268
                                                endcase
269
 
270
                                                dat_cnt <= dat_cnt + 1;
271
 
272
                                                if(nibble_cnt == 1'b1) // end of byte
273
                                                        begin
274
                                                                state <= `LPC_ST_H_TAR1;
275
                                                        end
276
                                                else
277
                                                        state <= `LPC_ST_H_DATA;
278
                                        end
279
 
280
                                `LPC_ST_H_TAR1:
281
                                        begin
282
                                                lad_o <= 4'b1111;               // Drive LAD high
283
                                                lad_oe <= 1'b1;
284
                                                state <= `LPC_ST_H_TAR2;
285
                                        end
286
                                `LPC_ST_H_TAR2:
287
                                        begin
288
                                                lad_oe <= 1'b0;         // float LAD
289
                                                state <= `LPC_ST_SYNC;
290
                                        end
291
                                `LPC_ST_SYNC:
292
                                        begin
293
                                                lad_oe <= 1'b0;         // float LAD
294
                                                if(lad_i == `LPC_SYNC_READY) begin
295
                                                        if(wbs_wr) begin
296
                                                                state <= `LPC_ST_P_TAR1;
297
                                                        end
298
                                                        else
299
                                                                state <= `LPC_ST_P_DATA;
300
                                                        end
301
                                                else
302
                                                        state <= `LPC_ST_SYNC;
303
                                        end
304
 
305
                                `LPC_ST_P_DATA:
306
                                        begin
307
                                                case(dat_cnt)
308
                                                        4'h0:
309
                                                                lpc_dat_i[3:0] <= lad_i;
310
                                                        4'h1:
311
                                                                lpc_dat_i[7:4] <= lad_i;
312
                                                        4'h2:
313
                                                                lpc_dat_i[11:8] <= lad_i;
314
                                                        4'h3:
315
                                                                lpc_dat_i[15:12] <= lad_i;
316
                                                        4'h4:
317
                                                                lpc_dat_i[19:16] <= lad_i;
318
                                                        4'h5:
319
                                                                lpc_dat_i[23:20] <= lad_i;
320
                                                        4'h6:
321
                                                                lpc_dat_i[27:24] <= lad_i;
322
                                                        4'h7:
323
                                                                lpc_dat_i[31:28] <= lad_i;
324
                                                endcase
325
 
326
                                                dat_cnt <= dat_cnt + 1;
327
 
328
                                                if(nibble_cnt == 1'b1)                          // Byte transfer complete
329
                                                        if (byte_cnt == xfr_len-1)      // End of data transfer phase
330
                                                                state <= `LPC_ST_P_TAR1;
331
                                                        else
332
                                                                state <= `LPC_ST_SYNC;
333
                                                else                                                                            // Go to next nibble
334
                                                        state <= `LPC_ST_P_DATA;
335
                                        end
336
                                `LPC_ST_P_TAR1:
337
                                        begin
338
                                                lad_oe <= 1'b0;
339
//                                              state <= `LPC_ST_P_TAR2;
340
//                                      end
341
//                              `LPC_ST_P_TAR2:
342
//                                      begin
343
//                                              lad_oe <= 1'b0;         // float LAD
344
                                                if(byte_cnt == xfr_len) begin
345
                                                        state <= `LPC_ST_IDLE;
346
                                                        wbs_ack_o <= wbs_acc;
347
                                                end
348
                                                else begin
349
                                                        if(wbs_wr) begin        // DMA READ (Host to Peripheral)
350
                                                                state <= `LPC_ST_H_DATA;
351
                                                        end
352
                                                        else begin      // unhandled READ case
353
                                                                state <= `LPC_ST_IDLE;
354
                                                        end
355
                                                end
356
                                        end
357
                        endcase
358
                end
359
 
360
endmodule
361
 
362
 

powered by: WebSVN 2.1.0

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