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

Subversion Repositories zap

[/] [zap/] [trunk/] [src/] [rtl/] [cpu/] [zap_wb_adapter.v] - Blame information for rev 43

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

Line No. Rev Author Line
1 26 Revanth
// -----------------------------------------------------------------------------
2
// --                                                                         --
3
// --                   (C) 2016-2018 Revanth Kamaraj.                        --
4
// --                                                                         -- 
5
// -- --------------------------------------------------------------------------
6
// --                                                                         --
7
// -- This program is free software; you can redistribute it and/or           --
8
// -- modify it under the terms of the GNU General Public License             --
9
// -- as published by the Free Software Foundation; either version 2          --
10
// -- of the License, or (at your option) any later version.                  --
11
// --                                                                         --
12
// -- This program is distributed in the hope that it will be useful,         --
13
// -- but WITHOUT ANY WARRANTY; without even the implied warranty of          --
14
// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           --
15
// -- GNU General Public License for more details.                            --
16
// --                                                                         --
17
// -- You should have received a copy of the GNU General Public License       --
18
// -- along with this program; if not, write to the Free Software             --
19
// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA           --
20
// -- 02110-1301, USA.                                                        --
21
// --                                                                         --
22
// -----------------------------------------------------------------------------
23
// --                                                                         --
24
// --  Implements store FIFO. Serves as a bridge between the processor core & --
25
// --  the memory interface.                                                  --
26
// --                                                                         --
27
// -----------------------------------------------------------------------------
28
 
29
`default_nettype none
30
 
31
module zap_wb_adapter #(parameter DEPTH = 32) (
32
 
33
// Clock.
34
input wire                   i_clk,
35
input wire                   i_reset,
36
 
37
// Processor Wishbone interface. These come from the Wishbone registered
38
// interface.
39
input wire                   I_WB_CYC,
40
input wire                   I_WB_STB,
41
input wire [3:0]             I_WB_SEL,
42
input wire [2:0]             I_WB_CTI,
43
input wire [31:0]            I_WB_ADR,
44
input wire [31:0]            I_WB_DAT,
45
input wire                   I_WB_WE,
46 29 Revanth
output reg [31:0]            O_WB_DAT,
47
output reg                   O_WB_ACK,
48 26 Revanth
 
49
// Wishbone interface.
50
output reg                   o_wb_cyc,
51
output reg                   o_wb_stb,
52
output wire     [31:0]       o_wb_dat,
53
output wire     [31:0]       o_wb_adr,
54
output wire     [3:0]        o_wb_sel,
55
output wire     [2:0]        o_wb_cti,
56
output wire                  o_wb_we,
57
input wire      [31:0]       i_wb_dat,
58 43 Revanth
input wire                   i_wb_ack,
59 26 Revanth
 
60 43 Revanth
output reg                   o_wb_stb_nxt,
61
output reg                   o_wb_cyc_nxt,
62
output wire     [3:0]        o_wb_sel_nxt,
63
output wire     [31:0]       o_wb_dat_nxt,
64
output wire     [31:0]       o_wb_adr_nxt,
65
output wire                  o_wb_we_nxt
66
 
67 26 Revanth
);
68
 
69
`include "zap_defines.vh"
70
`include "zap_localparams.vh"
71
 
72
reg  fsm_write_en;
73
reg  [69:0] fsm_write_data;
74
wire w_eob;
75
wire w_full;
76 43 Revanth
wire w_eob_nxt;
77 26 Revanth
 
78
assign    o_wb_cti = {w_eob, 1'd1, w_eob};
79
 
80
wire w_emp;
81
 
82
// {SEL, DATA, ADDR, EOB, WEN} = 4 + 64 + 1 + 1 = 70 bit.
83 43 Revanth
zap_sync_fifo #(.WIDTH(70), .DEPTH(DEPTH), .FWFT(1'd0), .PROVIDE_NXT_DATA(1)) U_STORE_FIFO (
84 26 Revanth
.i_clk          (i_clk),
85
.i_reset        (i_reset),
86
.i_ack          ((i_wb_ack && o_wb_stb) || emp_ff),
87
.i_wr_en        (fsm_write_en),
88
.i_data         (fsm_write_data),
89 43 Revanth
.o_data         ({o_wb_sel,     o_wb_dat,     o_wb_adr,     w_eob,     o_wb_we}),
90
.o_data_nxt     ({o_wb_sel_nxt, o_wb_dat_nxt, o_wb_adr_nxt, w_eob_nxt, o_wb_we_nxt}),
91 26 Revanth
.o_empty        (w_emp),
92
.o_full         (w_full),
93
.o_empty_n      (),
94
.o_full_n       (),
95
.o_full_n_nxt   ()
96
);
97
 
98 43 Revanth
reg emp_nxt;
99 26 Revanth
reg emp_ff;
100
reg [31:0] ctr_nxt, ctr_ff;
101
reg [31:0] dff, dnxt;
102
reg ack;        // ACK write channel.
103
reg ack_ff;     // Read channel.
104
 
105
localparam IDLE = 0;
106
localparam PRPR_RD_SINGLE = 1;
107
localparam PRPR_RD_BURST = 2;
108
localparam WRITE = 3;
109
localparam WAIT1 = 5;
110
localparam WAIT2 = 6;
111
localparam NUMBER_OF_STATES = 7;
112
 
113
reg [$clog2(NUMBER_OF_STATES)-1:0] state_ff, state_nxt;
114
 
115 43 Revanth
// FIFO pipeline register and nxt state logic.
116
always @ (*)
117 26 Revanth
begin
118 43 Revanth
        emp_nxt      = emp_ff;
119
        o_wb_stb_nxt = o_wb_stb;
120
        o_wb_cyc_nxt = o_wb_cyc;
121
 
122
        if ( i_reset )
123 26 Revanth
        begin
124 43 Revanth
                emp_nxt      = 1'd1;
125
                o_wb_stb_nxt = 1'd0;
126
                o_wb_cyc_nxt = 1'd0;
127 26 Revanth
        end
128 43 Revanth
        else if ( emp_ff || (i_wb_ack && o_wb_stb) )
129 26 Revanth
        begin
130 43 Revanth
                emp_nxt      = w_emp;
131
                o_wb_stb_nxt = !w_emp;
132
                o_wb_cyc_nxt = !w_emp;
133 26 Revanth
        end
134
end
135
 
136 43 Revanth
always @ (posedge i_clk)
137
begin
138
        emp_ff   <= emp_nxt;
139
        o_wb_stb <= o_wb_stb_nxt;
140
        o_wb_cyc <= o_wb_cyc_nxt;
141
end
142
 
143 26 Revanth
// Flip flop clocking block.
144
always @ (posedge i_clk)
145
begin
146
        if ( i_reset )
147
        begin
148
                state_ff <= IDLE;
149
                ctr_ff   <= 0;
150
                dff      <= 0;
151
        end
152
        else
153
        begin
154
                state_ff <= state_nxt;
155
                ctr_ff   <= ctr_nxt;
156
                dff      <= dnxt;
157
        end
158
end
159
 
160
// Reads from the Wishbone bus are flopped.
161
always @ (posedge i_clk)
162
begin
163
        if ( i_reset )
164
        begin
165
                ack_ff  <= 1'd0;
166
        end
167
        else if ( !o_wb_we && o_wb_cyc && o_wb_stb && i_wb_ack )
168
        begin
169
                ack_ff   <= 1'd1;
170
                O_WB_DAT <= i_wb_dat;
171
        end
172
        else
173
        begin
174
                ack_ff <= 1'd0;
175
        end
176
end
177
 
178
localparam BURST_LEN = 4;
179
 
180
// OR from flop and mealy FSM output.
181
always @* O_WB_ACK = ack_ff | ack;
182
 
183
// State machine.
184
always @*
185
begin
186
        state_nxt = state_ff;
187
        ctr_nxt = ctr_ff;
188
        ack = 0;
189
        dnxt = dff;
190
        fsm_write_en = 0;
191
        fsm_write_data = 0;
192
 
193
        case(state_ff)
194
        IDLE:
195
        begin
196
                ctr_nxt = 0;
197
                dnxt = 0;
198
 
199
                if ( I_WB_STB && I_WB_WE && !o_wb_stb ) // Wishbone write request 
200
                begin
201
                        // Simply buffer stores into the FIFO.
202
                        state_nxt = WRITE;
203
                end
204
                else if ( I_WB_STB && !I_WB_WE && !o_wb_stb ) // Wishbone read request
205
                begin
206
                        // Write a set of reads into the FIFO.
207
                        if ( I_WB_CTI == CTI_BURST ) // Burst of 4 words. Each word is 4 byte.
208
                        begin
209
                                state_nxt = PRPR_RD_BURST;
210 43 Revanth
                                $display($time, " - %m :: Read burst requested. Base address = %x", I_WB_ADR);
211 26 Revanth
                        end
212
                        else // Single.
213
                        begin
214
                                state_nxt = PRPR_RD_SINGLE;
215
                        end
216
                end
217
        end
218
 
219
        PRPR_RD_SINGLE: // Write a single read token into the FIFO.
220
        begin
221
                if ( !w_full )
222
                begin
223
                        state_nxt = WAIT1;
224
                        fsm_write_en = 1'd1;
225
                        fsm_write_data = {      I_WB_SEL,
226
                                                I_WB_DAT,
227
                                                I_WB_ADR,
228
                                                I_WB_CTI != CTI_BURST ? 1'd1 : 1'd0,
229
                                                1'd0};
230
                end
231
        end
232
 
233
        PRPR_RD_BURST: // Write burst read requests into the FIFO.
234
        begin
235
                if ( O_WB_ACK )
236
                begin
237
                        dnxt = dff + 1'd1;
238 43 Revanth
                        $display($time, " - %m :: Early response received for read burst. Data received %x", O_WB_DAT);
239 26 Revanth
                end
240
 
241
                if ( ctr_ff == BURST_LEN * 4 )
242
                begin
243
                        ctr_nxt = 0;
244
                        state_nxt = WAIT2; // FIFO prep done.
245
                end
246
                else if ( !w_full )
247
                begin: blk1
248
                        reg [31:0] adr;
249
                        adr = {I_WB_ADR[31:4], 4'd0} + ctr_ff; // Ignore lower 4-bits.
250
 
251
                        fsm_write_en = 1'd1;
252
                        fsm_write_data = {      I_WB_SEL,
253
                                                I_WB_DAT,
254
                                                adr,
255
                                                ctr_ff == 12 ? 1'd1 : 1'd0,
256
                                                1'd0 };
257
                        ctr_nxt = ctr_ff + 4;
258
 
259 43 Revanth
                        $display($time, " - %m :: Read Burst. Writing data SEL = %x DATA = %x ADDR = %x EOB = %x WEN = %x to the FIFO",
260
                        fsm_write_data[69:66], fsm_write_data[65:34], fsm_write_data[33:2], fsm_write_data[1], fsm_write_data[0]);
261 26 Revanth
                end
262
        end
263
 
264
        WRITE:
265
        begin
266
                // As long as requests exist, write them out to the FIFO.
267
                if ( I_WB_STB && I_WB_WE )
268
                begin
269
                        if ( !w_full )
270
                        begin
271
                                fsm_write_en    = 1'd1;
272
                                fsm_write_data  =  {I_WB_SEL, I_WB_DAT, I_WB_ADR, I_WB_CTI != CTI_BURST ? 1'd1 : 1'd0, 1'd1};
273
                                ack = 1'd1;
274
                        end
275
                end
276
                else // Writes done!
277
                begin
278
                        state_nxt = IDLE;
279
                end
280
        end
281
 
282
        WAIT1: // Wait for single read to complete.
283
        begin
284
                if ( O_WB_ACK )
285
                begin
286
                        state_nxt = IDLE;
287
                end
288
        end
289
 
290
        WAIT2: // Wait for burst reads to complete.
291
        begin
292
                if ( O_WB_ACK )
293
                begin
294
                        dnxt = dff + 1;
295 43 Revanth
                        $display($time, " - %m :: Read Burst. ACK sent. Data provided is %x", O_WB_DAT);
296 26 Revanth
                end
297
 
298
                if ( dff == BURST_LEN && !o_wb_stb )
299
                begin
300
                        state_nxt = IDLE;
301
                end
302
        end
303
 
304
        endcase
305
end
306
 
307
endmodule
308
`default_nettype wire

powered by: WebSVN 2.1.0

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