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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [boards/] [xilinx/] [ml501/] [rtl/] [verilog/] [gpio/] [gpio.v] - Blame information for rev 425

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

Line No. Rev Author Line
1 408 julius
/*
2
 *
3 412 julius
 * Simple 24-bit wide GPIO module
4 408 julius
 *
5
 * Can be made wider as needed, but must be done manually.
6
 *
7
 * First lot of bytes are the GPIO I/O regs
8
 * Second lot are the direction registers
9
 *
10
 * Set direction bit to '1' to output corresponding data bit.
11
 *
12
 * Register mapping:
13
 *
14
 * For 8 GPIOs we would have
15
 * adr 0: gpio data 7:0
16
 * adr 1: gpio data 15:8
17 412 julius
 * adr 2: gpio data 23:16
18 408 julius
 * adr 3: gpio dir 7:0
19
 * adr 4: gpio dir 15:8
20 412 julius
 * adr 5: gpio dir 23:16
21 408 julius
 *
22
 * Backend pinout file needs to be updated for any GPIO width changes.
23
 *
24
 */
25
 
26
module gpio(
27
            wb_clk,
28
            wb_rst,
29
 
30
            wb_adr_i,
31
            wb_dat_i,
32
            wb_we_i,
33
            wb_cyc_i,
34
            wb_stb_i,
35
            wb_cti_i,
36
            wb_bte_i,
37
 
38
            wb_ack_o,
39
            wb_dat_o,
40
            wb_err_o,
41
            wb_rty_o,
42
 
43
            gpio_io);
44
 
45
 
46 412 julius
   parameter gpio_io_width = 24;
47 408 julius
 
48
   parameter gpio_dir_reset_val = 0;
49
   parameter gpio_o_reset_val = 0;
50
 
51
 
52
   parameter wb_dat_width = 8;
53
   parameter wb_adr_width = 3; // 8 bytes addressable
54
 
55
   input wb_clk;
56
   input wb_rst;
57
 
58
   input [wb_adr_width-1:0] wb_adr_i;
59
   input [wb_dat_width-1:0] wb_dat_i;
60
   input                    wb_we_i;
61
   input                    wb_cyc_i;
62
   input                    wb_stb_i;
63
   input [2:0]               wb_cti_i;
64
   input [1:0]               wb_bte_i;
65
   output reg [wb_dat_width-1:0] wb_dat_o; // constantly sampling gpio in bus
66
   output reg                wb_ack_o;
67
   output                    wb_err_o;
68
   output                    wb_rty_o;
69
 
70
   inout [gpio_io_width-1:0] gpio_io;
71
 
72
   // Internal registers
73
   reg [gpio_io_width-1:0]   gpio_dir;
74
 
75
   reg [gpio_io_width-1:0]   gpio_o;
76
 
77
   wire [gpio_io_width-1:0]  gpio_i;
78
 
79
   // Tristate logic for IO
80
   genvar                    i;
81
   generate
82
      for (i=0;i<gpio_io_width;i=i+1)  begin: gpio_tris
83
         assign gpio_io[i] = (gpio_dir[i]) ? gpio_o[i] : 1'bz;
84
         assign gpio_i[i] = (gpio_dir[i]) ? gpio_o[i] : gpio_io[i];
85
      end
86
   endgenerate
87
 
88 412 julius
   // GPIO data out register
89
   always @(posedge wb_clk)
90
     if (wb_rst)
91
       gpio_o <= 0; // All set to in at reset
92
     else if (wb_stb_i & wb_we_i)
93
       begin
94
          if (wb_adr_i == 0)
95
            gpio_o[7:0] <= wb_dat_i;
96
          if (wb_adr_i == 1)
97
            gpio_o[15:8] <= wb_dat_i;
98
          if (wb_adr_i == 2)
99
            gpio_o[23:16] <= wb_dat_i;
100
          /* Add appropriate address detection here for wider GPIO */
101
       end
102 408 julius
 
103 412 julius
 
104 408 julius
   // GPIO dir register
105
   always @(posedge wb_clk)
106
     if (wb_rst)
107
       gpio_dir <= 0; // All set to in at reset
108
     else if (wb_stb_i & wb_we_i)
109
       begin
110
          if (wb_adr_i == ((gpio_io_width/8)))
111
            gpio_dir[7:0] <= wb_dat_i;
112
          if (wb_adr_i == ((gpio_io_width/8)+1))
113
            gpio_dir[15:8] <= wb_dat_i;
114
          if (wb_adr_i == ((gpio_io_width/8)+2))
115
            //gpio_dir[23:16] <= wb_dat_i;
116
            gpio_dir[21:16] <= wb_dat_i[5:0];
117 412 julius
 
118 408 julius
          /* Add appropriate address detection here for wider GPIO */
119
 
120
       end
121
 
122
   // Register the gpio in signal
123
   always @(posedge wb_clk)
124
     begin
125
        // Data regs
126
        if (wb_adr_i == 0)
127
          wb_dat_o[7:0] <= gpio_i[7:0];
128
        if (wb_adr_i == 1)
129
          wb_dat_o[7:0] <= gpio_i[15:8];
130
        if (wb_adr_i == 2)
131
          wb_dat_o[7:0] <= gpio_i[23:16];
132
        /* Add appropriate address detection here for wider GPIO */
133
        // Direction regs
134 412 julius
        if (wb_adr_i == ((gpio_io_width/8)))
135 408 julius
          wb_dat_o[7:0] <= gpio_dir[7:0];
136 412 julius
        if (wb_adr_i == ((gpio_io_width/8)+1))
137 408 julius
          wb_dat_o[7:0] <= gpio_dir[15:8];
138 412 julius
        if (wb_adr_i == ((gpio_io_width/8)+2))
139 408 julius
          wb_dat_o[7:0] <= gpio_dir[23:16];
140 412 julius
 
141 408 julius
        /* Add appropriate address detection here for wider GPIO */
142
 
143
     end
144
 
145
 
146
   // Ack generation
147
   always @(posedge wb_clk)
148
     if (wb_rst)
149
       wb_ack_o <= 0;
150
     else if (wb_ack_o)
151
       wb_ack_o <= 0;
152
     else if (wb_stb_i & !wb_ack_o)
153
       wb_ack_o <= 1;
154
 
155
   assign wb_err_o = 0;
156
   assign wb_rty_o = 0;
157
 
158
 
159
endmodule // gpio

powered by: WebSVN 2.1.0

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