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

Subversion Repositories pss

[/] [pss/] [trunk/] [pss/] [hdl/] [pss/] [udm/] [udm_controller.v] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 AlexAntono
/*
2
 PSS
3
 
4
 Copyright (c) 2016 Alexander Antonov <153287@niuitmo.ru>
5
 All rights reserved.
6
 
7
 Version 0.9
8
 
9
 The FreeBSD license
10
 
11
 Redistribution and use in source and binary forms, with or without
12
 modification, are permitted provided that the following conditions
13
 are met:
14
 
15
 1. Redistributions of source code must retain the above copyright
16
    notice, this list of conditions and the following disclaimer.
17
 2. Redistributions in binary form must reproduce the above
18
    copyright notice, this list of conditions and the following
19
    disclaimer in the documentation and/or other materials
20
    provided with the distribution.
21
 
22
 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
23
 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24
 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25
 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26
 PSS PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27
 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29
 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31
 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
33
 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
*/
35
 
36
 
37
module udm_controller
38
(
39
        input clk_i, reset_i,
40
 
41
        // uart rx
42
        input rx_done_tick_i,
43
    input [7:0] rx_din_bi,
44
 
45
        // uart tx
46
        output reg [7:0] tx_dout_bo,
47
        output reg tx_start_o,
48
    input tx_done_tick_i,
49
 
50
        // bus
51
        output reg rst_o,
52
        output reg bus_enb_o,
53
        output reg bus_we_o,
54
        output reg [31:0] bus_addr_bo,
55
    output reg [31:0] bus_wdata_bo,
56
 
57
    input bus_ack_i,
58
    input [31:0] bus_rdata_bi
59
);
60
 
61
// control bytes
62
localparam SYNC_BYTE = 8'h55;
63
localparam ESCAPE_BYTE = 8'h5a;
64
 
65
// commands
66
localparam IDCODE_CMD = 8'h00;          // check udm accessibility
67
localparam RST_CMD = 8'h80;                     // Reset slave  
68
localparam WR_INC_CMD = 8'h81;          // Write slave with autoincrement
69
localparam RD_INC_CMD = 8'h82;          // Read slave with autoincrement
70
localparam WR_NOINC_CMD = 8'h83;        // Write slave without autoincrement
71
localparam RD_NOINC_CMD = 8'h84;        // Read slave without autoincrement
72
 
73
 
74
reg rx_req, rx_sync;
75
reg [7:0] r_data;
76
 
77
// rx sync logic
78
reg escape_received;
79
always @(posedge clk_i)
80
        begin
81
        if (reset_i)
82
                begin
83
                rx_req <= 1'b0;
84
                rx_sync <= 1'b0;
85
                r_data <= 8'hx;
86
                escape_received <= 1'b0;
87
                end
88
        else
89
                begin
90
                rx_req <= 1'b0;
91
                rx_sync <= 1'b0;
92
                r_data <= 8'hx;
93
 
94
                if (escape_received == 1'b0)
95
                        begin
96
                        if (rx_done_tick_i == 1'b1)
97
                                begin
98
                                if (rx_din_bi == SYNC_BYTE)
99
                                        rx_sync <= 1'b1;
100
                                else if (rx_din_bi == ESCAPE_BYTE)
101
                                        escape_received <= 1'b1;
102
                                else
103
                                        begin
104
                                        rx_req <= 1'b1;
105
                                        r_data <= rx_din_bi;
106
                                        end
107
                                end
108
                        end
109
                else
110
                        begin
111
                        if (rx_done_tick_i == 1'b1)
112
                                begin
113
                                rx_req <= 1'b1;
114
                                r_data <= rx_din_bi;
115
                                escape_received <= 1'b0;
116
                                end
117
                        end
118
                end
119
        end
120
 
121
// states
122
localparam IDLE = 8'h00;
123
localparam FETCH_ADDR = 8'h01;
124
localparam FETCH_LENGTH = 8'h02;
125
localparam FETCH_DATA = 8'h03;
126
localparam WAIT_ACCEPT = 8'h04;
127
localparam RD_DATA = 8'h05;
128
localparam TX_DATA = 8'h06;
129
localparam WAIT_TX = 8'h07;
130
 
131
reg [7:0] state;
132
reg [1:0] counter;
133
reg cmd_ff, autoinc_ff;
134
reg [31:0] RD_DATA_reg;
135
reg [31:0] tr_length;
136
 
137
always @(posedge clk_i, posedge reset_i)
138
        begin
139
        if (reset_i == 1'b1)
140
                begin
141
 
142
                rst_o <= 1'b0;
143
 
144
                state <= IDLE;
145
                tx_start_o <= 1'b0;
146
 
147
                bus_enb_o <= 1'b0;
148
                bus_we_o <= 1'bx;
149
                bus_addr_bo <= 32'hxxxxxxxx;
150
                bus_wdata_bo <= 32'hxxxxxxxx;
151
 
152
                end
153
        else
154
                begin
155
 
156
                if (rx_sync == 1'b1)
157
                        begin
158
                        state <= IDLE;
159
                        tx_start_o <= 1'b0;
160
 
161
                        bus_enb_o <= 1'b0;
162
                        bus_we_o <= 1'bx;
163
                        bus_addr_bo <= 32'hxxxxxxxx;
164
                        bus_wdata_bo <= 32'hxxxxxxxx;
165
                        tr_length <= 32'h0;
166
                        end
167
 
168
                else
169
                        begin
170
                        rst_o <= 1'b0;
171
 
172
                        tx_start_o <= 1'b0;
173
 
174
                        case (state)
175
 
176
                                IDLE:
177
                                        begin
178
                                        if (rx_req)
179
                                                begin
180
                                                case (r_data)
181
 
182
                                                        IDCODE_CMD:
183
                                                                begin
184
                                                                tx_start_o <= 1'b1;
185
                                                                tx_dout_bo <= SYNC_BYTE;
186
                                                                end
187
 
188
                                                        RST_CMD:
189
                                                                begin
190
                                                                rst_o <= 1'b1;
191
                                                                end
192
 
193
                                                        WR_INC_CMD:
194
                                                                begin
195
                                                                cmd_ff <= 1'b1;
196
                                                                autoinc_ff <= 1'b1;
197
                                                                state <= FETCH_ADDR;
198
                                                                counter <= 2'b00;
199
                                                                end
200
 
201
                                                        RD_INC_CMD:
202
                                                                begin
203
                                                                cmd_ff <= 1'b0;
204
                                                                autoinc_ff <= 1'b1;
205
                                                                state <= FETCH_ADDR;
206
                                                                counter <= 2'b00;
207
                                                                end
208
 
209
                                                        WR_NOINC_CMD:
210
                                                                begin
211
                                                                cmd_ff <= 1'b1;
212
                                                                autoinc_ff <= 1'b0;
213
                                                                state <= FETCH_ADDR;
214
                                                                counter <= 2'b00;
215
                                                                end
216
 
217
                                                        RD_NOINC_CMD:
218
                                                                begin
219
                                                                cmd_ff <= 1'b0;
220
                                                                autoinc_ff <= 1'b0;
221
                                                                state <= FETCH_ADDR;
222
                                                                counter <= 2'b00;
223
                                                                end
224
 
225
                                                        default:
226
                                                                state <= IDLE;
227
 
228
                                                endcase
229
                                                end
230
                                        end
231
 
232
                                FETCH_ADDR:
233
                                        begin
234
                                        if (rx_req)
235
                                                begin
236
                                                bus_addr_bo <= {r_data, bus_addr_bo[31:8]};
237
                                                if (counter == 2'b11)
238
                                                        begin
239
                                                        state <= FETCH_LENGTH;
240
                                                        counter <= 2'b00;
241
                                                        end
242
                                                else
243
                                                        begin
244
                                                        counter <= counter + 2'b01;
245
                                                        end
246
                                                end
247
                                        end
248
 
249
                                FETCH_LENGTH:
250
                                        begin
251
                                        if (rx_req)
252
                                                begin
253
                                                tr_length <= {r_data, tr_length[31:8]};
254
                                                if (counter == 2'b11)
255
                                                        begin
256
                                                        if (cmd_ff == 1'b1)
257
                                                                begin
258
                                                                state <= FETCH_DATA;
259
                                                                counter <= 2'b00;
260
                                                                end
261
                                                        else
262
                                                                begin
263
                                                                bus_enb_o <= 1'b1;
264
                                                                bus_we_o <= 1'b0;
265
                                                                bus_wdata_bo <= 32'hx;
266
                                                                state <= WAIT_ACCEPT;
267
                                                                counter <= 2'b00;
268
                                                                end
269
                                                        end
270
                                                else
271
                                                        begin
272
                                                        counter <= counter + 2'b01;
273
                                                        end
274
                                                end
275
                                        end
276
 
277
                                FETCH_DATA:
278
                                        begin
279
                                        if (rx_req)
280
                                                begin
281
                                                bus_wdata_bo <= {r_data, bus_wdata_bo[31:8]};
282
                                                if (counter == 2'b11)
283
                                                        begin
284
                                                        bus_enb_o <= 1'b1;
285
                                                        bus_we_o <= 1'b1;
286
                                                        state <= WAIT_ACCEPT;
287
                                                        end
288
                                                else
289
                                                        begin
290
                                                        counter <= counter + 2'b01;
291
                                                        end
292
                                                end
293
                                        end
294
 
295
                                WAIT_ACCEPT:
296
                                        begin
297
                                        if (bus_ack_i == 1'b1)
298
                                                begin
299
                                                bus_enb_o <= 1'b0;
300
                                                bus_we_o <= 1'bx;
301
                                                bus_wdata_bo <= 32'hx;
302
                                                RD_DATA_reg <= bus_rdata_bi;
303
                                                if (cmd_ff == 1'b0)
304
                                                        begin
305
                                                        state <= TX_DATA;
306
                                                        end
307
                                                else
308
                                                        begin
309
                                                        if (tr_length == 32'h4) state <= IDLE;
310
                                                        else
311
                                                                begin
312
                                                                if (autoinc_ff == 1'b1) bus_addr_bo <= bus_addr_bo + 32'h4;
313
                                                                state <= FETCH_DATA;
314
                                                                counter <= 2'b00;
315
                                                                end
316
                                                        tr_length <= tr_length - 32'h4;
317
                                                        end
318
                                                end
319
                                        end
320
 
321
                                TX_DATA:
322
                                        begin
323
                                        tx_start_o <= 1'b1;
324
                                        tx_dout_bo <= RD_DATA_reg[7:0];
325
                                        RD_DATA_reg <= {8'h0, RD_DATA_reg[31:8]};
326
                                        counter <= 2'b00;
327
                                        state <= WAIT_TX;
328
                                        end
329
 
330
                                WAIT_TX:
331
                                        begin
332
                                        if (tx_done_tick_i == 1'b1)
333
                                                begin
334
                                                if (counter == 2'b11)
335
                                                        begin
336
                                                        if (tr_length == 32'h4) state <= IDLE;
337
                                                        else
338
                                                                begin
339
                                                                if (autoinc_ff == 1'b1) bus_addr_bo <= bus_addr_bo + 32'h4;
340
                                                                bus_enb_o <= 1'b1;
341
                                                                bus_we_o <= 1'b0;
342
                                                                bus_wdata_bo <= 32'hx;
343
                                                                state <= WAIT_ACCEPT;
344
                                                                counter <= 2'b00;
345
                                                                end
346
                                                        tr_length <= tr_length - 32'h4;
347
                                                        end
348
                                                else
349
                                                        begin
350
                                                        tx_start_o <= 1'b1;
351
                                                        tx_dout_bo <= RD_DATA_reg[7:0];
352
                                                        RD_DATA_reg <= {8'h0, RD_DATA_reg[31:8]};
353
                                                        end
354
                                                counter <= counter + 2'b01;
355
                                                end
356
                                        end
357
 
358
                                default:
359
                                        begin
360
                                        state <= IDLE;
361
                                        end
362
 
363
                        endcase
364
                        end
365
                end
366
        end
367
 
368
endmodule

powered by: WebSVN 2.1.0

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