adding initial draft of gpio
[pinmux.git] / src / bsv / bsv_lib / 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 `include "defined_parameters.bsv"
23 import Semi_FIFOF :: *;
24 import AXI4_Lite_Types :: *;
25 import AXI4_Lite_Fabric :: *;
26 /*============================ */
27
28 interface GPIO;
29 (*always_ready,always_enabled*)
30 method Action gpio_in (Vector#(`IONum,Bit#(1)) inp);
31 method Vector#(`IONum,Bit#(1)) gpio_out;
32 method Vector#(`IONum,Bit#(1)) gpio_out_en;
33 method Vector#(`IONum,Bit#(1)) gpio_DRV0;
34 method Vector#(`IONum,Bit#(1)) gpio_DRV1;
35 method Vector#(`IONum,Bit#(1)) gpio_DRV2;
36 method Vector#(`IONum,Bit#(1)) gpio_PD;
37 method Vector#(`IONum,Bit#(1)) gpio_PPEN;
38 method Vector#(`IONum,Bit#(1)) gpio_PRG_SLEW;
39 method Vector#(`IONum,Bit#(1)) gpio_PUQ;
40 method Vector#(`IONum,Bit#(1)) gpio_PWRUPZHL;
41 method Vector#(`IONum,Bit#(1)) gpio_PWRUP_PULL_EN;
42 interface Vector#(`IONum,Reg#(Bit#(1))) to_plic;
43 `ifdef GPIO_MUX
44 method Vector#(`IONum,Bit#(2)) gpio_MUX;
45 `endif
46 interface AXI4_Lite_Slave_IFC#(`PADDR,`Reg_width,`USERSPACE) axi_slave;
47 endinterface
48
49 (*synthesize*)
50 module mkgpio(GPIO);
51 Vector#(`IONum,ConfigReg#(Bool)) direction_reg <-replicateM(mkConfigReg(False));
52 Vector#(`IONum,ConfigReg#(Bit#(1))) dataout_register <-replicateM(mkConfigReg(0));
53 Vector#(`IONum,ConfigReg#(Bit#(1))) datain_register <-replicateM(mkConfigReg(0));
54 Vector#(`IONum,ConfigReg#(Bit#(1))) drv0_reg <-replicateM(mkConfigReg(1'b1));
55 Vector#(`IONum,ConfigReg#(Bit#(1))) drv1_reg <-replicateM(mkConfigReg(1'b1));
56 Vector#(`IONum,ConfigReg#(Bit#(1))) drv2_reg <-replicateM(mkConfigReg(0));
57 Vector#(`IONum,ConfigReg#(Bit#(1))) pd_reg <-replicateM(mkConfigReg(0));
58 Vector#(`IONum,ConfigReg#(Bit#(1))) ppen_reg <-replicateM(mkConfigReg(0));
59 Vector#(`IONum,ConfigReg#(Bit#(1))) prg_slew_reg <-replicateM(mkConfigReg(1'b1));
60 Vector#(`IONum,ConfigReg#(Bit#(1))) puq_reg <-replicateM(mkConfigReg(0));
61 Vector#(`IONum,ConfigReg#(Bit#(1))) pwrupzhl_reg <-replicateM(mkConfigReg(0));
62 Vector#(`IONum,ConfigReg#(Bit#(1))) pwrup_pull_en_reg <-replicateM(mkConfigReg(0));
63 Vector#(`IONum,ConfigReg#(Bit#(1))) toplic <-replicateM(mkConfigReg(0));
64 `ifdef GPIO_MUX
65 Vector#(`IONum,ConfigReg#(Bit#(2))) muxer_reg <-replicateM(mkConfigReg(0));
66 `endif
67
68 AXI4_Lite_Slave_Xactor_IFC #(`PADDR, `Reg_width, `USERSPACE) s_xactor <- mkAXI4_Lite_Slave_Xactor;
69 let ionum=valueOf(`IONum);
70 rule capture_interrupt;
71 for(Integer i=0;i<`IONum;i=i+1)
72 toplic[i]<=(!direction_reg[i])?datain_register[i]:0;
73 endrule
74
75 rule rl_wr_respond;
76 // Get the wr request
77 let aw <- pop_o (s_xactor.o_wr_addr);
78 let w <- pop_o (s_xactor.o_wr_data);
79 let b = AXI4_Lite_Wr_Resp {bresp: AXI4_LITE_OKAY, buser: aw.awuser};
80 if(aw.awaddr[5:0]=='h0)
81 for(Integer i=0;i<`IONum;i=i+1)
82 direction_reg[i]<=unpack(w.wdata[i]);
83 else if(aw.awaddr[5:0]=='h4)
84 for(Integer i=0;i<`IONum;i=i+1)
85 dataout_register[i]<=w.wdata[i];
86 else if(aw.awaddr[5:0]=='h8)
87 for(Integer i=0;i<`IONum;i=i+1)
88 drv0_reg[i]<=w.wdata[i];
89 else if(aw.awaddr[5:0]=='hC)
90 for(Integer i=0;i<`IONum;i=i+1)
91 drv1_reg[i]<=w.wdata[i];
92 else if(aw.awaddr[5:0]=='h10)
93 for(Integer i=0;i<`IONum;i=i+1)
94 drv2_reg[i]<=w.wdata[i];
95 else if(aw.awaddr[5:0]=='h14)
96 for(Integer i=0;i<`IONum;i=i+1)
97 pd_reg[i]<=w.wdata[i];
98 else if(aw.awaddr[5:0]=='h18)
99 for(Integer i=0;i<`IONum;i=i+1)
100 ppen_reg[i]<=w.wdata[i];
101 else if(aw.awaddr[5:0]=='h1C)
102 for(Integer i=0;i<`IONum;i=i+1)
103 prg_slew_reg[i]<=w.wdata[i];
104 else if(aw.awaddr[5:0]=='h20)
105 for(Integer i=0;i<`IONum;i=i+1)
106 puq_reg[i]<=w.wdata[i];
107 else if(aw.awaddr[5:0]=='h24)
108 for(Integer i=0;i<`IONum;i=i+1)
109 pwrupzhl_reg[i]<=w.wdata[i];
110 else if(aw.awaddr[5:0]=='h28)
111 for(Integer i=0;i<`IONum;i=i+1)
112 pwrup_pull_en_reg[i]<=w.wdata[i];
113 `ifdef GPIO_MUX
114 else if(aw.awaddr[5:0]=='h2c)
115 for(Integer i=0;i<min(`IONum, 16);i=i+1) begin
116 muxer_reg[i]<= w.wdata[i*2+1:i*2];
117 end
118 else if(aw.awaddr[5:0]=='h30 && ionum>=16)
119 for(Integer i=0;i<`IONum-16;i=i+1) begin
120 muxer_reg[i+16]<= w.wdata[i*2+1:i*2];
121 end
122 `endif
123 else
124 b.bresp=AXI4_LITE_SLVERR;
125
126 s_xactor.i_wr_resp.enq (b);
127 endrule
128
129 rule rl_rd_respond;
130 let ar<- pop_o(s_xactor.o_rd_addr);
131 Bit#(32) temp=0;
132 AXI4_Lite_Rd_Data#(`Reg_width,`USERSPACE) r = AXI4_Lite_Rd_Data {rresp: AXI4_LITE_OKAY, rdata: ?, ruser: 0};
133 if(ar.araddr[5:0]=='h0)begin
134 for(Integer i=0;i<`IONum;i=i+1)
135 temp[i]=pack(direction_reg[i]);
136 r.rdata=duplicate(temp);
137 end
138 else if(ar.araddr[5:0]=='h4)begin
139 for(Integer i=0;i<`IONum;i=i+1)
140 temp[i]=datain_register[i];
141 r.rdata=duplicate(temp);
142 end
143 else if(ar.araddr[5:0]=='h8)begin
144 for(Integer i=0;i<`IONum;i=i+1)
145 temp[i]=drv0_reg[i];
146 r.rdata=duplicate(temp);
147 end
148 else if(ar.araddr[5:0]=='hC)begin
149 for(Integer i=0;i<`IONum;i=i+1)
150 temp[i]=drv1_reg[i];
151 r.rdata=duplicate(temp);
152 end
153 else if(ar.araddr[5:0]=='h10)begin
154 for(Integer i=0;i<`IONum;i=i+1)
155 temp[i]=drv2_reg[i];
156 r.rdata=duplicate(temp);
157 end
158 else if(ar.araddr[5:0]=='h14)begin
159 for(Integer i=0;i<`IONum;i=i+1)
160 temp[i]=pd_reg[i];
161 r.rdata=duplicate(temp);
162 end
163 else if(ar.araddr[5:0]=='h18)begin
164 for(Integer i=0;i<`IONum;i=i+1)
165 temp[i]=ppen_reg[i];
166 r.rdata=duplicate(temp);
167 end
168 else if(ar.araddr[5:0]=='h1C)begin
169 for(Integer i=0;i<`IONum;i=i+1)
170 temp[i]=prg_slew_reg[i];
171 r.rdata=duplicate(temp);
172 end
173 else if(ar.araddr[5:0]=='h20)begin
174 for(Integer i=0;i<`IONum;i=i+1)
175 temp[i]=puq_reg[i];
176 r.rdata=duplicate(temp);
177 end
178 else if(ar.araddr[5:0]=='h24)begin
179 for(Integer i=0;i<`IONum;i=i+1)
180 temp[i]=pwrupzhl_reg[i];
181 r.rdata=duplicate(temp);
182 end
183 else if(ar.araddr[5:0]=='h28)begin
184 for(Integer i=0;i<`IONum;i=i+1)
185 temp[i]=pwrup_pull_en_reg[i];
186 r.rdata=duplicate(temp);
187 end
188 `ifdef GPIO_MUX
189 else if(ar.araddr[5:0]=='h2c)begin
190 for(Integer i=0;i<min(`IONum, 16);i=i+1) begin
191 temp[i*2+ 1:i*2]=muxer_reg[i];
192 end
193 r.rdata=duplicate(temp);
194 end
195 else if(ar.araddr[5:0]=='h30 && ionum>=16)begin
196 for(Integer i=0;i<`IONum-16;i=i+1) begin
197 temp[i*2+ 1:i*2]=muxer_reg[i+ 16];
198 end
199 r.rdata=duplicate(temp);
200 end
201 `endif
202 else
203 r.rresp=AXI4_LITE_SLVERR;
204
205 s_xactor.i_rd_data.enq(r);
206 endrule
207
208 interface axi_slave= s_xactor.axi_side;
209 method Action gpio_in (Vector#(`IONum,Bit#(1)) inp);
210 for(Integer i=0;i<`IONum;i=i+1)
211 datain_register[i]<=inp[i];
212 endmethod
213 method Vector#(`IONum,Bit#(1)) gpio_out;
214 Vector#(`IONum,Bit#(1)) temp;
215 for(Integer i=0;i<`IONum;i=i+1)
216 temp[i]=dataout_register[i];
217 return temp;
218 endmethod
219 method Vector#(`IONum,Bit#(1)) gpio_out_en;
220 Vector#(`IONum,Bit#(1)) temp;
221 for(Integer i=0;i<`IONum;i=i+1)
222 temp[i]=pack(direction_reg[i]);
223 return temp;
224 endmethod
225 method Vector#(`IONum,Bit#(1)) gpio_DRV0;
226 Vector#(`IONum,Bit#(1)) temp;
227 for(Integer i=0;i<`IONum;i=i+1)
228 temp[i]=pack(drv0_reg[i]);
229 return temp;
230 endmethod
231 method Vector#(`IONum,Bit#(1)) gpio_DRV1;
232 Vector#(`IONum,Bit#(1)) temp;
233 for(Integer i=0;i<`IONum;i=i+1)
234 temp[i]=pack(drv1_reg[i]);
235 return temp;
236 endmethod
237 method Vector#(`IONum,Bit#(1)) gpio_DRV2;
238 Vector#(`IONum,Bit#(1)) temp;
239 for(Integer i=0;i<`IONum;i=i+1)
240 temp[i]=pack(drv2_reg[i]);
241 return temp;
242 endmethod
243 method Vector#(`IONum,Bit#(1)) gpio_PD;
244 Vector#(`IONum,Bit#(1)) temp;
245 for(Integer i=0;i<`IONum;i=i+1)
246 temp[i]=pack(pd_reg[i]);
247 return temp;
248 endmethod
249 method Vector#(`IONum,Bit#(1)) gpio_PPEN;
250 Vector#(`IONum,Bit#(1)) temp;
251 for(Integer i=0;i<`IONum;i=i+1)
252 temp[i]=pack(ppen_reg[i]);
253 return temp;
254 endmethod
255 method Vector#(`IONum,Bit#(1)) gpio_PRG_SLEW;
256 Vector#(`IONum,Bit#(1)) temp;
257 for(Integer i=0;i<`IONum;i=i+1)
258 temp[i]=pack(prg_slew_reg[i]);
259 return temp;
260 endmethod
261 method Vector#(`IONum,Bit#(1)) gpio_PUQ;
262 Vector#(`IONum,Bit#(1)) temp;
263 for(Integer i=0;i<`IONum;i=i+1)
264 temp[i]=pack(puq_reg[i]);
265 return temp;
266 endmethod
267 method Vector#(`IONum,Bit#(1)) gpio_PWRUPZHL;
268 Vector#(`IONum,Bit#(1)) temp;
269 for(Integer i=0;i<`IONum;i=i+1)
270 temp[i]=pack(pwrupzhl_reg[i]);
271 return temp;
272 endmethod
273 method Vector#(`IONum,Bit#(1)) gpio_PWRUP_PULL_EN;
274 Vector#(`IONum,Bit#(1)) temp;
275 for(Integer i=0;i<`IONum;i=i+1)
276 temp[i]=pack(pwrup_pull_en_reg[i]);
277 return temp;
278 endmethod
279 method Vector#(`IONum,Bit#(2)) gpio_MUX;
280 Vector#(`IONum,Bit#(2)) temp;
281 for(Integer i=0;i<`IONum;i=i+1)
282 temp[i]=pack(muxer_reg[i]);
283 return temp;
284 endmethod
285 interface to_plic=toplic;
286 endmodule
287 endpackage
288