2 Copyright (c) 2013, IIT Madras
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
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.
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 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
15 /*==== Package imports ==== */
21 /*============================ */
22 /*===== Project Imports ===== */
23 import Semi_FIFOF :: *;
24 import AXI4_Lite_Types :: *;
25 /*============================ */
26 `include "instance_defines.bsv"
28 interface GPIO_func#(numeric type ionum);
29 (*always_ready,always_enabled*)
30 interface Put#(Vector#(ionum,Bit#(1))) gpio_in;
32 interface Get#(Vector#(ionum,Bit#(1))) gpio_out;
34 interface Get#(Vector#(ionum,Bit#(1))) gpio_out_en;
36 interface GPIO_config#(numeric type ionum);
38 method Vector#(ionum,Bit#(1)) gpio_DRV0;
40 method Vector#(ionum,Bit#(1)) gpio_DRV1;
42 method Vector#(ionum,Bit#(1)) gpio_DRV2;
44 method Vector#(ionum,Bit#(1)) gpio_PD;
46 method Vector#(ionum,Bit#(1)) gpio_PPEN;
48 method Vector#(ionum,Bit#(1)) gpio_PRG_SLEW;
50 method Vector#(ionum,Bit#(1)) gpio_PUQ;
52 method Vector#(ionum,Bit#(1)) gpio_PWRUPZHL;
54 method Vector#(ionum,Bit#(1)) gpio_PWRUP_PULL_EN;
56 interface GPIO#(numeric type ionum);
57 interface GPIO_config#(ionum) pad_config;
58 interface GPIO_func#(ionum) func;
59 interface AXI4_Lite_Slave_IFC#(`ADDR,`DATA,`USERSPACE) axi_slave;
62 module mkgpio(GPIO#(ionum_));
63 let ionum = valueOf(ionum_);
64 Vector#(ionum_,ConfigReg#(Bool)) direction_reg <-replicateM(mkConfigReg(False));
65 Vector#(ionum_,ConfigReg#(Bit#(1))) dataout_register <-replicateM(mkConfigReg(0));
66 Vector#(ionum_,ConfigReg#(Bit#(1))) datain_register <-replicateM(mkConfigReg(0));
67 Vector#(ionum_,ConfigReg#(Bit#(1))) drv0_reg <-replicateM(mkConfigReg(1'b1));
68 Vector#(ionum_,ConfigReg#(Bit#(1))) drv1_reg <-replicateM(mkConfigReg(1'b1));
69 Vector#(ionum_,ConfigReg#(Bit#(1))) drv2_reg <-replicateM(mkConfigReg(0));
70 Vector#(ionum_,ConfigReg#(Bit#(1))) pd_reg <-replicateM(mkConfigReg(0));
71 Vector#(ionum_,ConfigReg#(Bit#(1))) ppen_reg <-replicateM(mkConfigReg(0));
72 Vector#(ionum_,ConfigReg#(Bit#(1))) prg_slew_reg <-replicateM(mkConfigReg(1'b1));
73 Vector#(ionum_,ConfigReg#(Bit#(1))) puq_reg <-replicateM(mkConfigReg(0));
74 Vector#(ionum_,ConfigReg#(Bit#(1))) pwrupzhl_reg <-replicateM(mkConfigReg(0));
75 Vector#(ionum_,ConfigReg#(Bit#(1))) pwrup_pull_en_reg <-replicateM(mkConfigReg(0));
77 AXI4_Lite_Slave_Xactor_IFC #(`ADDR, `DATA, `USERSPACE) s_xactor <- mkAXI4_Lite_Slave_Xactor;
80 let aw <- pop_o (s_xactor.o_wr_addr);
81 let w <- pop_o (s_xactor.o_wr_data);
82 let b = AXI4_Lite_Wr_Resp {bresp: AXI4_LITE_OKAY, buser: aw.awuser};
83 if(aw.awaddr[5:0]=='h0)
84 for(Integer i=0;i<ionum;i=i+1)
85 direction_reg[i]<=unpack(w.wdata[i]);
86 else if(aw.awaddr[5:0]=='h4)
87 for(Integer i=0;i<ionum;i=i+1)
88 dataout_register[i]<=w.wdata[i];
89 else if(aw.awaddr[5:0]=='h8)
90 for(Integer i=0;i<ionum;i=i+1)
91 drv0_reg[i]<=w.wdata[i];
92 else if(aw.awaddr[5:0]=='hC)
93 for(Integer i=0;i<ionum;i=i+1)
94 drv1_reg[i]<=w.wdata[i];
95 else if(aw.awaddr[5:0]=='h10)
96 for(Integer i=0;i<ionum;i=i+1)
97 drv2_reg[i]<=w.wdata[i];
98 else if(aw.awaddr[5:0]=='h14)
99 for(Integer i=0;i<ionum;i=i+1)
100 pd_reg[i]<=w.wdata[i];
101 else if(aw.awaddr[5:0]=='h18)
102 for(Integer i=0;i<ionum;i=i+1)
103 ppen_reg[i]<=w.wdata[i];
104 else if(aw.awaddr[5:0]=='h1C)
105 for(Integer i=0;i<ionum;i=i+1)
106 prg_slew_reg[i]<=w.wdata[i];
107 else if(aw.awaddr[5:0]=='h20)
108 for(Integer i=0;i<ionum;i=i+1)
109 puq_reg[i]<=w.wdata[i];
110 else if(aw.awaddr[5:0]=='h24)
111 for(Integer i=0;i<ionum;i=i+1)
112 pwrupzhl_reg[i]<=w.wdata[i];
113 else if(aw.awaddr[5:0]=='h28)
114 for(Integer i=0;i<ionum;i=i+1)
115 pwrup_pull_en_reg[i]<=w.wdata[i];
117 b.bresp=AXI4_LITE_SLVERR;
119 s_xactor.i_wr_resp.enq (b);
123 let ar<- pop_o(s_xactor.o_rd_addr);
125 AXI4_Lite_Rd_Data#(`DATA,`USERSPACE) r = AXI4_Lite_Rd_Data {rresp: AXI4_LITE_OKAY, rdata: ?, ruser: 0};
126 if(ar.araddr[5:0]=='h0)begin
127 for(Integer i=0;i<ionum;i=i+1)
128 temp[i]=pack(direction_reg[i]);
129 r.rdata=duplicate(temp);
131 else if(ar.araddr[5:0]=='h4)begin
132 for(Integer i=0;i<ionum;i=i+1)
133 temp[i]=datain_register[i];
134 r.rdata=duplicate(temp);
136 else if(ar.araddr[5:0]=='h8)begin
137 for(Integer i=0;i<ionum;i=i+1)
139 r.rdata=duplicate(temp);
141 else if(ar.araddr[5:0]=='hC)begin
142 for(Integer i=0;i<ionum;i=i+1)
144 r.rdata=duplicate(temp);
146 else if(ar.araddr[5:0]=='h10)begin
147 for(Integer i=0;i<ionum;i=i+1)
149 r.rdata=duplicate(temp);
151 else if(ar.araddr[5:0]=='h14)begin
152 for(Integer i=0;i<ionum;i=i+1)
154 r.rdata=duplicate(temp);
156 else if(ar.araddr[5:0]=='h18)begin
157 for(Integer i=0;i<ionum;i=i+1)
159 r.rdata=duplicate(temp);
161 else if(ar.araddr[5:0]=='h1C)begin
162 for(Integer i=0;i<ionum;i=i+1)
163 temp[i]=prg_slew_reg[i];
164 r.rdata=duplicate(temp);
166 else if(ar.araddr[5:0]=='h20)begin
167 for(Integer i=0;i<ionum;i=i+1)
169 r.rdata=duplicate(temp);
171 else if(ar.araddr[5:0]=='h24)begin
172 for(Integer i=0;i<ionum;i=i+1)
173 temp[i]=pwrupzhl_reg[i];
174 r.rdata=duplicate(temp);
176 else if(ar.araddr[5:0]=='h28)begin
177 for(Integer i=0;i<ionum;i=i+1)
178 temp[i]=pwrup_pull_en_reg[i];
179 r.rdata=duplicate(temp);
182 r.rresp=AXI4_LITE_SLVERR;
184 s_xactor.i_rd_data.enq(r);
187 interface axi_slave= s_xactor.axi_side;
188 interface func=interface GPIO_func
189 interface gpio_in = interface Put#(ionum)
190 method Action put(Vector#(ionum,Bit#(1)) in);
191 for(Integer i=0;i<ionum;i=i+1)
192 datain_register[i]<=in[i];
195 interface gpio_out = interface Get#(ionum)
196 method Vector#(ionum,Bit#(1)) get;
197 Vector#(ionum,Bit#(1)) temp;
198 for(Integer i=0;i<ionum;i=i+1)
199 temp[i]=dataout_register[i];
203 interface gpio_out_en = interface Get#(ionum)
204 method Vector#(ionum,Bit#(1)) get;
205 Vector#(ionum,Bit#(1)) temp;
206 for(Integer i=0;i<ionum;i=i+1)
207 temp[i]=pack(direction_reg[i]);
211 interface pad_config=interface GPIO_config
212 method Vector#(ionum,Bit#(1)) gpio_DRV0;
213 Vector#(ionum,Bit#(1)) temp;
214 for(Integer i=0;i<ionum;i=i+1)
215 temp[i]=pack(drv0_reg[i]);
218 method Vector#(ionum,Bit#(1)) gpio_DRV1;
219 Vector#(ionum,Bit#(1)) temp;
220 for(Integer i=0;i<ionum;i=i+1)
221 temp[i]=pack(drv1_reg[i]);
224 method Vector#(ionum,Bit#(1)) gpio_DRV2;
225 Vector#(ionum,Bit#(1)) temp;
226 for(Integer i=0;i<ionum;i=i+1)
227 temp[i]=pack(drv2_reg[i]);
230 method Vector#(ionum,Bit#(1)) gpio_PD;
231 Vector#(ionum,Bit#(1)) temp;
232 for(Integer i=0;i<ionum;i=i+1)
233 temp[i]=pack(pd_reg[i]);
236 method Vector#(ionum,Bit#(1)) gpio_PPEN;
237 Vector#(ionum,Bit#(1)) temp;
238 for(Integer i=0;i<ionum;i=i+1)
239 temp[i]=pack(ppen_reg[i]);
242 method Vector#(ionum,Bit#(1)) gpio_PRG_SLEW;
243 Vector#(ionum,Bit#(1)) temp;
244 for(Integer i=0;i<ionum;i=i+1)
245 temp[i]=pack(prg_slew_reg[i]);
248 method Vector#(ionum,Bit#(1)) gpio_PUQ;
249 Vector#(ionum,Bit#(1)) temp;
250 for(Integer i=0;i<ionum;i=i+1)
251 temp[i]=pack(puq_reg[i]);
254 method Vector#(ionum,Bit#(1)) gpio_PWRUPZHL;
255 Vector#(ionum,Bit#(1)) temp;
256 for(Integer i=0;i<ionum;i=i+1)
257 temp[i]=pack(pwrupzhl_reg[i]);
260 method Vector#(ionum,Bit#(1)) gpio_PWRUP_PULL_EN;
261 Vector#(ionum,Bit#(1)) temp;
262 for(Integer i=0;i<ionum;i=i+1)
263 temp[i]=pack(pwrup_pull_en_reg[i]);