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

Subversion Repositories wb2axi4

[/] [wb2axi4/] [trunk/] [rtl/] [wb_egress.sv] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alzhang
//Author     : Alex Zhang (cgzhangwei@gmail.com)
2
//Date       : 03-11-2015
3
//Description: Now support the classic WB protocol.
4
//             Change the ACK_I meaing to improve the efficiency.
5
//TODO       : 4 beat wrapper or 8 beat wrapper is not supported yet.
6
 
7
module wb_egress(
8
wb_clk,
9
wb_resetn,
10
ENABLE,
11
WB_TX_IF,
12
fifo_adr_rdata,
13
fifo_adr_rd,
14
fifo_adr_empty,
15
fifo_dat_rdata,
16
fifo_dat_rd,
17 3 alzhang
fifo_dat_empty
18 2 alzhang
);
19
 
20
parameter  WB_ADR_W      = 32;
21
parameter  WB_DAT_W      = 32;
22
parameter  WB_TGA_W      = 8;
23
parameter  WB_TGD_W      = 8;
24
parameter  WB_TGC_W      = 4;
25
parameter  WB_SEL_W      = 4;
26
parameter  WB_CTI_W      = 3;
27
parameter  WB_BTE_W      = 2;
28
parameter  AXI_ID_W      = 3;
29
parameter  AXI_ADDR_W    = 32;
30
parameter  AXI_LEN_W     = 4;
31
parameter  AXI_SIZE_W    = 3;
32
parameter  AXI_BURST_W   = 2;
33
parameter  AXI_LOCK_W    = 2;
34
parameter  AXI_CACHE_W   = 4;
35
parameter  AXI_PROT_W    = 3;
36
parameter  AXI_DATA_W    = 32;
37 3 alzhang
parameter  AXI_STB_W     = 4;
38 2 alzhang
parameter  FIFO_ADR_W    = AXI_ID_W + AXI_ADDR_W + AXI_LEN_W + AXI_SIZE_W + AXI_BURST_W + AXI_LOCK_W + AXI_CACHE_W + AXI_PROT_W +1 ;
39 3 alzhang
parameter  FIFO_DAT_W    = AXI_ID_W + AXI_DATA_W + AXI_STB_W + 2;
40 2 alzhang
parameter  ST_W          = 2 ;
41
parameter  ST_IDLE       = 2'b00,
42
           ST_READ_ADDR  = 2'b01,
43
           ST_WAIT_DATA  = 2'b10,
44
           ST_READ_DATA  = 2'b11;
45
parameter  WB_W          = 2;
46
parameter  WB_IDLE       = 2'b00,
47
           WB_FIRST_DATA = 2'b01,
48
           WB_NEXT_DATA  = 2'b10;
49
 
50 3 alzhang
 
51 2 alzhang
input  wire                          wb_clk;
52
input  wire                          wb_resetn;
53
input  wire                          ENABLE;
54 3 alzhang
wishbone_if.master                   WB_TX_IF;
55 2 alzhang
input  wire [FIFO_ADR_W-1:0]         fifo_adr_rdata;
56
output wire                          fifo_adr_rd;
57
input  wire                          fifo_adr_empty;
58
input  wire [FIFO_DAT_W-1:0]         fifo_dat_rdata;
59
output wire                          fifo_dat_rd;
60
input  wire                          fifo_dat_empty;
61
 
62
 
63
reg  [ST_W-1:0]        state;
64
reg  [ST_W-1:0]        next_state;
65
reg                    inc_dat_ptr;
66
reg  [4:0]             data_count;
67
wire                   allow_adr_rd;
68
wire                   fifo_adr_rd_q;
69
reg  [AXI_ID_W   -1:0] axi_id    ;
70
reg  [AXI_ADDR_W -1:0] axi_addr  ;
71
reg  [AXI_LEN_W  -1:0] axi_len   ;
72
reg  [AXI_SIZE_W -1:0] axi_size  ;
73
reg  [AXI_BURST_W-1:0] axi_burst ;
74
reg  [AXI_LOCK_W -1:0] axi_lock  ;
75
reg  [AXI_CACHE_W-1:0] axi_cache ;
76
reg  [AXI_PROT_W -1:0] axi_prot  ;
77
reg                    wr_req    ;
78
reg  [AXI_ID_W   -1:0] axi_wid   ;
79
reg  [AXI_DATA_W -1:0] axi_wdata ;
80 3 alzhang
reg  [AXI_STB_W  -1:0] axi_wstrb ;
81 2 alzhang
reg                    axi_wlast ;
82
reg                    axi_wvalid;
83
reg                    wb_we_o ;
84
reg  [WB_ADR_W-1:0]    wb_adr_o;
85
reg  [WB_TGA_W-1:0]    wb_tga_o;
86
reg  [WB_ADR_W-1:0]    wb_adr_tmp;
87 3 alzhang
reg  [AXI_LEN_W-1:0]   wb_len_tmp;
88 2 alzhang
reg  [WB_BTE_W-1:0]    wb_bte_o;
89
reg                    wb_cyc_o;
90
reg  [WB_TGC_W-1:0]    wb_tgc_o;
91
reg  [WB_CTI_W-1:0]    wb_cti_o;
92 3 alzhang
reg                    wb_stb_o;
93 2 alzhang
reg  [WB_DAT_W-1:0]    wb_dat_o;
94
reg  [WB_TGD_W-1:0]    wb_tgd_o;
95
reg  [WB_SEL_W-1:0]    wb_sel_o;
96
 
97 3 alzhang
reg  [WB_W-1:0]  wb_cs;
98
reg  [WB_W-1:0]  wb_ns;
99 2 alzhang
 
100 3 alzhang
 
101
 
102 2 alzhang
assign allow_adr_rd = wb_cs == WB_IDLE;
103
always_comb begin
104
  next_state = state;
105
  inc_dat_ptr  = 0; //int- internal
106
  case (state)
107
    ST_IDLE : begin
108
      if (!fifo_adr_empty&allow_adr_rd) begin
109
        next_state = ST_READ_ADDR;
110
      end else begin
111
        next_state = ST_IDLE;
112
      end
113
    end
114
    ST_READ_ADDR : begin
115
      next_state = ST_WAIT_DATA;
116
    end
117
    ST_WAIT_DATA : begin
118 3 alzhang
      if (WB_TX_IF.ACK & !fifo_dat_empty) begin
119 2 alzhang
        next_state = ST_READ_DATA;
120
      end else begin
121
        next_state = ST_WAIT_DATA;
122
      end
123
    end
124
    ST_READ_DATA : begin
125 3 alzhang
      if (data_count>0 & WB_TX_IF.ACK) begin
126 2 alzhang
        next_state = ST_READ_DATA;
127
        inc_dat_ptr = 1;
128
      end else if (data_count>0) begin
129
        next_state = ST_WAIT_DATA;
130
        inc_dat_ptr = 0;
131 3 alzhang
      end else begin
132 2 alzhang
        next_state = ST_IDLE;
133
        inc_dat_ptr = 0;
134
      end
135
    end
136
  endcase
137
end
138
 
139
assign fifo_adr_rd = state == ST_READ_ADDR;
140
assign fifo_dat_rd = inc_dat_ptr;
141
 
142
sync_single_ff #(.DATA_W(1)) adr_rd_ff (
143
  .DIN    ( fifo_adr_rd   ),
144
  .DOUT   ( fifo_adr_rd_q ),
145
  .CLK    ( wb_clk        ),
146
  .RESET_N( wb_resetn     )
147 3 alzhang
);
148
 
149 2 alzhang
always @(posedge wb_clk or negedge wb_resetn)
150
  if (~wb_resetn) begin
151
    state <= ST_IDLE;
152
    data_count <= 0 ;
153
  end else begin
154
    state <= next_state;
155
    data_count <= state==ST_READ_ADDR ? axi_len   + 1 :
156
                  state==ST_READ_DATA ? data_count -1 : data_count ;
157
  end
158
 
159
//AXI3 only accept the alignment input of 4Byte-aligned data.i.e. awaddr[1:0]==0
160
 
161
 
162
always @(posedge wb_clk or negedge wb_resetn)
163
  if (~wb_resetn) begin
164
    axi_id     <= 0;
165
    axi_addr   <= 0;
166
    axi_len    <= 0;
167
    axi_size   <= 0;
168
    axi_burst  <= 0;
169
    axi_lock   <= 0;
170
    axi_cache  <= 0;
171
    axi_prot   <= 0;
172
    wr_req     <= 0;
173
    axi_wid    <= 0;
174
    axi_wdata  <= 0;
175
    axi_wstrb  <= 0;
176
    axi_wlast  <= 0;
177
    axi_wvalid <= 0;
178
  end else begin
179
    if ( fifo_adr_rd )
180
      {axi_id, axi_addr, axi_len, axi_size, axi_burst, axi_lock, axi_cache, axi_prot, wr_req}<= fifo_adr_rdata;
181
    if ( fifo_dat_rd )
182
      {axi_wid, axi_wdata, axi_wstrb, axi_wlast, axi_wvalid}<= fifo_dat_rdata;
183
  end
184
 
185
always @(posedge wb_clk or negedge wb_resetn) begin
186
  if (~wb_resetn) begin
187
    wb_cs <= WB_IDLE;
188
  end else begin
189
    wb_cs <= wb_ns;
190
  end
191
end
192
///Wishbone master output
193
always @(*) begin
194
  wb_ns = wb_cs;
195
  case (wb_cs)
196
    WB_IDLE : begin
197 3 alzhang
      if (fifo_dat_rd) begin
198 2 alzhang
        wb_ns = WB_FIRST_DATA;
199
      end  else begin
200
        wb_ns = WB_IDLE;
201
      end
202
    end
203
    WB_FIRST_DATA : begin
204 3 alzhang
      if (axi_wlast & WB_TX_IF.ACK)
205 2 alzhang
        wb_ns = WB_IDLE;
206 3 alzhang
      else if (~axi_wlast & WB_TX_IF.ACK)
207 2 alzhang
        wb_ns = WB_NEXT_DATA;
208
      else
209
        wb_ns = WB_FIRST_DATA;
210
    end
211
 
212
    WB_NEXT_DATA : begin
213 3 alzhang
      if (axi_wlast & WB_TX_IF.ACK)
214 2 alzhang
        wb_ns = WB_IDLE;
215
      else
216
        wb_ns = WB_NEXT_DATA;
217
    end
218
  endcase
219
end
220
 
221
 
222
always @(posedge wb_clk or negedge wb_resetn) begin
223
  if (~wb_resetn) begin
224
        wb_we_o  <= 0;
225
        wb_adr_o <= 0;
226
        wb_tga_o <= 0;
227
 
228
        wb_adr_tmp <= 0;
229
        wb_bte_o <= 0;
230
        wb_cyc_o <= 0;
231
        wb_tgc_o <= 0;
232
        wb_cti_o <= 0;
233
        wb_stb_o <= 0;
234
 
235
        wb_dat_o <= 0;
236
        wb_tgd_o <= 0;
237
        wb_sel_o <= 0;
238
  end else begin
239
    case (wb_cs)
240
      WB_IDLE : begin
241
        wb_we_o  <= 0;
242
        wb_adr_o <= 0;
243
        wb_tga_o <= 0;
244
 
245
        wb_bte_o <= 0;
246
        wb_cyc_o <= 0;
247
        wb_tgc_o <= 0;
248
        wb_cti_o <= 0;
249
        wb_stb_o <= 0;
250
 
251
        wb_dat_o <= 0;
252
        wb_tgd_o <= 0;
253
        wb_sel_o <= 0;
254
      end
255
      WB_FIRST_DATA : begin
256
        wb_we_o  <= wr_req;
257
        wb_adr_o <= axi_addr;
258
        wb_adr_tmp <= axi_addr;
259
        wb_len_tmp <= axi_len-1;
260
        wb_tga_o <= axi_id;
261
 
262
        wb_bte_o <= 2'b00; //burst
263
        wb_cyc_o <= 1;
264
        wb_tgc_o <= {axi_prot, axi_cache, axi_lock, axi_len};
265
        wb_cti_o <= axi_wlast ? 3'b111 : 3'b000;
266
        wb_stb_o <= 1;
267
 
268
        wb_dat_o <= axi_wdata;
269
        wb_tgd_o <= axi_wid;
270
        wb_sel_o <= axi_wstrb;
271
      end
272
      WB_NEXT_DATA : begin
273
        wb_we_o  <= wr_req;
274
        wb_adr_o <= wb_adr_tmp + 4'b100;
275
        wb_adr_tmp <= wb_adr_tmp +4'b100;
276
        wb_len_tmp <= wb_len_tmp -1 ;
277
        wb_tga_o <= axi_id;
278
 
279
        wb_bte_o <= 2'b00; //burst
280
        wb_cyc_o <= 1;
281
        wb_tgc_o <= {axi_prot, axi_cache, axi_lock, wb_len_tmp };
282
        wb_cti_o <= axi_wlast ? 3'b111 : 3'b000;
283
        wb_stb_o <= 1;
284
 
285
        wb_dat_o <= axi_wdata;
286
        wb_tgd_o <= axi_wid;
287
        wb_sel_o <= axi_wstrb;
288
      end
289
    endcase
290
  end
291
end
292
 
293 3 alzhang
assign WB_TX_IF.ADR   = wb_adr_o;
294
assign WB_TX_IF.WE    = wb_we_o;
295
assign WB_TX_IF.TGA   = wb_tga_o;
296
assign WB_TX_IF.BTE   = wb_bte_o;
297
assign WB_TX_IF.CYC   = wb_cyc_o;
298
assign WB_TX_IF.TGC   = wb_tgc_o;
299
assign WB_TX_IF.CTI   = wb_cti_o;
300
assign WB_TX_IF.STB   = wb_stb_o;
301 2 alzhang
assign WB_TX_IF.DAT_O = wb_dat_o;
302
assign WB_TX_IF.TGD_O = wb_tgd_o;
303 3 alzhang
assign WB_TX_IF.SEL   = wb_sel_o;
304 2 alzhang
 
305
endmodule

powered by: WebSVN 2.1.0

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