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

Subversion Repositories xulalx25soc

[/] [xulalx25soc/] [trunk/] [rtl/] [wbuexec.v] - Blame information for rev 20

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

Line No. Rev Author Line
1 2 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    wbuexec.v
4
//
5
// Project:     XuLA2 board
6
//
7
// Purpose:     This is the part of the USB-JTAG to wishbone conversion that
8
//              actually conducts a wishbone transaction.  Transactions are
9
//      requested via codewords that come in, and the results recorded on
10
//      codewords that are sent out.  Compression and/or decompression, coding
11
//      etc. all take place external to this routine.
12
//
13
//
14
// Creator:     Dan Gisselquist, Ph.D.
15
//              Gisselquist Technology, LLC
16
//
17
////////////////////////////////////////////////////////////////////////////////
18
//
19
// Copyright (C) 2015, Gisselquist Technology, LLC
20
//
21
// This program is free software (firmware): you can redistribute it and/or
22
// modify it under the terms of  the GNU General Public License as published
23
// by the Free Software Foundation, either version 3 of the License, or (at
24
// your option) any later version.
25
//
26
// This program is distributed in the hope that it will be useful, but WITHOUT
27
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
28
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
29
// for more details.
30
//
31
// License:     GPL, v3, as defined and found on www.gnu.org,
32
//              http://www.gnu.org/licenses/gpl.html
33
//
34
//
35
////////////////////////////////////////////////////////////////////////////////
36
//
37
//
38
module  wbuexec(i_clk, i_rst, i_stb, i_codword, o_busy,
39
                o_wb_cyc, o_wb_stb, o_wb_we, o_wb_addr, o_wb_data,
40
                        i_wb_ack, i_wb_stall, i_wb_err, i_wb_data,
41
                o_stb, o_codword);
42
        input                   i_clk, i_rst;
43
        // The command inputs
44
        input                   i_stb;
45
        input           [35:0]   i_codword;
46
        output  reg     o_busy;
47
        // Wishbone outputs
48
        output  reg             o_wb_cyc, o_wb_stb, o_wb_we;
49
        output  reg     [31:0]   o_wb_addr, o_wb_data;
50
        // Wishbone inputs
51
        input                   i_wb_ack, i_wb_stall, i_wb_err;
52
        input           [31:0]   i_wb_data;
53
        // And our codeword outputs
54
        output  reg             o_stb;
55
        output  reg     [35:0]   o_codword;
56
 
57
 
58
        wire    w_accept, w_eow, w_newwr, w_new_err;
59
        // wire w_newad, w_newrd;
60
        assign  w_accept = (i_stb)&&(~o_busy);
61
        // assign       w_newad  = (w_accept)&&(i_codword[35:34] == 2'b00);
62
        assign  w_newwr  = (w_accept)&&(i_codword[35:34] == 2'b01);
63
        assign  w_eow    = (w_accept)&&(i_codword[35:30] == 6'h2e);
64
        // assign       w_newrd  = (w_accept)&&(i_codword[35:34] == 2'b11);
65
        wire    [31:0]   w_cod_data;
66
        assign  w_cod_data={ i_codword[32:31], i_codword[29:0] };
67
        assign  w_new_err = ((w_accept)
68
                                &&((i_codword[35:33] != 3'h3)||(~o_wb_we))
69
                                &&(i_codword[35:30] != 6'h2e));
70
 
71
        reg     [9:0]    r_acks_needed, r_len;
72
 
73
        reg     r_inc, r_wb_err, r_new_addr, r_eow;
74
        initial r_wb_err = 1'b0;
75
        initial r_new_addr = 1'b1;
76
        always @(posedge i_clk)
77
                if (i_rst)
78
                begin
79
                        o_stb <= 1'b1;
80
                        o_codword <= { 6'h3, 30'h000 };
81
                        r_wb_err <= 1'b0;
82
                        o_wb_cyc <= 1'b0;
83
                end else if (o_wb_cyc) // In the middle of a bus transaction
84
                begin
85
                        o_stb <= 1'b0;
86
 
87
                        // Deal with bus errors
88
                        if (r_wb_err)
89
                        begin
90
                                if (w_eow)
91
                                        o_wb_cyc <= 1'b0;
92
                                o_wb_stb <= 1'b0;
93
                        end else if ((i_wb_err)||(w_new_err))
94
                        begin
95
                                o_wb_cyc <= (~o_busy);
96
                                o_wb_stb <= 1'b0;
97
                                r_wb_err <= 1'b1;
98
                                //
99
                                o_stb <= 1'b1;
100
                                o_codword <= { 6'h5, 30'h0000 };
101
                                //
102
                        end else if ((o_wb_stb)&&(~i_wb_stall))
103
                        // Deal with the strobe line
104
                        begin // Strobe was accepted, busy should be '1' here
105
                                if (r_len != 0) // read
106
                                        r_len <= r_len - 10'h01;
107
                                else
108
                                        o_wb_stb <= 1'b0;
109
 
110
                                if (o_wb_we)
111
                                begin // Acknowledge a write
112
                                        o_stb <= 1'b1;
113
                                        o_codword <= { 6'h2, 30'h0000 };
114
                                end
115
 
116
                                if (r_inc)
117
                                        o_wb_addr <= o_wb_addr + 32'h001;
118
                        end else if (w_newwr) begin
119
                                r_inc <= i_codword[30];
120
                                o_wb_data <= w_cod_data;
121
                                o_wb_stb <= 1'b1;
122
                        /*
123
                        end else if (w_newrd)
124
                        begin // This seems good, but it would stall the bus
125
                                // BUS ERROR!
126
                                o_wb_cyc <= 1'b0;
127
                                o_stb <= 1'b1;
128
                                o_codword <= { 4'h5, 32'h0000 };
129
                        */
130
                        end
131
 
132
                        if (w_eow)
133
                                r_eow <= 1'b1;
134
 
135
                        if ((r_wb_err)||(i_wb_err)||(w_new_err))
136
                                // On an error, flush any inputs ...
137
                                o_busy <= 1'b0;
138
                        else if ((w_eow)||(w_newwr)||(r_eow))
139
                                // On a new command, we're busy again
140
                                o_busy <= 1'b1;
141
                        else if((o_wb_we)&&(o_wb_stb)&&(~i_wb_stall)&&(r_len==0))
142
                                // Once our command completes, if it was a write
143
                                // command, then 
144
                                o_busy <= 1'b0;
145
                        else if ((o_wb_we)&&(~o_wb_stb))
146
                                o_busy <= 1'b0;
147
 
148
                        //
149
                        // Now let's process the acknowledgements
150
                        //
151
                        if ((r_wb_err)||(i_wb_err))
152
                        begin
153
                                // Acks are irrelevant here
154
                        end else if (r_acks_needed != 10'h00)
155
                        begin
156
                                if ((i_wb_ack)&&(~o_wb_we))
157
                                begin // Return a read result
158
                                o_stb <= 1'b1;
159
                                o_codword <= { 3'h7, i_wb_data[31:30], r_inc,
160
                                        i_wb_data[29:0] };
161
                                end
162
 
163
                                if ((i_wb_ack)&&(~w_newwr))
164
                                        r_acks_needed <= r_acks_needed - 10'h001;
165
                                else if ((~i_wb_ack)&&(w_newwr))
166
                                        r_acks_needed <= r_acks_needed + 10'h001;
167
                        end else if (r_acks_needed == 10'h0)
168
                        begin
169
                                if ((~o_wb_we)||(r_eow)||(w_eow)) // End our bus cycle
170
                                        o_wb_cyc <= 1'b0;
171
                                else if (w_newwr)
172
                                begin
173
                                        r_acks_needed <= r_acks_needed + 10'h001;
174
                                        o_wb_data <= w_cod_data;
175
                                end
176
                        end
177
                //
178
                //
179
                //
180
                //
181
                //
182
                end else if (i_stb)
183
                //
184
                //
185
                //
186
                //
187
                //
188
                begin
189
                        // Default is not to send any codewords
190
                        o_stb    <= 1'b0;
191
                        // Increment addresses?
192
                        r_inc <= i_codword[30];
193
                        // Will this be a write?
194
                        o_wb_we <= (~i_codword[35]);
195
                        // Do we need to broadcast a new address?
196
                        // r_new_addr <= 1'b0;
197
                        // Errors are all clear by now
198
                        r_wb_err <= 1'b0;
199
                        // Need to be not-busy when o_wb_cyc is low
200
                        o_busy   <= 1'b0;
201
                        // 
202
                        r_eow <= 1'b0;
203
                        if (i_codword[35:32] == 4'h0)
204
                        begin // Set a new address
205
                                r_new_addr <= 1'b1;
206
                                o_wb_addr <= i_codword[31:0];
207
                        end else if (i_codword[35:33] == 3'b001)
208
                        begin // Set a new relative address
209
                                o_wb_addr <= o_wb_addr
210
                                        + { i_codword[32:31], i_codword[29:0] };
211
                                r_new_addr <= 1'b1;
212
                        end else if (i_codword[35:34] == 2'b11)
213
                        begin // Start a vector read
214
                                // Address is already set ...
215
                                // This also depends upon the decoder working
216
                                r_len <= i_codword[9:0] - 10'h01;
217
                                o_wb_cyc <= 1'b1;
218
                                o_wb_stb <= 1'b1;
219
                                r_acks_needed <= i_codword[9:0];
220
                                o_busy   <= 1'b1;
221
 
222
                                if (r_new_addr)
223
                                begin
224
                                        o_stb <= 1'b1;
225
                                        o_codword <= { 4'h2, o_wb_addr };
226
                                        r_new_addr <= 1'b0;
227
                                end
228
                        end else if (~i_codword[35])
229
                        begin // Start a write transaction, address is alrdy set
230
                                o_wb_cyc <= 1'b1;
231
                                o_wb_stb <= 1'b1;
232
                                o_wb_data <= w_cod_data;
233
                                o_busy   <= 1'b1;
234
                                r_len <= 10'h00;
235
                                r_new_addr <= 1'b1;
236
                                r_acks_needed <= 10'h01;
237
                        end
238
                end else begin
239
                        r_wb_err <= 1'b0;
240
                        o_busy   <= 1'b0;
241
                        o_stb    <= 1'b0;
242
                end
243
 
244
endmodule

powered by: WebSVN 2.1.0

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