source: trunk/Octopus/i2c_fifo.v@ 200

Last change on this file since 200 was 102, checked in by demin, 15 years ago

initial commit

File size: 3.6 KB
RevLine 
[102]1module i2c_fifo
2 (
3 input wire clock, reset,
4
5 input wire bus_ssel, bus_wren,
6 input wire [15:0] bus_mosi,
7
8 output wire bus_busy,
9
10 inout wire i2c_sda,
11 inout wire i2c_scl
12 );
13
14 wire int_rdempty, int_wrfull, i2c_clk, start, stop;
15 wire [15:0] int_q;
16
17 reg int_bus_busy;
18 reg int_rdreq, int_wrreq, int_clken, int_sdo, int_scl, int_ack;
19 reg [15:0] int_bus_mosi;
20 reg [15:0] int_data;
21 reg [9:0] counter;
22 reg [4:0] state;
23
24 assign i2c_sda = int_sdo ? 1'bz : 1'b0;
25 assign i2c_scl = int_scl | (int_clken ? counter[9] : 1'b0);
26
27 assign start = int_data[8];
28 assign stop = int_data[9];
29
30 scfifo #(
31 .add_ram_output_register("OFF"),
32 .intended_device_family("Cyclone III"),
33 .lpm_numwords(16),
34 .lpm_showahead("ON"),
35 .lpm_type("scfifo"),
36 .lpm_width(16),
37 .lpm_widthu(4),
38 .overflow_checking("ON"),
39 .underflow_checking("ON"),
40 .use_eab("OFF")) fifo_tx (
41 .rdreq((~int_rdempty) & (int_rdreq) & (&counter)),
42 .aclr(1'b0),
43 .clock(clock),
44 .wrreq(int_wrreq),
45 .data(int_bus_mosi),
46 .empty(int_rdempty),
47 .q(int_q),
48 .full(int_wrfull),
49 .almost_empty(),
50 .almost_full(),
51 .sclr(),
52 .usedw());
53
54 always @ (posedge clock)
55 begin
56 int_bus_busy <= int_wrfull;
57
58 if (bus_ssel)
59 begin
60 if (~int_wrfull & bus_wren)
61 begin
62 int_bus_mosi <= bus_mosi;
63 int_wrreq <= 1'b1;
64 end
65 end
66
67 if (~int_wrfull & int_wrreq)
68 begin
69 int_wrreq <= 1'b0;
70 end
71
72 end
73
74 always @ (posedge clock)
75 begin
76 counter <= counter + 10'd1;
77 if (&counter)
78 begin
79 case (state)
80 0:
81 begin
82 int_ack <= 1'b0;
83 int_sdo <= 1'b1;
84 int_scl <= 1'b1;
85 int_rdreq <= 1'b1;
86 state <= 5'd1;
87 end
88
89 1:
90 begin
91 if (~int_rdempty)
92 begin
93 int_data <= int_q;
94 int_rdreq <= 1'b0;
95 state <= 5'd2;
96 end
97 end
98
99 2:
100 begin
101 if (start)
102 begin
103 int_sdo <= 1'b1;
104 int_scl <= 1'b1;
105 state <= 5'd3;
106 end
107 else
108 begin
109 state <= 5'd5;
110 end
111 end
112
113 3:
114 begin // start
115 int_sdo <= 1'b0;
116 state <= 5'd4;
117 end
118
119 4:
120 begin
121 int_scl <= 1'b0;
122 state <= 5'd5;
123 end
124
125 5:
126 begin // data
127 int_clken <= 1'b1;
128 int_sdo <= int_data[7];
129 state <= 5'd6;
130 end
131
132 6:
133 begin
134 int_sdo <= int_data[6];
135 state <= 5'd7;
136 end
137
138 7:
139 begin
140 int_sdo <= int_data[5];
141 state <= 5'd8;
142 end
143
144 8:
145 begin
146 int_sdo <= int_data[4];
147 state <= 5'd9;
148 end
149
150 9:
151 begin
152 int_sdo <= int_data[3];
153 state <= 5'd10;
154 end
155
156 10:
157 begin
158 int_sdo <= int_data[2];
159 state <= 5'd11;
160 end
161
162 11:
163 begin
164 int_sdo <= int_data[1];
165 state <= 5'd12;
166 end
167
168 12:
169 begin
170 int_sdo <= int_data[0];
171 state <= 5'd13;
172 end
173
174 13:
175 begin // ack
176 int_sdo <= 1'b1;
177 int_rdreq <= 1'b1;
178 state <= 5'd14;
179 end
180
181 14:
182 begin
183 int_ack <= i2c_sda;
184 int_rdreq <= 1'b0;
185 if (stop | int_rdempty)
186 begin
187 int_clken <= 1'b0;
188 int_sdo <= 1'b0;
189 int_scl <= 1'b0;
190 state <= 5'd15;
191 end
192 else if (~int_rdempty)
193 begin
194 int_data <= int_q;
195 int_sdo <= int_q[7];
196 state <= 5'd6;
197 end
198 end
199
200 15:
201 begin // stop
202 int_scl <= 1'b1;
203 state <= 5'd16;
204 end
205
206 16:
207 begin
208 int_sdo <= 1'b1;
209 state <= 5'd0;
210 end
211
212 endcase
213 end
214 end
215
216 // output logic
217 assign bus_busy = int_bus_busy;
218
219endmodule
Note: See TracBrowser for help on using the repository browser.