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

Subversion Repositories wb_size_bridge

[/] [wb_size_bridge/] [trunk/] [src/] [wb_size_bridge.v] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 qaztronic
// --------------------------------------------------------------------
2
//
3
// --------------------------------------------------------------------
4
 
5
`timescale 1ns/10ps
6
 
7
 
8
module wb_size_bridge(
9
                        input         wb_hi_clk_i,
10
                        input         wb_hi_rst_i,
11
                        output [31:0] wb_hi_dat_o,
12
                        input  [31:0] wb_hi_dat_i,
13
                        input  [31:0] wb_hi_adr_i,
14
                        input         wb_hi_cyc_i,
15
                        input         wb_hi_stb_i,
16
                        input         wb_hi_we_i,
17
                        input  [3:0]  wb_hi_sel_i,
18
                        output        wb_hi_ack_o,
19
                        output        wb_hi_err_o,
20
                        output        wb_hi_rty_o,
21
 
22
                        output        wb_lo_clk_o,
23
                        output        wb_lo_rst_o,
24
                        input  [15:0] wb_lo_dat_i,
25
                        output [15:0] wb_lo_dat_o,
26
                        output [31:0] wb_lo_adr_o,
27
                        output        wb_lo_cyc_o,
28
                        output        wb_lo_stb_o,
29
                        output        wb_lo_we_o,
30
                        output [1:0]  wb_lo_sel_o,
31
                        input         wb_lo_ack_i,
32
                        input         wb_lo_err_i,
33
                        input         wb_lo_rty_i,
34
 
35
                        input         lo_byte_if_i
36
                      );
37
 
38
  // --------------------------------------------------------------------
39
  //  state machine encoder
40
  reg [2:0] state_enc;
41
 
42
  wire state_enc_3_more_chunks  = state_enc[2];
43
  wire state_enc_1_more_chunks  = state_enc[1];
44
  wire state_enc_error          = state_enc[0];
45
 
46
  always @(*)
47
    case( { lo_byte_if_i, wb_hi_sel_i } )
48
      5'b1_0001:  state_enc = { 1'b0, 1'b0, 1'b0 };
49
      5'b1_0010:  state_enc = { 1'b0, 1'b0, 1'b0 };
50
      5'b1_0100:  state_enc = { 1'b0, 1'b0, 1'b0 };
51
      5'b1_1000:  state_enc = { 1'b0, 1'b0, 1'b0 };
52
      5'b1_0011:  state_enc = { 1'b0, 1'b1, 1'b0 };
53
      5'b1_1100:  state_enc = { 1'b0, 1'b1, 1'b0 };
54
      5'b1_1111:  state_enc = { 1'b1, 1'b0, 1'b0 };
55
      5'b0_0001:  state_enc = { 1'b0, 1'b0, 1'b0 };
56
      5'b0_0010:  state_enc = { 1'b0, 1'b0, 1'b0 };
57
      5'b0_0100:  state_enc = { 1'b0, 1'b0, 1'b0 };
58
      5'b0_1000:  state_enc = { 1'b0, 1'b0, 1'b0 };
59
      5'b0_0011:  state_enc = { 1'b0, 1'b0, 1'b0 };
60
      5'b0_1100:  state_enc = { 1'b0, 1'b0, 1'b0 };
61
      5'b0_1111:  state_enc = { 1'b0, 1'b1, 1'b0 };
62
      default:   state_enc = { 1'b0, 1'b0, 1'b1 };
63
    endcase
64
 
65
 
66
  // --------------------------------------------------------------------
67
  //  state machine
68
 
69
  localparam   STATE_DONT_CARE     = 4'b????;
70
  localparam   STATE_PASS_THROUGH  = 4'b0001;
71
  localparam   STATE_1_MORE_CHUNK  = 4'b0010;
72
  localparam   STATE_2_MORE_CHUNK  = 4'b0100;
73
  localparam   STATE_3_MORE_CHUNK  = 4'b1000;
74
 
75
  reg [3:0] state;
76
  reg [3:0] next_state;
77
 
78
  always @(posedge wb_hi_clk_i or posedge wb_hi_rst_i)
79
    if(wb_hi_rst_i)
80
      state <= STATE_PASS_THROUGH;
81
    else
82
      state <= next_state;
83
 
84
  always @(*)
85
    case( state )
86
      STATE_PASS_THROUGH: if( state_enc_1_more_chunks & wb_lo_ack_i & wb_hi_stb_i & wb_hi_cyc_i )
87
                            next_state = STATE_1_MORE_CHUNK;
88
                          else if( state_enc_3_more_chunks & wb_lo_ack_i & wb_hi_stb_i & wb_hi_cyc_i )
89
                            next_state = STATE_3_MORE_CHUNK;
90
                          else
91
                            next_state = STATE_PASS_THROUGH;
92
 
93
      STATE_3_MORE_CHUNK: if( wb_lo_ack_i )
94
                            next_state = STATE_2_MORE_CHUNK;
95
                          else
96
                            next_state = STATE_3_MORE_CHUNK;
97
 
98
      STATE_2_MORE_CHUNK: if( wb_lo_ack_i )
99
                            next_state = STATE_1_MORE_CHUNK;
100
                          else
101
                            next_state = STATE_2_MORE_CHUNK;
102
 
103
      STATE_1_MORE_CHUNK: if( wb_lo_ack_i )
104
                            next_state = STATE_PASS_THROUGH;
105
                          else
106
                            next_state = STATE_1_MORE_CHUNK;
107
 
108
      default:            next_state = STATE_PASS_THROUGH;
109
    endcase
110
 
111
 
112
  // --------------------------------------------------------------------
113
  //  byte enable & select
114
  reg [3:0] byte_enable;
115
  localparam   BYTE_N_ENABLED  = 4'b0000;
116
  localparam   BYTE_0_ENABLED  = 4'b0001;
117
  localparam   BYTE_1_ENABLED  = 4'b0010;
118
  localparam   BYTE_2_ENABLED  = 4'b0100;
119
  localparam   BYTE_3_ENABLED  = 4'b1000;
120
 
121
  reg [1:0] byte_select;
122
  localparam   BYTE_0_SELECTED  = 2'b00;
123
  localparam   BYTE_1_SELECTED  = 2'b01;
124
  localparam   BYTE_2_SELECTED  = 2'b10;
125
  localparam   BYTE_3_SELECTED  = 2'b11;
126
  localparam   BYTE_X_SELECTED  = 2'b??;
127
 
128
  always @(*)
129
    casez( { lo_byte_if_i, wb_hi_sel_i, state } )
130
      { 1'b1, 4'b0001, STATE_PASS_THROUGH }:  byte_enable = BYTE_0_ENABLED;
131
      { 1'b1, 4'b0010, STATE_PASS_THROUGH }:  byte_enable = BYTE_1_ENABLED;
132
      { 1'b1, 4'b0100, STATE_PASS_THROUGH }:  byte_enable = BYTE_2_ENABLED;
133
      { 1'b1, 4'b1000, STATE_PASS_THROUGH }:  byte_enable = BYTE_3_ENABLED;
134
 
135
      { 1'b1, 4'b0011, STATE_PASS_THROUGH }:  byte_enable = BYTE_0_ENABLED;
136
      { 1'b1, 4'b0011, STATE_1_MORE_CHUNK }:  byte_enable = BYTE_1_ENABLED;
137
 
138
      { 1'b1, 4'b1100, STATE_PASS_THROUGH }:  byte_enable = BYTE_2_ENABLED;
139
      { 1'b1, 4'b1100, STATE_1_MORE_CHUNK }:  byte_enable = BYTE_3_ENABLED;
140
 
141
      { 1'b1, 4'b1111, STATE_PASS_THROUGH }:  byte_enable = BYTE_0_ENABLED;
142
      { 1'b1, 4'b1111, STATE_3_MORE_CHUNK }:  byte_enable = BYTE_1_ENABLED;
143
      { 1'b1, 4'b1111, STATE_2_MORE_CHUNK }:  byte_enable = BYTE_2_ENABLED;
144
      { 1'b1, 4'b1111, STATE_1_MORE_CHUNK }:  byte_enable = BYTE_3_ENABLED;
145
 
146
      { 1'b0, 4'b????, STATE_DONT_CARE }:     byte_enable = BYTE_N_ENABLED;
147
      default:                                byte_enable = BYTE_N_ENABLED;
148
    endcase
149
 
150
  always @(*)
151
    case( byte_enable )
152
      BYTE_0_ENABLED:  byte_select = BYTE_0_SELECTED;
153
      BYTE_1_ENABLED:  byte_select = BYTE_1_SELECTED;
154
      BYTE_2_ENABLED:  byte_select = BYTE_2_SELECTED;
155
      BYTE_3_ENABLED:  byte_select = BYTE_3_SELECTED;
156
      default:  byte_select = 2'bxx;
157
    endcase
158
 
159
 
160
  // --------------------------------------------------------------------
161
  //  word enable & select
162
  reg [1:0] word_enable;
163
  localparam   WORD_N_ENABLED  = 2'b00;
164
  localparam   WORD_0_ENABLED  = 2'b01;
165
  localparam   WORD_1_ENABLED  = 2'b10;
166
 
167
  reg word_select;
168
  localparam   WORD_0_SELECTED  = 1'b0;
169
  localparam   WORD_1_SELECTED  = 1'b1;
170
  localparam   WORD_X_SELECTED  = 1'b?;
171
 
172
  always @(*)
173
    casez( { lo_byte_if_i, wb_hi_sel_i, state } )
174
      { 1'b0, 4'b0011, STATE_PASS_THROUGH }:  word_enable = WORD_0_ENABLED;
175
      { 1'b0, 4'b1100, STATE_PASS_THROUGH }:  word_enable = WORD_1_ENABLED;
176
      { 1'b0, 4'b0001, STATE_PASS_THROUGH }:  word_enable = WORD_0_ENABLED;
177
      { 1'b0, 4'b0010, STATE_PASS_THROUGH }:  word_enable = WORD_0_ENABLED;
178
      { 1'b0, 4'b0100, STATE_PASS_THROUGH }:  word_enable = WORD_1_ENABLED;
179
      { 1'b0, 4'b1000, STATE_PASS_THROUGH }:  word_enable = WORD_1_ENABLED;
180
 
181
      { 1'b0, 4'b1111, STATE_PASS_THROUGH }:  word_enable = WORD_0_ENABLED;
182
      { 1'b0, 4'b1111, STATE_1_MORE_CHUNK }:  word_enable = WORD_1_ENABLED;
183
 
184
      { 1'b1, 4'b????, STATE_DONT_CARE }:     word_enable = WORD_N_ENABLED;
185
      default:                                word_enable = WORD_N_ENABLED;
186
    endcase
187
 
188
  always @(*)
189
    case( word_enable )
190
      WORD_0_ENABLED: word_select = WORD_0_SELECTED;
191
      WORD_1_ENABLED: word_select = WORD_1_SELECTED;
192
      default:        word_select = 1'bx;
193
    endcase
194
 
195
 
196
  // --------------------------------------------------------------------
197
  //  write mux
198
  reg [1:0] byte_write_mux_enc;
199
 
200
  always @(*)
201
    casez( {lo_byte_if_i, byte_select, word_select} )
202
      { 1'b1, BYTE_0_SELECTED, WORD_X_SELECTED }: byte_write_mux_enc = 2'b00;
203
      { 1'b1, BYTE_1_SELECTED, WORD_X_SELECTED }: byte_write_mux_enc = 2'b01;
204
      { 1'b1, BYTE_2_SELECTED, WORD_X_SELECTED }: byte_write_mux_enc = 2'b10;
205
      { 1'b1, BYTE_3_SELECTED, WORD_X_SELECTED }: byte_write_mux_enc = 2'b11;
206
      { 1'b0, BYTE_X_SELECTED, WORD_0_SELECTED }: byte_write_mux_enc = 2'b00;
207
      { 1'b0, BYTE_X_SELECTED, WORD_1_SELECTED }: byte_write_mux_enc = 2'b10;
208
      default:                                    byte_write_mux_enc = 2'b00;
209
    endcase
210
 
211
  reg [7:0] byte_write_mux;
212
 
213
  always @(*)
214
    case( byte_write_mux_enc )
215
      2'b00:    byte_write_mux = wb_hi_dat_i[7:0];
216
      2'b01:    byte_write_mux = wb_hi_dat_i[15:8];
217
      2'b10:    byte_write_mux = wb_hi_dat_i[23:16];
218
      2'b11:    byte_write_mux = wb_hi_dat_i[31:24];
219
      default:  byte_write_mux = wb_hi_dat_i[7:0];
220
    endcase
221
 
222
  reg [7:0] word_write_mux;
223
 
224
  always @(*)
225
    case( word_select )
226
      WORD_0_SELECTED:  word_write_mux = wb_hi_dat_i[15:8];
227
      WORD_1_SELECTED:  word_write_mux = wb_hi_dat_i[31:24];
228
      default:          word_write_mux = wb_hi_dat_i[15:8];
229
    endcase
230
 
231
 
232
  // --------------------------------------------------------------------
233
  //  read buffer & bypass mux 
234
 
235
  // low side input mux
236
  wire [7:0] read_word_lo_mux = wb_lo_dat_i[7:0];
237
  wire [7:0] read_word_hi_mux = ( word_enable[0] | word_enable[1] )? wb_lo_dat_i[15:8] : wb_lo_dat_i[7:0];
238
 
239
  reg [31:0] read_buffer;
240
 
241
  wire read_buffer_0_enable = (byte_enable[0] | word_enable[0]) & ~wb_hi_we_i;
242
  wire read_buffer_1_enable = (byte_enable[1] | word_enable[0]) & ~wb_hi_we_i;
243
  wire read_buffer_2_enable = (byte_enable[2] | word_enable[1]) & ~wb_hi_we_i;
244
  wire read_buffer_3_enable = (byte_enable[3] | word_enable[1]) & ~wb_hi_we_i;
245
 
246
  always @(posedge wb_hi_clk_i)
247
    if( read_buffer_0_enable )
248
      read_buffer[7:0] <= read_word_lo_mux;
249
 
250
  always @(posedge wb_hi_clk_i)
251
    if( read_buffer_1_enable )
252
      read_buffer[15:8] <= read_word_hi_mux;
253
 
254
  always @(posedge wb_hi_clk_i)
255
    if( read_buffer_2_enable )
256
      read_buffer[23:16] <= read_word_lo_mux;
257
 
258
  always @(posedge wb_hi_clk_i)
259
    if( read_buffer_3_enable )
260
      read_buffer[31:24] <= read_word_hi_mux;
261
 
262
  wire [31:0] read_buffer_mux;
263
 
264
  // bypass read mux
265
  assign read_buffer_mux[7:0]   = read_buffer_0_enable ? read_word_lo_mux : read_buffer[7:0];
266
  assign read_buffer_mux[15:8]  = read_buffer_1_enable ? read_word_hi_mux : read_buffer[15:8];
267
  assign read_buffer_mux[23:16] = read_buffer_2_enable ? read_word_lo_mux : read_buffer[23:16];
268
  assign read_buffer_mux[31:24] = read_buffer_3_enable ? read_word_hi_mux : read_buffer[31:24];
269
 
270
 
271
  // --------------------------------------------------------------------
272
  //  misc logic
273
  wire [1:0] lo_addr_bits;
274
  assign lo_addr_bits = ( |byte_enable ) ? byte_select : { word_select, 1'b0 };
275
 
276
  wire all_done = ( ~(|state_enc) & (state == STATE_PASS_THROUGH) ) |
277
                  ( |state_enc & (state == STATE_1_MORE_CHUNK) );
278
 
279
  reg [1:0] wb_lo_sel_r;
280
  always @(*)
281
    casez( { lo_byte_if_i, wb_hi_sel_i, state } )
282
      { 1'b0, 4'b0001, STATE_PASS_THROUGH }:  wb_lo_sel_r = 2'b01;
283
      { 1'b0, 4'b0010, STATE_PASS_THROUGH }:  wb_lo_sel_r = 2'b10;
284
      { 1'b0, 4'b0100, STATE_PASS_THROUGH }:  wb_lo_sel_r = 2'b01;
285
      { 1'b0, 4'b1000, STATE_PASS_THROUGH }:  wb_lo_sel_r = 2'b10;
286
      default:                                wb_lo_sel_r = 2'b11;
287
    endcase
288
 
289
 
290
 
291
  // --------------------------------------------------------------------
292
  //  output port assignments
293
  assign wb_hi_dat_o = read_buffer_mux;
294
  assign wb_hi_err_o = (wb_lo_err_i | state_enc_error) & wb_hi_stb_i & wb_hi_cyc_i;
295
  assign wb_hi_rty_o = wb_lo_rty_i;
296
  assign wb_hi_ack_o = all_done & wb_hi_stb_i & wb_hi_cyc_i & wb_lo_ack_i;
297
 
298
  assign wb_lo_adr_o = { wb_hi_adr_i[31:2], lo_addr_bits };
299
  assign wb_lo_clk_o = wb_hi_clk_i;
300
  assign wb_lo_rst_o = wb_hi_rst_i;
301
  assign wb_lo_cyc_o = wb_hi_cyc_i;
302
  assign wb_lo_stb_o = wb_hi_stb_i;
303
  assign wb_lo_we_o  = wb_hi_we_i & wb_hi_stb_i & wb_hi_cyc_i;
304
  assign wb_lo_dat_o = {word_write_mux, byte_write_mux};
305
  assign wb_lo_sel_o = wb_lo_sel_r;
306
 
307
 
308
endmodule
309
 
310
 

powered by: WebSVN 2.1.0

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