3ac83bad392628c266ee6bf203b0b15dcf2da30d
[shakti-peripherals.git] / src / peripherals / gpio / gpio.bsv
1 /*
2 Copyright (c) 2013, IIT Madras
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6
7 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9 * Neither the name of IIT Madras nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10
11 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
13 */
14 package gpio;
15 /*==== Package imports ==== */
16 import TriState ::*;
17 import Vector ::*;
18 import BUtils::*;
19 import ConfigReg ::*;
20 /*============================ */
21 /*===== Project Imports ===== */
22 import Semi_FIFOF :: *;
23 import AXI4_Lite_Types :: *;
24 /*============================ */
25 `include "instance_defines.bsv"
26
27 interface GPIO_func#(numeric type ionum);
28 (*always_ready,always_enabled*)
29 method Action gpio_in (Vector#(ionum,Bit#(1)) inp);
30 (*always_ready*)
31 method Vector#(ionum,Bit#(1)) gpio_out;
32 (*always_ready*)
33 method Vector#(ionum,Bit#(1)) gpio_out_en;
34 endinterface
35 interface GPIO_config#(numeric type ionum);
36 (*always_ready*)
37 method Vector#(ionum,Bit#(1)) gpio_DRV0;
38 (*always_ready*)
39 method Vector#(ionum,Bit#(1)) gpio_DRV1;
40 (*always_ready*)
41 method Vector#(ionum,Bit#(1)) gpio_DRV2;
42 (*always_ready*)
43 method Vector#(ionum,Bit#(1)) gpio_PD;
44 (*always_ready*)
45 method Vector#(ionum,Bit#(1)) gpio_PPEN;
46 (*always_ready*)
47 method Vector#(ionum,Bit#(1)) gpio_PRG_SLEW;
48 (*always_ready*)
49 method Vector#(ionum,Bit#(1)) gpio_PUQ;
50 (*always_ready*)
51 method Vector#(ionum,Bit#(1)) gpio_PWRUPZHL;
52 (*always_ready*)
53 method Vector#(ionum,Bit#(1)) gpio_PWRUP_PULL_EN;
54 endinterface
55 interface GPIO#(numeric type ionum);
56 interface GPIO_config#(ionum) pad_config;
57 interface GPIO_func#(ionum) func;
58 interface AXI4_Lite_Slave_IFC#(`ADDR,`DATA,`USERSPACE) axi_slave;
59 endinterface
60
61 module mkgpio(GPIO#(ionum_));
62 let ionum = valueOf(ionum_);
63 Vector#(ionum_,ConfigReg#(Bool)) direction_reg <-replicateM(mkConfigReg(False));
64 Vector#(ionum_,ConfigReg#(Bit#(1))) dataout_register <-replicateM(mkConfigReg(0));
65 Vector#(ionum_,ConfigReg#(Bit#(1))) datain_register <-replicateM(mkConfigReg(0));
66 Vector#(ionum_,ConfigReg#(Bit#(1))) drv0_reg <-replicateM(mkConfigReg(1'b1));
67 Vector#(ionum_,ConfigReg#(Bit#(1))) drv1_reg <-replicateM(mkConfigReg(1'b1));
68 Vector#(ionum_,ConfigReg#(Bit#(1))) drv2_reg <-replicateM(mkConfigReg(0));
69 Vector#(ionum_,ConfigReg#(Bit#(1))) pd_reg <-replicateM(mkConfigReg(0));
70 Vector#(ionum_,ConfigReg#(Bit#(1))) ppen_reg <-replicateM(mkConfigReg(0));
71 Vector#(ionum_,ConfigReg#(Bit#(1))) prg_slew_reg <-replicateM(mkConfigReg(1'b1));
72 Vector#(ionum_,ConfigReg#(Bit#(1))) puq_reg <-replicateM(mkConfigReg(0));
73 Vector#(ionum_,ConfigReg#(Bit#(1))) pwrupzhl_reg <-replicateM(mkConfigReg(0));
74 Vector#(ionum_,ConfigReg#(Bit#(1))) pwrup_pull_en_reg <-replicateM(mkConfigReg(0));
75
76 AXI4_Lite_Slave_Xactor_IFC #(`ADDR, `DATA, `USERSPACE) s_xactor <- mkAXI4_Lite_Slave_Xactor;
77 rule rl_wr_respond;
78 // Get the wr request
79 let aw <- pop_o (s_xactor.o_wr_addr);
80 let w <- pop_o (s_xactor.o_wr_data);
81 let b = AXI4_Lite_Wr_Resp {bresp: AXI4_LITE_OKAY, buser: aw.awuser};
82 if(aw.awaddr[5:0]=='h0)
83 for(Integer i=0;i<ionum;i=i+1)
84 direction_reg[i]<=unpack(w.wdata[i]);
85 else if(aw.awaddr[5:0]=='h4)
86 for(Integer i=0;i<ionum;i=i+1)
87 dataout_register[i]<=w.wdata[i];
88 else if(aw.awaddr[5:0]=='h8)
89 for(Integer i=0;i<ionum;i=i+1)
90 drv0_reg[i]<=w.wdata[i];
91 else if(aw.awaddr[5:0]=='hC)
92 for(Integer i=0;i<ionum;i=i+1)
93 drv1_reg[i]<=w.wdata[i];
94 else if(aw.awaddr[5:0]=='h10)
95 for(Integer i=0;i<ionum;i=i+1)
96 drv2_reg[i]<=w.wdata[i];
97 else if(aw.awaddr[5:0]=='h14)
98 for(Integer i=0;i<ionum;i=i+1)
99 pd_reg[i]<=w.wdata[i];
100 else if(aw.awaddr[5:0]=='h18)
101 for(Integer i=0;i<ionum;i=i+1)
102 ppen_reg[i]<=w.wdata[i];
103 else if(aw.awaddr[5:0]=='h1C)
104 for(Integer i=0;i<ionum;i=i+1)
105 prg_slew_reg[i]<=w.wdata[i];
106 else if(aw.awaddr[5:0]=='h20)
107 for(Integer i=0;i<ionum;i=i+1)
108 puq_reg[i]<=w.wdata[i];
109 else if(aw.awaddr[5:0]=='h24)
110 for(Integer i=0;i<ionum;i=i+1)
111 pwrupzhl_reg[i]<=w.wdata[i];
112 else if(aw.awaddr[5:0]=='h28)
113 for(Integer i=0;i<ionum;i=i+1)
114 pwrup_pull_en_reg[i]<=w.wdata[i];
115 else
116 b.bresp=AXI4_LITE_SLVERR;
117
118 s_xactor.i_wr_resp.enq (b);
119 endrule
120
121 rule rl_rd_respond;
122 let ar<- pop_o(s_xactor.o_rd_addr);
123 Bit#(32) temp=0;
124 AXI4_Lite_Rd_Data#(`DATA,`USERSPACE) r = AXI4_Lite_Rd_Data {rresp: AXI4_LITE_OKAY, rdata: ?, ruser: 0};
125 if(ar.araddr[5:0]=='h0)begin
126 for(Integer i=0;i<ionum;i=i+1)
127 temp[i]=pack(direction_reg[i]);
128 r.rdata=duplicate(temp);
129 end
130 else if(ar.araddr[5:0]=='h4)begin
131 for(Integer i=0;i<ionum;i=i+1)
132 temp[i]=datain_register[i];
133 r.rdata=duplicate(temp);
134 end
135 else if(ar.araddr[5:0]=='h8)begin
136 for(Integer i=0;i<ionum;i=i+1)
137 temp[i]=drv0_reg[i];
138 r.rdata=duplicate(temp);
139 end
140 else if(ar.araddr[5:0]=='hC)begin
141 for(Integer i=0;i<ionum;i=i+1)
142 temp[i]=drv1_reg[i];
143 r.rdata=duplicate(temp);
144 end
145 else if(ar.araddr[5:0]=='h10)begin
146 for(Integer i=0;i<ionum;i=i+1)
147 temp[i]=drv2_reg[i];
148 r.rdata=duplicate(temp);
149 end
150 else if(ar.araddr[5:0]=='h14)begin
151 for(Integer i=0;i<ionum;i=i+1)
152 temp[i]=pd_reg[i];
153 r.rdata=duplicate(temp);
154 end
155 else if(ar.araddr[5:0]=='h18)begin
156 for(Integer i=0;i<ionum;i=i+1)
157 temp[i]=ppen_reg[i];
158 r.rdata=duplicate(temp);
159 end
160 else if(ar.araddr[5:0]=='h1C)begin
161 for(Integer i=0;i<ionum;i=i+1)
162 temp[i]=prg_slew_reg[i];
163 r.rdata=duplicate(temp);
164 end
165 else if(ar.araddr[5:0]=='h20)begin
166 for(Integer i=0;i<ionum;i=i+1)
167 temp[i]=puq_reg[i];
168 r.rdata=duplicate(temp);
169 end
170 else if(ar.araddr[5:0]=='h24)begin
171 for(Integer i=0;i<ionum;i=i+1)
172 temp[i]=pwrupzhl_reg[i];
173 r.rdata=duplicate(temp);
174 end
175 else if(ar.araddr[5:0]=='h28)begin
176 for(Integer i=0;i<ionum;i=i+1)
177 temp[i]=pwrup_pull_en_reg[i];
178 r.rdata=duplicate(temp);
179 end
180 else
181 r.rresp=AXI4_LITE_SLVERR;
182
183 s_xactor.i_rd_data.enq(r);
184 endrule
185
186 interface axi_slave= s_xactor.axi_side;
187 interface func=interface GPIO_func
188 method Action gpio_in (Vector#(ionum,Bit#(1)) inp);
189 for(Integer i=0;i<ionum;i=i+1)
190 datain_register[i]<=inp[i];
191 endmethod
192 method Vector#(ionum,Bit#(1)) gpio_out;
193 Vector#(ionum,Bit#(1)) temp;
194 for(Integer i=0;i<ionum;i=i+1)
195 temp[i]=dataout_register[i];
196 return temp;
197 endmethod
198 method Vector#(ionum,Bit#(1)) gpio_out_en;
199 Vector#(ionum,Bit#(1)) temp;
200 for(Integer i=0;i<ionum;i=i+1)
201 temp[i]=pack(direction_reg[i]);
202 return temp;
203 endmethod
204 endinterface;
205 interface pad_config=interface GPIO_config
206 method Vector#(ionum,Bit#(1)) gpio_DRV0;
207 Vector#(ionum,Bit#(1)) temp;
208 for(Integer i=0;i<ionum;i=i+1)
209 temp[i]=pack(drv0_reg[i]);
210 return temp;
211 endmethod
212 method Vector#(ionum,Bit#(1)) gpio_DRV1;
213 Vector#(ionum,Bit#(1)) temp;
214 for(Integer i=0;i<ionum;i=i+1)
215 temp[i]=pack(drv1_reg[i]);
216 return temp;
217 endmethod
218 method Vector#(ionum,Bit#(1)) gpio_DRV2;
219 Vector#(ionum,Bit#(1)) temp;
220 for(Integer i=0;i<ionum;i=i+1)
221 temp[i]=pack(drv2_reg[i]);
222 return temp;
223 endmethod
224 method Vector#(ionum,Bit#(1)) gpio_PD;
225 Vector#(ionum,Bit#(1)) temp;
226 for(Integer i=0;i<ionum;i=i+1)
227 temp[i]=pack(pd_reg[i]);
228 return temp;
229 endmethod
230 method Vector#(ionum,Bit#(1)) gpio_PPEN;
231 Vector#(ionum,Bit#(1)) temp;
232 for(Integer i=0;i<ionum;i=i+1)
233 temp[i]=pack(ppen_reg[i]);
234 return temp;
235 endmethod
236 method Vector#(ionum,Bit#(1)) gpio_PRG_SLEW;
237 Vector#(ionum,Bit#(1)) temp;
238 for(Integer i=0;i<ionum;i=i+1)
239 temp[i]=pack(prg_slew_reg[i]);
240 return temp;
241 endmethod
242 method Vector#(ionum,Bit#(1)) gpio_PUQ;
243 Vector#(ionum,Bit#(1)) temp;
244 for(Integer i=0;i<ionum;i=i+1)
245 temp[i]=pack(puq_reg[i]);
246 return temp;
247 endmethod
248 method Vector#(ionum,Bit#(1)) gpio_PWRUPZHL;
249 Vector#(ionum,Bit#(1)) temp;
250 for(Integer i=0;i<ionum;i=i+1)
251 temp[i]=pack(pwrupzhl_reg[i]);
252 return temp;
253 endmethod
254 method Vector#(ionum,Bit#(1)) gpio_PWRUP_PULL_EN;
255 Vector#(ionum,Bit#(1)) temp;
256 for(Integer i=0;i<ionum;i=i+1)
257 temp[i]=pack(pwrup_pull_en_reg[i]);
258 return temp;
259 endmethod
260 endinterface;
261 endmodule
262
263 endpackage
264