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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [rtl/] [soc/] [driver_sd/] [avalon_slave.v] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 alfik
/*
2
 * This file is subject to the terms and conditions of the BSD License. See
3
 * the file "LICENSE" in the main directory of this archive for more details.
4
 *
5
 * Copyright (C) 2014 Aleksander Osman
6
 */
7
 
8
module avalon_slave(
9
    input               clk,
10
    input               rst_n,
11
 
12
    //
13
    input       [1:0]   avs_address,
14
    input               avs_read,
15
    output      [31:0]  avs_readdata,
16
    input               avs_write,
17
    input       [31:0]  avs_writedata,
18
 
19
    //
20
    output reg          operation_init,
21
    output reg          operation_read,
22
    output reg          operation_write,
23
 
24
    input               operation_sector_update,
25
    output              operation_sector_last,
26
 
27
    input               operation_finished_ok,
28
    input               operation_finished_with_error,
29
 
30
    //
31
    output reg  [31:0]  sd_address,
32
    output reg  [31:0]  avalon_address_base
33
);
34
 
35
//------------------------------------------------------------------------------
36
 
37
assign avs_readdata = (avs_address == 2'd0)? {29'd0, status[2:0]} : { 29'd0, mutex };
38
 
39
reg [2:0] mutex;
40
always @(posedge clk or negedge rst_n) begin
41
    if(rst_n == 1'b0)                                                               mutex <= 3'd0;
42
    else if(mutex == 3'd0 && avs_address == 2'd1 && avs_read)                       mutex <= 3'd1;
43
    else if(mutex == 3'd0 && avs_address == 2'd2 && avs_read)                       mutex <= 3'd2;
44
    else if(mutex == 3'd0 && avs_address == 2'd3 && avs_read)                       mutex <= 3'd3;
45
    else if(mutex < 3'd4 && (operation_init || operation_read || operation_write))  mutex <= 3'd4;
46
    else if(operation_finished_ok || operation_finished_with_error)                 mutex <= 3'd0;
47
end
48
 
49
//------------------------------------------------------------------------------
50
 
51
wire operation_idle = ~(operation_init) && ~(operation_read) && ~(operation_write);
52
 
53
localparam [1:0] CONTROL_IDLE   = 2'd0; //not used
54
localparam [1:0] CONTROL_INIT   = 2'd1;
55
localparam [1:0] CONTROL_READ   = 2'd2;
56
localparam [1:0] CONTROL_WRITE  = 2'd3;
57
 
58
always @(posedge clk or negedge rst_n) begin
59
    if(rst_n == 1'b0)                                                                                   operation_init <= 1'b1;
60
    else if(operation_finished_ok || operation_finished_with_error)                                     operation_init <= 1'b0;
61
    else if(operation_idle && avs_write && avs_address == 2'd3 && avs_writedata[1:0] == CONTROL_INIT)   operation_init <= 1'b1;
62
end
63
 
64
always @(posedge clk or negedge rst_n) begin
65
    if(rst_n == 1'b0)                                                                                   operation_read <= 1'b0;
66
    else if(operation_finished_ok || operation_finished_with_error)                                     operation_read <= 1'b0;
67
    else if(operation_idle && avs_write && avs_address == 2'd3 && avs_writedata[1:0] == CONTROL_READ)   operation_read <= 1'b1;
68
end
69
 
70
always @(posedge clk or negedge rst_n) begin
71
    if(rst_n == 1'b0)                                                                                   operation_write <= 1'b0;
72
    else if(operation_finished_ok || operation_finished_with_error)                                     operation_write <= 1'b0;
73
    else if(operation_idle && avs_write && avs_address == 2'd3 && avs_writedata[1:0] == CONTROL_WRITE)  operation_write <= 1'b1;
74
end
75
 
76
//------------------------------------------------------------------------------
77
 
78
localparam [2:0] STATUS_INIT        = 3'd0;
79
localparam [2:0] STATUS_INIT_ERROR  = 3'd1;
80
localparam [2:0] STATUS_IDLE        = 3'd2;
81
localparam [2:0] STATUS_READ        = 3'd3;
82
localparam [2:0] STATUS_WRITE       = 3'd4;
83
localparam [2:0] STATUS_ERROR       = 3'd5;
84
 
85
reg [2:0] status;
86
always @(posedge clk or negedge rst_n) begin
87
    if(rst_n == 1'b0)                                                                                   status <= STATUS_INIT;
88
    else if(operation_idle && avs_write && avs_address == 2'd3 && avs_writedata[1:0] == CONTROL_INIT)   status <= STATUS_INIT;
89
    else if(operation_idle && avs_write && avs_address == 2'd3 && avs_writedata[1:0] == CONTROL_READ)   status <= STATUS_READ;
90
    else if(operation_idle && avs_write && avs_address == 2'd3 && avs_writedata[1:0] == CONTROL_WRITE)  status <= STATUS_WRITE;
91
    else if(operation_init && operation_finished_with_error)                                            status <= STATUS_INIT_ERROR;
92
    else if(operation_finished_with_error)                                                              status <= STATUS_ERROR;
93
    else if(operation_finished_ok)                                                                      status <= STATUS_IDLE;
94
end
95
 
96
//------------------------------------------------------------------------------
97
 
98
always @(posedge clk or negedge rst_n) begin
99
    if(rst_n == 1'b0)                                           avalon_address_base <= 32'd0;
100
    else if(operation_idle && avs_write && avs_address == 2'd0) avalon_address_base <= avs_writedata;
101
end
102
 
103
always @(posedge clk or negedge rst_n) begin
104
    if(rst_n == 1'b0)                                           sd_address <= 32'd0;
105
    else if(operation_idle && avs_write && avs_address == 2'd1) sd_address <= avs_writedata;
106
end
107
 
108
reg [31:0] sd_block_count;
109
always @(posedge clk or negedge rst_n) begin
110
    if(rst_n == 1'b0)                                           sd_block_count <= 32'd0;
111
    else if(operation_sector_update)                            sd_block_count <= sd_block_count - 32'd1;
112
    else if(operation_idle && avs_write && avs_address == 2'd2) sd_block_count <= avs_writedata;
113
end
114
 
115
assign operation_sector_last = sd_block_count == 32'd1;
116
 
117
//------------------------------------------------------------------------------
118
 
119
endmodule

powered by: WebSVN 2.1.0

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