forked from SJTU-YONGFU-RESEARCH-GRP/core
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwishbone_master.v
More file actions
executable file
·300 lines (277 loc) · 11 KB
/
wishbone_master.v
File metadata and controls
executable file
·300 lines (277 loc) · 11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
/**
* Wishbone Master Interface
*
* This module implements a Wishbone master interface for the Wishbone bus
* protocol. Wishbone is an open-source hardware bus interface standard used
* for connecting IP cores in System-on-Chip (SoC) designs.
*
* Key Features:
* - Wishbone compliant: Follows Wishbone specification
* - Read/write transactions: Supports both read and write operations
* - Retry support: Handles retry responses from slaves
* - Error handling: Detects and reports bus errors
* - Tag support: Optional tag signals for transaction identification
*
* Wishbone Protocol:
* - STB (Strobe): Master asserts to indicate valid address/data
* - CYC (Cycle): Master asserts to indicate bus cycle in progress
* - ACK (Acknowledge): Slave asserts when transaction complete
* - ERR (Error): Slave asserts to indicate error condition
* - RTY (Retry): Slave asserts to request retry
*
* Transaction Flow:
* 1. Master asserts STB, CYC, and provides address/data
* 2. Slave responds with ACK, ERR, or RTY
* 3. Master deasserts STB, CYC on response
* 4. For RTY: Master retries transaction (up to MAX_RETRY times)
*
* States:
* - IDLE: Waiting for read/write request
* - WRITE_WAIT: Waiting for write response
* - READ_WAIT: Waiting for read response
* - RETRY: Retrying transaction after RTY
*
* Use Cases:
* - SoC interconnects
* - IP core integration
* - Memory controllers
* - Peripheral interfaces
*
* @param ADDR_WIDTH Address width (default: 32 bits)
* @param DATA_WIDTH Data width (default: 32 bits)
* @param SELECT_WIDTH Byte select width (default: DATA_WIDTH/8)
* @param TAG_WIDTH Tag width (default: 1 bit)
*
* Wishbone Signals:
* @output wb_adr_o[ADDR_WIDTH-1:0] Address output
* @output wb_dat_o[DATA_WIDTH-1:0] Write data output
* @input wb_dat_i[DATA_WIDTH-1:0] Read data input
* @output wb_we_o Write enable (1=write, 0=read)
* @output wb_sel_o[SELECT_WIDTH-1:0] Byte select (which bytes are valid)
* @output wb_stb_o Strobe (valid address/data)
* @output wb_cyc_o Cycle (bus cycle in progress)
* @input wb_ack_i Acknowledge (transaction complete)
* @input wb_err_i Error (transaction error)
* @input wb_rty_i Retry (request retry)
* @output wb_tgd_o[TAG_WIDTH-1:0] Tag output
* @input wb_tgd_i[TAG_WIDTH-1:0] Tag input
*
* User Interface:
* @input write_req Write request
* @input write_addr[ADDR_WIDTH-1:0] Write address
* @input write_data[DATA_WIDTH-1:0] Write data
* @input write_sel[SELECT_WIDTH-1:0] Write byte select
* @output write_done Write transaction complete
* @output write_err Write transaction error
*
* @input read_req Read request
* @input read_addr[ADDR_WIDTH-1:0] Read address
* @input read_sel[SELECT_WIDTH-1:0] Read byte select
* @output read_data[DATA_WIDTH-1:0] Read data
* @output read_done Read transaction complete
* @output read_err Read transaction error
*/
module wishbone_master #(
parameter ADDR_WIDTH = 32,
parameter DATA_WIDTH = 32,
parameter SELECT_WIDTH = DATA_WIDTH/8,
parameter TAG_WIDTH = 1
)(
// Global signals
input wire clk,
input wire rst_n,
// Wishbone master interface
output reg [ADDR_WIDTH-1:0] wb_adr_o,
output reg [DATA_WIDTH-1:0] wb_dat_o,
input wire [DATA_WIDTH-1:0] wb_dat_i,
output reg wb_we_o,
output reg [SELECT_WIDTH-1:0] wb_sel_o,
output reg wb_stb_o,
output reg wb_cyc_o,
input wire wb_ack_i,
input wire wb_err_i,
input wire wb_rty_i,
output reg [TAG_WIDTH-1:0] wb_tgd_o,
input wire [TAG_WIDTH-1:0] wb_tgd_i,
// User interface
input wire write_req,
input wire [ADDR_WIDTH-1:0] write_addr,
input wire [DATA_WIDTH-1:0] write_data,
input wire [SELECT_WIDTH-1:0] write_sel,
output reg write_done,
output reg write_err,
input wire read_req,
input wire [ADDR_WIDTH-1:0] read_addr,
input wire [SELECT_WIDTH-1:0] read_sel,
output reg [DATA_WIDTH-1:0] read_data,
output reg read_done,
output reg read_err
);
// FSM states
localparam IDLE = 2'b00;
localparam WRITE_WAIT = 2'b01;
localparam READ_WAIT = 2'b10;
localparam RETRY = 2'b11;
// FSM state register
reg [1:0] state;
reg [1:0] next_state;
// Retry counter
reg [3:0] retry_count;
localparam MAX_RETRY = 4'd8;
// Combinational next state logic
always @(*) begin
next_state = state; // Default: stay in current state
case (state)
IDLE: begin
if (write_req)
next_state = WRITE_WAIT;
else if (read_req)
next_state = READ_WAIT;
end
WRITE_WAIT: begin
if (wb_ack_i)
next_state = IDLE;
else if (wb_err_i)
next_state = IDLE;
else if (wb_rty_i)
next_state = RETRY;
end
READ_WAIT: begin
if (wb_ack_i)
next_state = IDLE;
else if (wb_err_i)
next_state = IDLE;
else if (wb_rty_i)
next_state = RETRY;
end
RETRY: begin
if (retry_count >= MAX_RETRY)
next_state = IDLE;
else if (wb_we_o)
next_state = WRITE_WAIT;
else
next_state = READ_WAIT;
end
default:
next_state = IDLE;
endcase
end
// Sequential state and output logic
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= IDLE;
retry_count <= 4'b0;
// Reset outputs
wb_adr_o <= {ADDR_WIDTH{1'b0}};
wb_dat_o <= {DATA_WIDTH{1'b0}};
wb_we_o <= 1'b0;
wb_sel_o <= {SELECT_WIDTH{1'b0}};
wb_stb_o <= 1'b0;
wb_cyc_o <= 1'b0;
wb_tgd_o <= {TAG_WIDTH{1'b0}};
write_done <= 1'b0;
write_err <= 1'b0;
read_data <= {DATA_WIDTH{1'b0}};
read_done <= 1'b0;
read_err <= 1'b0;
end else begin
// Update state
state <= next_state;
case (state)
IDLE: begin
// Reset bus signals
wb_stb_o <= 1'b0;
wb_cyc_o <= 1'b0;
retry_count <= 4'b0;
// Clear status signals when starting a new transaction
if (write_req) begin
// Setup for write transaction
wb_adr_o <= write_addr;
wb_dat_o <= write_data;
wb_we_o <= 1'b1;
wb_sel_o <= write_sel;
wb_stb_o <= 1'b1;
wb_cyc_o <= 1'b1;
// Clear status signals
write_done <= 1'b0;
write_err <= 1'b0;
end else if (read_req) begin
// Setup for read transaction
wb_adr_o <= read_addr;
wb_we_o <= 1'b0;
wb_sel_o <= read_sel;
wb_stb_o <= 1'b1;
wb_cyc_o <= 1'b1;
// Clear status signals
read_done <= 1'b0;
read_err <= 1'b0;
end
end
WRITE_WAIT: begin
// Keep bus signals asserted until response
wb_stb_o <= 1'b1;
wb_cyc_o <= 1'b1;
if (wb_ack_i) begin
wb_stb_o <= 1'b0;
wb_cyc_o <= 1'b0;
write_done <= 1'b1;
end else if (wb_err_i) begin
wb_stb_o <= 1'b0;
wb_cyc_o <= 1'b0;
write_err <= 1'b1;
end else if (wb_rty_i) begin
wb_stb_o <= 1'b0;
wb_cyc_o <= 1'b0;
retry_count <= retry_count + 1'b1;
end
end
READ_WAIT: begin
// Keep bus signals asserted until response
wb_stb_o <= 1'b1;
wb_cyc_o <= 1'b1;
if (wb_ack_i) begin
// Capture read data on ACK assertion
read_data <= wb_dat_i;
read_done <= 1'b1;
wb_stb_o <= 1'b0;
wb_cyc_o <= 1'b0;
end else if (wb_err_i) begin
wb_stb_o <= 1'b0;
wb_cyc_o <= 1'b0;
read_err <= 1'b1;
end else if (wb_rty_i) begin
wb_stb_o <= 1'b0;
wb_cyc_o <= 1'b0;
retry_count <= retry_count + 1'b1;
end
end
RETRY: begin
// ============================================================
// Retry Logic
// ============================================================
if (retry_count >= MAX_RETRY) begin
// ============================================================
// Maximum Retries Exceeded
// ============================================================
// Too many retries: report error and abort transaction
if (wb_we_o)
write_err <= 1'b1; // Write error
else
read_err <= 1'b1; // Read error
// Deassert bus signals
wb_stb_o <= 1'b0;
wb_cyc_o <= 1'b0;
end else begin
// ============================================================
// Retry Transaction
// ============================================================
// Retry the transaction: reassert bus signals
// Address and data remain from previous attempt
wb_stb_o <= 1'b1;
wb_cyc_o <= 1'b1;
end
end
endcase
end
end
endmodule